1 // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2 // The test was reported to hang sometimes on Darwin:
3 // https://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20210517/917003.html
14 pthread_t main_thread
;
15 pthread_mutex_t mutex
;
18 void timer_handler(int signum
) {
19 write(2, "timer_handler\n", strlen("timer_handler\n"));
20 if (++signals_handled
< 10)
24 __atomic_store_n(&done
, 1, __ATOMIC_RELEASE
);
25 (void)pthread_kill(main_thread
, SIGUSR1
);
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
);
33 __atomic_store_n(&done
, 1, __ATOMIC_RELEASE
);
37 int main(int argc
, char **argv
) {
38 main_thread
= pthread_self();
39 pthread_mutex_init(&mutex
, 0);
40 pthread_cond_init(&cond
, 0);
44 sigaddset(&sigset
, SIGUSR1
);
45 if (sigprocmask(SIG_BLOCK
, &sigset
, NULL
))
46 exit((perror("sigprocmask"), 1));
49 memset(&sa
, 0, sizeof(sa
));
50 sa
.sa_handler
= &timer_handler
;
51 if (sigaction(SIGALRM
, &sa
, NULL
))
52 exit((perror("setitimer"), 1));
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));
65 while (__atomic_load_n(&done
, __ATOMIC_ACQUIRE
) == 0) {
67 sigwait(&sigset
, &signum
);
68 write(2, "sigwait\n", strlen("sigwait\n"));
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"));
76 pthread_mutex_unlock(&mutex
);
78 while (__atomic_load_n(&done
, __ATOMIC_ACQUIRE
) == 0) {
82 memset(&timer
, 0, sizeof(timer
));
83 if (setitimer(ITIMER_REAL
, &timer
, NULL
))
84 exit((perror("setitimer"), 1));
88 fprintf(stderr
, "DONE\n");