1 | // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s |
2 | #include "test.h" |
3 | |
4 | int fds[2]; |
5 | |
6 | void *ThreadCreatePipe(void *x) { |
7 | pipe(pipedes: fds); |
8 | return NULL; |
9 | } |
10 | |
11 | void *ThreadDummy(void *x) { |
12 | return NULL; |
13 | } |
14 | |
15 | void *ThreadWrite(void *x) { |
16 | write(fd: fds[1], buf: "a" , n: 1); |
17 | barrier_wait(barrier: &barrier); |
18 | return NULL; |
19 | } |
20 | |
21 | void *ThreadClose(void *x) { |
22 | barrier_wait(barrier: &barrier); |
23 | close(fd: fds[0]); |
24 | close(fd: fds[1]); |
25 | return NULL; |
26 | } |
27 | |
28 | int main() { |
29 | barrier_init(barrier: &barrier, count: 2); |
30 | pthread_t t_create; |
31 | pthread_create(newthread: &t_create, NULL, start_routine: ThreadCreatePipe, NULL); |
32 | pthread_join(th: t_create, NULL); |
33 | |
34 | for (int i = 0; i < 100; i++) { |
35 | pthread_t t_dummy; |
36 | pthread_create(newthread: &t_dummy, NULL, start_routine: ThreadDummy, NULL); |
37 | pthread_join(th: t_dummy, NULL); |
38 | } |
39 | |
40 | pthread_t t[2]; |
41 | pthread_create(newthread: &t[0], NULL, start_routine: ThreadWrite, NULL); |
42 | pthread_create(newthread: &t[1], NULL, start_routine: ThreadClose, NULL); |
43 | pthread_join(th: t[0], NULL); |
44 | pthread_join(th: t[1], NULL); |
45 | } |
46 | |
47 | // CHECK-NOT: CHECK failed |
48 | // CHECK: WARNING: ThreadSanitizer: data race |
49 | // CHECK: Write of size 8 |
50 | // CHECK: #0 close |
51 | // CHECK: #1 ThreadClose |
52 | // CHECK: Previous read of size 8 |
53 | // CHECK: #0 write |
54 | // CHECK: #1 ThreadWrite |
55 | |