1 // RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=flush_memory_ms=1:flush_symbolizer_ms=1:memory_limit_mb=1 %run %t 2>&1 | FileCheck %s 2 #include "test.h" 3 #include <fcntl.h> 4 #include <string.h> 5 6 volatile long stop; 7 long atomic, read_only; 8 int fds[2]; 9 10 __attribute__((noinline)) void *SecondaryThread(void *x) { 11 __atomic_fetch_add(&atomic, 1, __ATOMIC_ACQ_REL); 12 return NULL; 13 } 14 15 void *Thread(void *x) { 16 const int me = (long)x; 17 volatile long sink = 0; 18 while (!stop) { 19 // If me == 0, we do all of the following, 20 // otherwise only 1 type of action. 21 if (me == 0 || me == 1) { 22 // just read the stop variable 23 } 24 if (me == 0 || me == 2) { 25 __atomic_store_n(&atomic, 1, __ATOMIC_RELEASE); 26 } 27 if (me == 0 || me == 3) { 28 sink += __atomic_fetch_add(&atomic, 1, __ATOMIC_ACQ_REL); 29 } 30 if (me == 0 || me == 4) { 31 SecondaryThread(NULL); 32 } 33 if (me == 0 || me == 5) { 34 write(fds[1], fds, 1); 35 } 36 if (me == 0 || me == 6) { 37 char buf[2]; 38 read(fds[0], &buf, sizeof(buf)); 39 } 40 if (me == 0 || me == 7) { 41 pthread_t th; 42 pthread_create(&th, NULL, SecondaryThread, NULL); 43 pthread_join(th, NULL); 44 } 45 if (me == 0 || me == 8) { 46 long buf; 47 memcpy(&buf, &read_only, sizeof(buf)); 48 sink += buf; 49 } 50 // If you add more actions, update kActions in main. 51 } 52 return NULL; 53 } 54 55 int main() { 56 ANNOTATE_BENIGN_RACE(stop); 57 if (pipe(fds)) 58 exit((perror("pipe"), 1)); 59 if (fcntl(fds[0], F_SETFL, O_NONBLOCK)) 60 exit((perror("fcntl"), 1)); 61 if (fcntl(fds[1], F_SETFL, O_NONBLOCK)) 62 exit((perror("fcntl"), 1)); 63 const int kActions = 9; 64 const int kMultiplier = 4; 65 pthread_t t[kActions * kMultiplier]; 66 for (int i = 0; i < kActions * kMultiplier; i++) 67 pthread_create(&t[i], NULL, Thread, (void *)(long)(i % kActions)); 68 sleep(5); 69 stop = 1; 70 for (int i = 0; i < kActions * kMultiplier; i++) 71 pthread_join(t[i], NULL); 72 fprintf(stderr, "DONE\n"); 73 return 0; 74 } 75 76 // CHECK-NOT: ThreadSanitizer: 77 // CHECK: DONE 78 // CHECK-NOT: ThreadSanitizer: 79