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 6const int kTestCount = 4; 7typedef long long T; 8T atomics[kTestCount * 2]; 9 10void 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 35void *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 47int 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