1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2 #include <pthread.h>
3 #include <stdio.h>
4 #include <unistd.h>
5
6 const int kTestCount = 4;
7 typedef long long T;
8 T atomics[kTestCount * 2];
9
Test(int test,T * p,bool main_thread)10 void Test(int test, T *p, bool main_thread) {
11 volatile T sink;
12 if (test == 0) {
13 if (main_thread)
14 __atomic_fetch_add(p, 1, __ATOMIC_RELAXED);
15 else
16 __atomic_fetch_add(p, 1, __ATOMIC_RELAXED);
17 } else if (test == 1) {
18 if (main_thread)
19 __atomic_exchange_n(p, 1, __ATOMIC_ACQ_REL);
20 else
21 __atomic_exchange_n(p, 1, __ATOMIC_ACQ_REL);
22 } else if (test == 2) {
23 if (main_thread)
24 sink = __atomic_load_n(p, __ATOMIC_SEQ_CST);
25 else
26 __atomic_store_n(p, 1, __ATOMIC_SEQ_CST);
27 } else if (test == 3) {
28 if (main_thread)
29 sink = __atomic_load_n(p, __ATOMIC_SEQ_CST);
30 else
31 sink = *p;
32 }
33 }
34
Thread(void * p)35 void *Thread(void *p) {
36 for (int i = 0; i < kTestCount; i++) {
37 Test(i, &atomics[i], false);
38 }
39 sleep(2);
40 for (int i = 0; i < kTestCount; i++) {
41 fprintf(stderr, "Test %d reverse\n", i);
42 Test(i, &atomics[kTestCount + i], false);
43 }
44 return 0;
45 }
46
main()47 int main() {
48 pthread_t t;
49 pthread_create(&t, 0, Thread, 0);
50 sleep(1);
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 }
58 pthread_join(t, 0);
59 }
60
61 // CHECK-NOT: ThreadSanitizer: data race
62