xref: /llvm-project/compiler-rt/test/tsan/signal_cond.cpp (revision bcaeed49cb063de9fe504aa29e1cadff8a7be710)
1*bcaeed49SFangrui Song // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2*bcaeed49SFangrui Song #include "test.h"
3*bcaeed49SFangrui Song #include <signal.h>
4*bcaeed49SFangrui Song #include <unistd.h>
5*bcaeed49SFangrui Song #include <errno.h>
6*bcaeed49SFangrui Song #include <semaphore.h>
7*bcaeed49SFangrui Song 
8*bcaeed49SFangrui Song // Test that signals can be delivered to blocked pthread_cond_wait.
9*bcaeed49SFangrui Song // https://github.com/google/sanitizers/issues/498
10*bcaeed49SFangrui Song 
11*bcaeed49SFangrui Song int g_thread_run = 1;
12*bcaeed49SFangrui Song pthread_mutex_t mutex;
13*bcaeed49SFangrui Song pthread_cond_t cond;
14*bcaeed49SFangrui Song 
sig_handler(int sig)15*bcaeed49SFangrui Song void sig_handler(int sig) {
16*bcaeed49SFangrui Song   (void)sig;
17*bcaeed49SFangrui Song   write(2, "SIGNAL\n", sizeof("SIGNAL\n") - 1);
18*bcaeed49SFangrui Song   barrier_wait(&barrier);
19*bcaeed49SFangrui Song }
20*bcaeed49SFangrui Song 
my_thread(void * arg)21*bcaeed49SFangrui Song void* my_thread(void* arg) {
22*bcaeed49SFangrui Song   pthread_mutex_lock(&mutex);
23*bcaeed49SFangrui Song   while (g_thread_run)
24*bcaeed49SFangrui Song     pthread_cond_wait(&cond, &mutex);
25*bcaeed49SFangrui Song   pthread_mutex_unlock(&mutex);
26*bcaeed49SFangrui Song   return 0;
27*bcaeed49SFangrui Song }
28*bcaeed49SFangrui Song 
main()29*bcaeed49SFangrui Song int main() {
30*bcaeed49SFangrui Song   barrier_init(&barrier, 2);
31*bcaeed49SFangrui Song 
32*bcaeed49SFangrui Song   pthread_mutex_init(&mutex, 0);
33*bcaeed49SFangrui Song   pthread_cond_init(&cond, 0);
34*bcaeed49SFangrui Song 
35*bcaeed49SFangrui Song   signal(SIGUSR1, &sig_handler);
36*bcaeed49SFangrui Song   pthread_t thr;
37*bcaeed49SFangrui Song   pthread_create(&thr, 0, &my_thread, 0);
38*bcaeed49SFangrui Song   // wait for thread to get inside pthread_cond_wait
39*bcaeed49SFangrui Song   // (can't use barrier_wait for that)
40*bcaeed49SFangrui Song   sleep(1);
41*bcaeed49SFangrui Song   pthread_kill(thr, SIGUSR1);
42*bcaeed49SFangrui Song   barrier_wait(&barrier);
43*bcaeed49SFangrui Song   pthread_mutex_lock(&mutex);
44*bcaeed49SFangrui Song   g_thread_run = 0;
45*bcaeed49SFangrui Song   pthread_cond_signal(&cond);
46*bcaeed49SFangrui Song   pthread_mutex_unlock(&mutex);
47*bcaeed49SFangrui Song   pthread_join(thr, 0);
48*bcaeed49SFangrui Song   fprintf(stderr, "DONE\n");
49*bcaeed49SFangrui Song   return 0;
50*bcaeed49SFangrui Song }
51*bcaeed49SFangrui Song 
52*bcaeed49SFangrui Song // CHECK: SIGNAL
53*bcaeed49SFangrui Song // CHECK: DONE
54