]>
Commit | Line | Data |
---|---|---|
92a42be0 SL |
1 | // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s |
2 | #include "test.h" | |
1a4d82fc JJ |
3 | |
4 | const int kTestCount = 4; | |
5 | typedef long long T; | |
6 | T atomics[kTestCount * 2]; | |
7 | ||
8 | void Test(int test, T *p, bool main_thread) { | |
9 | volatile T sink; | |
10 | if (test == 0) { | |
11 | if (main_thread) | |
12 | __atomic_fetch_add(p, 1, __ATOMIC_RELAXED); | |
13 | else | |
14 | *p = 42; | |
15 | } else if (test == 1) { | |
16 | if (main_thread) | |
17 | __atomic_fetch_add(p, 1, __ATOMIC_RELAXED); | |
18 | else | |
19 | sink = *p; | |
20 | } else if (test == 2) { | |
21 | if (main_thread) | |
22 | sink = __atomic_load_n(p, __ATOMIC_SEQ_CST); | |
23 | else | |
24 | *p = 42; | |
25 | } else if (test == 3) { | |
26 | if (main_thread) | |
27 | __atomic_store_n(p, 1, __ATOMIC_SEQ_CST); | |
28 | else | |
29 | sink = *p; | |
30 | } | |
31 | } | |
32 | ||
33 | void *Thread(void *p) { | |
34 | for (int i = 0; i < kTestCount; i++) { | |
35 | Test(i, &atomics[i], false); | |
36 | } | |
92a42be0 SL |
37 | barrier_wait(&barrier); |
38 | barrier_wait(&barrier); | |
1a4d82fc JJ |
39 | for (int i = 0; i < kTestCount; i++) { |
40 | fprintf(stderr, "Test %d reverse\n", i); | |
41 | Test(i, &atomics[kTestCount + i], false); | |
42 | } | |
43 | return 0; | |
44 | } | |
45 | ||
46 | int main() { | |
92a42be0 | 47 | barrier_init(&barrier, 2); |
1a4d82fc JJ |
48 | pthread_t t; |
49 | pthread_create(&t, 0, Thread, 0); | |
92a42be0 | 50 | barrier_wait(&barrier); |
1a4d82fc JJ |
51 | for (int i = 0; i < kTestCount; i++) { |
52 | fprintf(stderr, "Test %d\n", i); | |
53 | Test(i, &atomics[i], true); | |
54 | } | |
55 | for (int i = 0; i < kTestCount; i++) { | |
56 | Test(i, &atomics[kTestCount + i], true); | |
57 | } | |
92a42be0 | 58 | barrier_wait(&barrier); |
1a4d82fc JJ |
59 | pthread_join(t, 0); |
60 | } | |
61 | ||
62 | // CHECK: Test 0 | |
63 | // CHECK: ThreadSanitizer: data race | |
64 | // CHECK-NOT: SUMMARY{{.*}}tsan_interface_atomic | |
65 | // CHECK: Test 1 | |
66 | // CHECK: ThreadSanitizer: data race | |
67 | // CHECK-NOT: SUMMARY{{.*}}tsan_interface_atomic | |
68 | // CHECK: Test 2 | |
69 | // CHECK: ThreadSanitizer: data race | |
70 | // CHECK-NOT: SUMMARY{{.*}}tsan_interface_atomic | |
71 | // CHECK: Test 3 | |
72 | // CHECK: ThreadSanitizer: data race | |
73 | // CHECK-NOT: SUMMARY{{.*}}tsan_interface_atomic | |
74 | // CHECK: Test 0 reverse | |
75 | // CHECK: ThreadSanitizer: data race | |
76 | // CHECK: Test 1 reverse | |
77 | // CHECK: ThreadSanitizer: data race | |
78 | // CHECK: Test 2 reverse | |
79 | // CHECK: ThreadSanitizer: data race | |
80 | // CHECK: Test 3 reverse | |
81 | // CHECK: ThreadSanitizer: data race |