1#!/bin/sh 2 3# Test scenario from 4# Bug 192918 - [patch] A thread will spin if a signal interrupts umtxq_sleep_pi. 5# by eric@vangyzen.net 6 7. ../default.cfg 8 9here=`pwd` 10cd /tmp 11sed '1,/^EOF/d' < $here/$0 > umtx_suspend.c 12mycc -o umtx_suspend -Wall -Wextra -O0 -g umtx_suspend.c \ 13 -lpthread || exit 1 14rm -f umtx_suspend.c 15 16/tmp/umtx_suspend 17 18rm -f /tmp/umtx_suspend 19exit 0 20EOF 21// cc -lpthread -o umtx_suspend umtx_suspend.c 22// 23// failure: a thread spins around "umtxpi" the kernel, ignoring signals 24// success: the process exits 25 26#include <sys/cdefs.h> 27 28#include <err.h> 29#include <pthread.h> 30#include <pthread_np.h> 31#include <stdio.h> 32#include <unistd.h> 33 34pthread_mutex_t the_mutex; 35 36void * 37spinning_thread_func(void *arg __unused) 38{ 39 int error; 40 41 error = pthread_mutex_lock(&the_mutex); 42 if (error) 43 errc(1, error, "%s: pthread_mutex_lock", __func__); 44 45 return (NULL); 46} 47 48int 49main(int argc __unused, char *argv[] __unused) 50{ 51 int error; 52 pthread_t spinning_thread; 53 pthread_mutexattr_t the_mutex_attr; 54 55 error = pthread_mutexattr_init(&the_mutex_attr); 56 if (error) 57 errc(1, error, "pthread_mutexattr_init"); 58 59 error = pthread_mutexattr_setprotocol(&the_mutex_attr, PTHREAD_PRIO_INHERIT); 60 if (error) 61 errc(1, error, "pthread_mutexattr_setprotocol"); 62 63 error = pthread_mutex_init(&the_mutex, &the_mutex_attr); 64 if (error) 65 errc(1, error, "pthread_mutex_init"); 66 67 error = pthread_mutex_lock(&the_mutex); 68 if (error) 69 errc(1, error, "pthread_mutex_lock"); 70 71 error = pthread_create(&spinning_thread, NULL, spinning_thread_func, NULL); 72 if (error) 73 errc(1, error, "pthread_create"); 74 75 // Wait for the spinning_thread to call pthread_mutex_lock(3) 76 // and enter the kernel. 77 (void) sleep(1); 78 79 error = pthread_suspend_np(spinning_thread); 80 if (error) 81 errc(1, error, "pthread_suspend_np"); 82 83 // The spinning_thread should be spinning in the kernel. 84 // This thread should be blocked in pthread_suspend_np(3). 85 fputs("This test failed to reproduce the bug.\n", stderr); 86 87 return (0); 88} 89