1 // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s 2 #include "test.h" 3 4 // We want to establish the following sequence of accesses to X: 5 // - main thread writes X 6 // - thread2 reads X, this read happens-before the write in main thread 7 // - thread1 reads X, this read is concurrent with the write in main thread 8 // Write in main thread and read in thread1 should be detected as a race. 9 // Previously tsan replaced write by main thread with read by thread1, 10 // as the result the race was not detected. 11 12 volatile long X, Y, Z; 13 14 void *Thread1(void *x) { 15 barrier_wait(&barrier); 16 barrier_wait(&barrier); 17 Y = X; 18 return NULL; 19 } 20 21 void *Thread2(void *x) { 22 Z = X; 23 barrier_wait(&barrier); 24 return NULL; 25 } 26 27 int main() { 28 barrier_init(&barrier, 2); 29 pthread_t t[2]; 30 pthread_create(&t[0], 0, Thread1, 0); 31 X = 42; 32 barrier_wait(&barrier); 33 pthread_create(&t[1], 0, Thread2, 0); 34 pthread_join(t[0], 0); 35 pthread_join(t[1], 0); 36 return 0; 37 } 38 39 // CHECK: WARNING: ThreadSanitizer: data race 40 41