1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s 2 // UNSUPPORTED: darwin 3 #include <pthread.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <signal.h> 7 #include <sys/types.h> 8 #include <sys/time.h> 9 #include <unistd.h> 10 #include <errno.h> 11 12 volatile int X; 13 int stop; 14 15 static void handler(int sig) { 16 (void)sig; 17 if (X != 0) 18 printf("bad"); 19 } 20 21 static void* busy(void *p) { 22 while (__atomic_load_n(&stop, __ATOMIC_RELAXED) == 0) { 23 } 24 return 0; 25 } 26 27 static void* reset(void *p) { 28 struct sigaction act = {}; 29 for (int i = 0; i < 1000000; i++) { 30 act.sa_handler = &handler; 31 if (sigaction(SIGPROF, &act, 0)) { 32 perror("sigaction"); 33 exit(1); 34 } 35 act.sa_handler = SIG_IGN; 36 if (sigaction(SIGPROF, &act, 0)) { 37 perror("sigaction"); 38 exit(1); 39 } 40 } 41 return 0; 42 } 43 44 int main() { 45 struct sigaction act = {}; 46 act.sa_handler = SIG_IGN; 47 if (sigaction(SIGPROF, &act, 0)) { 48 perror("sigaction"); 49 exit(1); 50 } 51 52 itimerval t; 53 t.it_value.tv_sec = 0; 54 t.it_value.tv_usec = 10; 55 t.it_interval = t.it_value; 56 if (setitimer(ITIMER_PROF, &t, 0)) { 57 perror("setitimer"); 58 exit(1); 59 } 60 61 pthread_t th[2]; 62 pthread_create(&th[0], 0, busy, 0); 63 pthread_create(&th[1], 0, reset, 0); 64 65 pthread_join(th[1], 0); 66 __atomic_store_n(&stop, 1, __ATOMIC_RELAXED); 67 pthread_join(th[0], 0); 68 69 fprintf(stderr, "DONE\n"); 70 return 0; 71 } 72 73 // CHECK-NOT: WARNING: ThreadSanitizer: 74 // CHECK: DONE 75 // CHECK-NOT: WARNING: ThreadSanitizer: 76