49 lines · cpp
1// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s2#include "test.h"3 4const int kTestCount = 3;5typedef long long T;6T data[kTestCount];7T atomics[kTestCount];8 9void *Thread(void *p) {10 for (int i = 0; i < kTestCount; i++) {11 barrier_wait(&barrier);12 while (__atomic_load_n(&atomics[i], __ATOMIC_ACQUIRE) == 0) {13 }14 data[i]++;15 }16 return 0;17}18 19int main() {20 barrier_init(&barrier, 2);21 pthread_t t;22 pthread_create(&t, 0, Thread, 0);23 for (int i = 0; i < kTestCount; i++) {24 barrier_wait(&barrier);25 // We want the release to happen while the other thread26 // spins calling load-acquire. This can expose some27 // interesting interleavings of release and acquire.28 usleep(100 * 1000);29 data[i] = 1;30 switch (i) {31 case 0:32 __atomic_store_n(&atomics[i], 1, __ATOMIC_RELEASE);33 break;34 case 1:35 __atomic_fetch_add(&atomics[1], 1, __ATOMIC_RELEASE);36 break;37 case 2:38 T cmp = 0;39 __atomic_compare_exchange_n(&atomics[2], &cmp, 1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED);40 break;41 }42 }43 pthread_join(t, 0);44 fprintf(stderr, "DONE\n");45}46 47// CHECK-NOT: ThreadSanitizer: data race48// CHECK: DONE49