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