50 lines · cpp
1// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s2#include "test.h"3 4long long Data;5long long Sync;6 7void *Thread1(void *x) {8 Data++;9 __atomic_store_n(&Sync, 1, __ATOMIC_RELEASE);10 barrier_wait(&barrier);11 barrier_wait(&barrier);12 return NULL;13}14 15void *Thread2(void *x) {16 barrier_wait(&barrier);17 if (__atomic_load_n(&Sync, __ATOMIC_RELAXED) != 1)18 exit(0);19 // This store must terminate release sequence of the store in Thread1,20 // thus tsan must detect race between Thread1 and main on Data.21 __atomic_store_n(&Sync, 2, __ATOMIC_RELEASE);22 barrier_wait(&barrier);23 return NULL;24}25 26int main() {27 barrier_init(&barrier, 3);28 pthread_t t[2];29 pthread_create(&t[0], NULL, Thread1, NULL);30 pthread_create(&t[1], NULL, Thread2, NULL);31 barrier_wait(&barrier);32 barrier_wait(&barrier);33 if (__atomic_load_n(&Sync, __ATOMIC_ACQUIRE) != 2)34 exit(0);35 if (Data != 1)36 exit(0);37 pthread_join(t[0], NULL);38 pthread_join(t[1], NULL);39 fprintf(stderr, "DONE\n");40 return 0;41}42 43// CHECK: WARNING: ThreadSanitizer: data race44// CHECK: Read45// CHECK: #0 main46// CHECK: Previous write47// CHECK: #0 Thread148// CHECK: Location is global 'Data'49// CHECK: DONE50