92 lines · cpp
1// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s2// The test was reported to hang sometimes on Darwin:3// https://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20210517/917003.html4// UNSUPPORTED: darwin5 6#include "test.h"7#include <signal.h>8#include <string.h>9#include <sys/time.h>10 11int test;12int done;13int signals_handled;14pthread_t main_thread;15pthread_mutex_t mutex;16pthread_cond_t cond;17 18void timer_handler(int signum) {19 write(2, "timer_handler\n", strlen("timer_handler\n"));20 if (++signals_handled < 10)21 return;22 switch (test) {23 case 0:24 __atomic_store_n(&done, 1, __ATOMIC_RELEASE);25 (void)pthread_kill(main_thread, SIGUSR1);26 case 1:27 if (pthread_mutex_trylock(&mutex) == 0) {28 __atomic_store_n(&done, 1, __ATOMIC_RELEASE);29 pthread_cond_signal(&cond);30 pthread_mutex_unlock(&mutex);31 }32 case 2:33 __atomic_store_n(&done, 1, __ATOMIC_RELEASE);34 }35}36 37int main(int argc, char **argv) {38 main_thread = pthread_self();39 pthread_mutex_init(&mutex, 0);40 pthread_cond_init(&cond, 0);41 42 sigset_t sigset;43 sigemptyset(&sigset);44 sigaddset(&sigset, SIGUSR1);45 if (sigprocmask(SIG_BLOCK, &sigset, NULL))46 exit((perror("sigprocmask"), 1));47 48 struct sigaction sa;49 memset(&sa, 0, sizeof(sa));50 sa.sa_handler = &timer_handler;51 if (sigaction(SIGALRM, &sa, NULL))52 exit((perror("setitimer"), 1));53 54 for (test = 0; test < 3; test++) {55 fprintf(stderr, "test %d\n", test);56 struct itimerval timer;57 timer.it_value.tv_sec = 0;58 timer.it_value.tv_usec = 50000;59 timer.it_interval = timer.it_value;60 if (setitimer(ITIMER_REAL, &timer, NULL))61 exit((perror("setitimer"), 1));62 63 switch (test) {64 case 0:65 while (__atomic_load_n(&done, __ATOMIC_ACQUIRE) == 0) {66 int signum;67 sigwait(&sigset, &signum);68 write(2, "sigwait\n", strlen("sigwait\n"));69 }70 case 1:71 pthread_mutex_lock(&mutex);72 while (__atomic_load_n(&done, __ATOMIC_ACQUIRE) == 0) {73 pthread_cond_wait(&cond, &mutex);74 write(2, "pthread_cond_wait\n", strlen("pthread_cond_wait\n"));75 }76 pthread_mutex_unlock(&mutex);77 case 2:78 while (__atomic_load_n(&done, __ATOMIC_ACQUIRE) == 0) {79 }80 }81 82 memset(&timer, 0, sizeof(timer));83 if (setitimer(ITIMER_REAL, &timer, NULL))84 exit((perror("setitimer"), 1));85 done = 0;86 signals_handled = 0;87 }88 fprintf(stderr, "DONE\n");89}90 91// CHECK: DONE92