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