1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 66 2>&1 | FileCheck %s -check-prefix=CHECK-DIE
2 // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=die_after_fork=0 %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-NODIE
8 static void *sleeper(void *p
) {
9 barrier_wait(&barrier
);
13 static void *nop(void *p
) {
17 int main(int argc
, const char **argv
) {
18 barrier_init(&barrier
, 3);
19 const int kSleeperThreads
= 2;
20 barrier_init(&barrier
, kSleeperThreads
+ 1);
21 pthread_t th0
[kSleeperThreads
];
22 for (int i
= 0; i
< kSleeperThreads
; i
++)
23 pthread_create(&th0
[i
], 0, sleeper
, 0);
24 const int kNopThreads
= 5;
25 pthread_t th1
[kNopThreads
];
26 for (int i
= 0; i
< kNopThreads
; i
++)
27 pthread_create(&th1
[i
], 0, nop
, 0);
28 for (int i
= 0; i
< kNopThreads
; i
++)
29 pthread_join(th1
[i
], 0);
32 fprintf(stderr
, "failed to fork (%d)\n", errno
);
37 const int kChildThreads
= 4;
38 pthread_t th2
[kChildThreads
];
39 for (int i
= 0; i
< kChildThreads
; i
++)
40 pthread_create(&th2
[i
], 0, nop
, 0);
41 for (int i
= 0; i
< kChildThreads
; i
++)
42 pthread_join(th2
[i
], 0);
47 int expect
= argc
> 1 ? atoi(argv
[1]) : 0;
49 while (waitpid(pid
, &status
, 0) != pid
) {
51 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != expect
) {
52 fprintf(stderr
, "subprocess exited with %d, expected %d\n", status
, expect
);
55 barrier_wait(&barrier
);
56 for (int i
= 0; i
< kSleeperThreads
; i
++)
57 pthread_join(th0
[i
], 0);
58 fprintf(stderr
, "OK\n");
62 // CHECK-DIE: ThreadSanitizer: starting new threads after multi-threaded fork is not supported
64 // CHECK-NODIE-NOT: ThreadSanitizer:
66 // CHECK-NODIE-NOT: ThreadSanitizer: