xref: /llvm-project/compiler-rt/test/tsan/signal_sync2.cpp (revision fbe3f89bcf54cd8f674308d839a5a8f318915a8e)
1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2 // UNSUPPORTED: darwin
3 // Fails episodically on powerpc bots:
4 // https://lab.llvm.org/buildbot/#/builders/121/builds/13391
5 // UNSUPPORTED: target=powerpc64{{.*}}
6 #include "test.h"
7 #include <errno.h>
8 #include <signal.h>
9 #include <sys/time.h>
10 #include <sys/types.h>
11 
12 // Test synchronization in signal handled within IgnoreSync region.
13 
14 const int kSignalCount = 500;
15 
16 __thread int process_signals;
17 int signals_handled;
18 int done;
19 int ready[kSignalCount];
20 long long data[kSignalCount];
21 
handler(int sig)22 static void handler(int sig) {
23   if (!__atomic_load_n(&process_signals, __ATOMIC_RELAXED))
24     return;
25   int pos = signals_handled++;
26   if (pos >= kSignalCount)
27     return;
28   data[pos] = pos;
29   __atomic_store_n(&ready[pos], 1, __ATOMIC_RELEASE);
30 }
31 
thr(void * p)32 static void* thr(void *p) {
33   AnnotateIgnoreSyncBegin(__FILE__, __LINE__);
34   __atomic_store_n(&process_signals, 1, __ATOMIC_RELAXED);
35   while (!__atomic_load_n(&done, __ATOMIC_RELAXED)) {
36   }
37   AnnotateIgnoreSyncEnd(__FILE__, __LINE__);
38   return 0;
39 }
40 
main()41 int main() {
42   struct sigaction act = {};
43   act.sa_handler = handler;
44   if (sigaction(SIGPROF, &act, 0)) {
45     perror("sigaction");
46     exit(1);
47   }
48   itimerval t;
49   t.it_value.tv_sec = 0;
50   t.it_value.tv_usec = 10;
51   t.it_interval = t.it_value;
52   if (setitimer(ITIMER_PROF, &t, 0)) {
53     perror("setitimer");
54     exit(1);
55   }
56 
57   pthread_t th;
58   pthread_create(&th, 0, thr, 0);
59   for (int pos = 0; pos < kSignalCount; pos++) {
60     while (__atomic_load_n(&ready[pos], __ATOMIC_ACQUIRE) == 0) {
61     }
62     if (data[pos] != pos) {
63       printf("at pos %d, expect %d, got %lld\n", pos, pos, data[pos]);
64       exit(1);
65     }
66   }
67   __atomic_store_n(&done, 1, __ATOMIC_RELAXED);
68   pthread_join(th, 0);
69   fprintf(stderr, "DONE\n");
70   return 0;
71 }
72 
73 // CHECK-NOT: WARNING: ThreadSanitizer:
74 // CHECK: DONE
75