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