From 3ab6b2347e8d940b0687fb693c861c68d1e50998 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 21 Jan 2015 13:50:02 +0000 Subject: [PATCH] tsan: remove sleeps from tests Even sleep(1) lead to episodical flakes on some machines. Use an invisible by tsan barrier to enforce required execution order instead. This makes the tests deterministic and faster. llvm-svn: 226659 --- compiler-rt/test/tsan/atomic_free.cc | 7 +++-- compiler-rt/test/tsan/atomic_free2.cc | 7 +++-- compiler-rt/test/tsan/atomic_norace.cc | 11 ++++--- compiler-rt/test/tsan/atomic_race.cc | 11 ++++--- compiler-rt/test/tsan/atomic_stack.cc | 7 +++-- compiler-rt/test/tsan/benign_race.cc | 8 ++--- compiler-rt/test/tsan/blacklist2.cc | 8 ++--- compiler-rt/test/tsan/cond_cancel.c | 9 +++--- compiler-rt/test/tsan/cond_race.cc | 11 +++---- .../tsan/deadlock_detector_stress_test.cc | 25 ++++++++++----- compiler-rt/test/tsan/deep_stack1.cc | 16 +++++++--- compiler-rt/test/tsan/fd_close_norace.cc | 8 ++--- compiler-rt/test/tsan/fd_location.cc | 8 ++--- compiler-rt/test/tsan/fd_pipe_race.cc | 8 ++--- compiler-rt/test/tsan/fd_stdout_race.cc | 8 ++--- compiler-rt/test/tsan/fork_deadlock.cc | 8 ++--- compiler-rt/test/tsan/fork_multithreaded.cc | 14 +++++---- compiler-rt/test/tsan/free_race.c | 10 +++--- compiler-rt/test/tsan/global_race.cc | 9 +++--- compiler-rt/test/tsan/global_race2.cc | 9 +++--- compiler-rt/test/tsan/global_race3.cc | 9 +++--- compiler-rt/test/tsan/halt_on_error.cc | 8 ++--- compiler-rt/test/tsan/ignore_free.cc | 9 +++--- compiler-rt/test/tsan/ignore_malloc.cc | 7 ++--- compiler-rt/test/tsan/ignore_race.cc | 8 ++--- compiler-rt/test/tsan/inlined_memcpy_race.cc | 9 +++--- compiler-rt/test/tsan/inlined_memcpy_race2.cc | 9 +++--- compiler-rt/test/tsan/java.h | 5 +-- compiler-rt/test/tsan/java_finalizer.cc | 4 ++- compiler-rt/test/tsan/java_lock.cc | 5 +-- compiler-rt/test/tsan/java_lock_move.cc | 4 ++- compiler-rt/test/tsan/java_lock_rec.cc | 8 +++-- compiler-rt/test/tsan/java_lock_rec_race.cc | 8 +++-- compiler-rt/test/tsan/java_move_overlap.cc | 4 ++- .../test/tsan/java_move_overlap_race.cc | 4 ++- compiler-rt/test/tsan/java_race_move.cc | 4 ++- compiler-rt/test/tsan/java_rwlock.cc | 5 +-- compiler-rt/test/tsan/java_volatile.cc | 4 +-- compiler-rt/test/tsan/load_shared_lib.cc | 30 +++++++++++------- compiler-rt/test/tsan/malloc_stack.cc | 7 +++-- compiler-rt/test/tsan/map32bit.cc | 9 +++--- compiler-rt/test/tsan/memcpy_race.cc | 9 +++--- compiler-rt/test/tsan/mop_with_offset.cc | 9 +++--- compiler-rt/test/tsan/mop_with_offset2.cc | 9 +++--- compiler-rt/test/tsan/mutexset1.cc | 8 ++--- compiler-rt/test/tsan/mutexset2.cc | 8 ++--- compiler-rt/test/tsan/mutexset3.cc | 8 ++--- compiler-rt/test/tsan/mutexset4.cc | 8 ++--- compiler-rt/test/tsan/mutexset5.cc | 8 ++--- compiler-rt/test/tsan/mutexset6.cc | 8 ++--- compiler-rt/test/tsan/mutexset7.cc | 8 ++--- compiler-rt/test/tsan/mutexset8.cc | 8 ++--- compiler-rt/test/tsan/process_sleep.h | 7 ----- .../test/tsan/pthread_atfork_deadlock.c | 8 ++--- compiler-rt/test/tsan/race_on_barrier.c | 9 +++--- compiler-rt/test/tsan/race_on_mutex.c | 13 ++++---- compiler-rt/test/tsan/race_on_mutex2.c | 9 +++--- compiler-rt/test/tsan/race_on_puts.cc | 7 +++-- compiler-rt/test/tsan/race_on_read.cc | 20 +++++++----- .../test/tsan/race_on_speculative_load.cc | 11 ++++--- compiler-rt/test/tsan/race_on_write.cc | 9 +++--- .../test/tsan/race_with_finished_thread.cc | 11 +++---- compiler-rt/test/tsan/restore_stack.cc | 11 ++++--- compiler-rt/test/tsan/signal_errno.cc | 9 +++--- compiler-rt/test/tsan/signal_malloc.cc | 6 ++-- compiler-rt/test/tsan/signal_recursive.cc | 30 +++++++----------- compiler-rt/test/tsan/signal_sync.cc | 7 ++--- compiler-rt/test/tsan/signal_write.cc | 2 +- compiler-rt/test/tsan/simple_race.c | 8 ++--- compiler-rt/test/tsan/simple_race.cc | 8 ++--- compiler-rt/test/tsan/simple_stack.c | 24 +++++++------- compiler-rt/test/tsan/simple_stack2.cc | 20 ++++++------ compiler-rt/test/tsan/sleep_sync.cc | 8 +++-- compiler-rt/test/tsan/sleep_sync2.cc | 8 +++-- compiler-rt/test/tsan/stack_race.cc | 8 ++--- compiler-rt/test/tsan/stack_race2.cc | 8 ++--- compiler-rt/test/tsan/stack_sync_reuse.cc | 9 ++---- .../test/tsan/suppress_same_address.cc | 7 +++-- compiler-rt/test/tsan/suppressions_race.cc | 8 ++--- compiler-rt/test/tsan/suppressions_race2.cc | 8 ++--- compiler-rt/test/tsan/test.h | 31 +++++++++++++++++++ compiler-rt/test/tsan/thread_detach.c | 8 ++--- compiler-rt/test/tsan/thread_leak3.c | 8 +++-- compiler-rt/test/tsan/thread_leak4.c | 10 +++--- compiler-rt/test/tsan/thread_leak5.c | 8 +++-- compiler-rt/test/tsan/thread_name.cc | 8 ++--- compiler-rt/test/tsan/thread_name2.cc | 9 +++--- compiler-rt/test/tsan/tiny_race.c | 7 +++-- compiler-rt/test/tsan/tls_race.cc | 8 ++--- compiler-rt/test/tsan/tls_race2.cc | 8 ++--- compiler-rt/test/tsan/unaligned_race.cc | 9 +++--- compiler-rt/test/tsan/vptr_harmful_race.cc | 8 ++--- compiler-rt/test/tsan/vptr_harmful_race2.cc | 8 ++--- compiler-rt/test/tsan/vptr_harmful_race3.cc | 8 ++--- compiler-rt/test/tsan/vptr_harmful_race4.cc | 8 ++--- compiler-rt/test/tsan/write_in_reader_lock.cc | 9 +++--- 96 files changed, 476 insertions(+), 425 deletions(-) delete mode 100644 compiler-rt/test/tsan/process_sleep.h create mode 100644 compiler-rt/test/tsan/test.h diff --git a/compiler-rt/test/tsan/atomic_free.cc b/compiler-rt/test/tsan/atomic_free.cc index 1dcf887c41d5..a0d8e426b49f 100644 --- a/compiler-rt/test/tsan/atomic_free.cc +++ b/compiler-rt/test/tsan/atomic_free.cc @@ -1,17 +1,18 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" void *Thread(void *a) { __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST); + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); int *a = new int(0); pthread_t t; pthread_create(&t, 0, Thread, a); - sleep(1); + barrier_wait(&barrier); delete a; pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/atomic_free2.cc b/compiler-rt/test/tsan/atomic_free2.cc index c50be6bba940..4a9f268a4008 100644 --- a/compiler-rt/test/tsan/atomic_free2.cc +++ b/compiler-rt/test/tsan/atomic_free2.cc @@ -1,18 +1,19 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" void *Thread(void *a) { - sleep(1); + barrier_wait(&barrier); __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST); return 0; } int main() { + barrier_init(&barrier, 2); int *a = new int(0); pthread_t t; pthread_create(&t, 0, Thread, a); delete a; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/atomic_norace.cc b/compiler-rt/test/tsan/atomic_norace.cc index d9ccda58883c..625109b1fe63 100644 --- a/compiler-rt/test/tsan/atomic_norace.cc +++ b/compiler-rt/test/tsan/atomic_norace.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" const int kTestCount = 4; typedef long long T; @@ -36,7 +34,8 @@ void *Thread(void *p) { for (int i = 0; i < kTestCount; i++) { Test(i, &atomics[i], false); } - sleep(2); + barrier_wait(&barrier); + barrier_wait(&barrier); for (int i = 0; i < kTestCount; i++) { fprintf(stderr, "Test %d reverse\n", i); Test(i, &atomics[kTestCount + i], false); @@ -45,9 +44,10 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); for (int i = 0; i < kTestCount; i++) { fprintf(stderr, "Test %d\n", i); Test(i, &atomics[i], true); @@ -55,6 +55,7 @@ int main() { for (int i = 0; i < kTestCount; i++) { Test(i, &atomics[kTestCount + i], true); } + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/atomic_race.cc b/compiler-rt/test/tsan/atomic_race.cc index 9cee8ed8272f..5a0317c4acfa 100644 --- a/compiler-rt/test/tsan/atomic_race.cc +++ b/compiler-rt/test/tsan/atomic_race.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" const int kTestCount = 4; typedef long long T; @@ -36,7 +34,8 @@ void *Thread(void *p) { for (int i = 0; i < kTestCount; i++) { Test(i, &atomics[i], false); } - sleep(4); + barrier_wait(&barrier); + barrier_wait(&barrier); for (int i = 0; i < kTestCount; i++) { fprintf(stderr, "Test %d reverse\n", i); Test(i, &atomics[kTestCount + i], false); @@ -45,9 +44,10 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); for (int i = 0; i < kTestCount; i++) { fprintf(stderr, "Test %d\n", i); Test(i, &atomics[i], true); @@ -55,6 +55,7 @@ int main() { for (int i = 0; i < kTestCount; i++) { Test(i, &atomics[kTestCount + i], true); } + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/atomic_stack.cc b/compiler-rt/test/tsan/atomic_stack.cc index 7e3176f8e784..979eaea8b699 100644 --- a/compiler-rt/test/tsan/atomic_stack.cc +++ b/compiler-rt/test/tsan/atomic_stack.cc @@ -1,21 +1,22 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); __atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED); return NULL; } void *Thread2(void *x) { Global++; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/benign_race.cc b/compiler-rt/test/tsan/benign_race.cc index b6cba19aa96e..2f72fe1860d0 100644 --- a/compiler-rt/test/tsan/benign_race.cc +++ b/compiler-rt/test/tsan/benign_race.cc @@ -1,7 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; int WTFGlobal; @@ -18,10 +16,12 @@ void WTFAnnotateBenignRaceSized(const char *f, int l, void *Thread(void *x) { Global = 42; WTFGlobal = 142; + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); AnnotateBenignRaceSized(__FILE__, __LINE__, &Global, sizeof(Global), "Race on Global"); WTFAnnotateBenignRaceSized(__FILE__, __LINE__, @@ -29,7 +29,7 @@ int main() { "Race on WTFGlobal"); pthread_t t; pthread_create(&t, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); Global = 43; WTFGlobal = 143; pthread_join(t, 0); diff --git a/compiler-rt/test/tsan/blacklist2.cc b/compiler-rt/test/tsan/blacklist2.cc index 1092561e55bb..629b58821bfe 100644 --- a/compiler-rt/test/tsan/blacklist2.cc +++ b/compiler-rt/test/tsan/blacklist2.cc @@ -5,14 +5,12 @@ // RUN: %clangxx_tsan -O1 %s -fsanitize-blacklist=%t.blacklist -o %t // RUN: %deflake %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); // CHECK: ThreadSanitizer: data race // CHECK: Write of size 4 // CHECK: #0 Thread1{{.*}}blacklist2.cc:[[@LINE+1]] @@ -35,10 +33,12 @@ void *Blacklisted_Thread2(void *x) { Global--; // CHECK: #2 Blacklisted_Thread2{{.*}}blacklist2.cc:[[@LINE+1]] CallTouchGlobal(); + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Blacklisted_Thread2, NULL); diff --git a/compiler-rt/test/tsan/cond_cancel.c b/compiler-rt/test/tsan/cond_cancel.c index 397cad4b1838..e744570b12fc 100644 --- a/compiler-rt/test/tsan/cond_cancel.c +++ b/compiler-rt/test/tsan/cond_cancel.c @@ -2,10 +2,7 @@ // CHECK-NOT: WARNING // CHECK: OK -#include -#include -#include -#include +#include "test.h" pthread_mutex_t m; pthread_cond_t c; @@ -14,6 +11,7 @@ int x; void *thr1(void *p) { pthread_mutex_lock(&m); pthread_cleanup_push((void(*)(void *arg))pthread_mutex_unlock, &m); + barrier_wait(&barrier); while (x == 0) pthread_cond_wait(&c, &m); pthread_cleanup_pop(1); @@ -21,12 +19,15 @@ void *thr1(void *p) { } int main() { + barrier_init(&barrier, 2); + pthread_t th; pthread_mutex_init(&m, 0); pthread_cond_init(&c, 0); pthread_create(&th, 0, thr1, 0); + barrier_wait(&barrier); sleep(1); // let it block on cond var pthread_cancel(th); diff --git a/compiler-rt/test/tsan/cond_race.cc b/compiler-rt/test/tsan/cond_race.cc index fa42fafca4d2..52654f16e85c 100644 --- a/compiler-rt/test/tsan/cond_race.cc +++ b/compiler-rt/test/tsan/cond_race.cc @@ -3,10 +3,7 @@ // CHECK: ThreadSanitizer: data race // CHECK: pthread_cond_signal -#include -#include -#include -#include +#include "test.h" struct Ctx { pthread_mutex_t m; @@ -20,10 +17,12 @@ void *thr(void *p) { c->done = true; pthread_mutex_unlock(&c->m); pthread_cond_signal(&c->c); + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); Ctx *c = new Ctx(); pthread_mutex_init(&c->m, 0); pthread_cond_init(&c->c, 0); @@ -33,8 +32,8 @@ int main() { while (!c->done) pthread_cond_wait(&c->c, &c->m); pthread_mutex_unlock(&c->m); - // w/o this sleep, it can be reported as use-after-free - sleep(1); + // otherwise it can be reported as use-after-free + barrier_wait(&barrier); delete c; pthread_join(th, 0); } diff --git a/compiler-rt/test/tsan/deadlock_detector_stress_test.cc b/compiler-rt/test/tsan/deadlock_detector_stress_test.cc index 53624782e07b..e02a9123f5af 100644 --- a/compiler-rt/test/tsan/deadlock_detector_stress_test.cc +++ b/compiler-rt/test/tsan/deadlock_detector_stress_test.cc @@ -7,12 +7,9 @@ // RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD // RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRecursiveMutex // RUN: TSAN_OPTIONS=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC -#include +#include "test.h" #undef NDEBUG #include -#include -#include -#include #include #ifndef LockType @@ -224,7 +221,7 @@ class LockTest { fprintf(stderr, "Starting Test5\n"); // CHECK: Starting Test5 Init(5); - RunThreads(&LockTest::Lock_0_1, &LockTest::Lock_1_0); + RunThreads(&LockTest::Lock_0_1, &LockTest::Lock_1_0); // CHECK: WARNING: ThreadSanitizer: lock-order-inversion // CHECK: Cycle in lock order graph: [[M1:M[0-9]+]] ({{.*}}) => [[M2:M[0-9]+]] ({{.*}}) => [[M1]] // CHECK: Mutex [[M2]] acquired here while holding mutex [[M1]] in thread [[T1:T[0-9]+]] @@ -503,8 +500,21 @@ class LockTest { private: void Lock2(size_t l1, size_t l2) { L(l1); L(l2); U(l2); U(l1); } - void Lock_0_1() { Lock2(0, 1); } - void Lock_1_0() { sleep(1); Lock2(1, 0); } + + template + void Lock_0_1() { + Lock2(0, 1); + if (wait) + barrier_wait(&barrier); + } + + template + void Lock_1_0() { + if (wait) + barrier_wait(&barrier); + Lock2(1, 0); + } + void Lock1_Loop(size_t i, size_t n_iter) { for (size_t it = 0; it < n_iter; it++) { // if ((it & (it - 1)) == 0) fprintf(stderr, "%zd", i); @@ -569,6 +579,7 @@ class LockTest { }; int main(int argc, char **argv) { + barrier_init(&barrier, 2); if (argc > 1) test_number = atoi(argv[1]); if (argc > 2) diff --git a/compiler-rt/test/tsan/deep_stack1.cc b/compiler-rt/test/tsan/deep_stack1.cc index 1d00a0e856d5..39185efee7a9 100644 --- a/compiler-rt/test/tsan/deep_stack1.cc +++ b/compiler-rt/test/tsan/deep_stack1.cc @@ -1,8 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t -DORDER1 && %deflake %run %t | FileCheck %s // RUN: %clangxx_tsan -O1 %s -o %t -DORDER2 && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" volatile int X; volatile int N; @@ -17,13 +15,17 @@ static void foo() { void *Thread(void *p) { #ifdef ORDER1 - sleep(1); + barrier_wait(&barrier); #endif F(); +#ifdef ORDER2 + barrier_wait(&barrier); +#endif return 0; } int main() { + barrier_init(&barrier, 2); N = 50000; F = foo; pthread_t t; @@ -32,9 +34,13 @@ int main() { pthread_attr_setstacksize(&a, N * 256 + (1 << 20)); pthread_create(&t, &a, Thread, 0); #ifdef ORDER2 - sleep(1); + barrier_wait(&barrier); #endif X = 43; +#ifdef ORDER1 + barrier_wait(&barrier); +#endif + pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/fd_close_norace.cc b/compiler-rt/test/tsan/fd_close_norace.cc index 7238d64b432b..1b52c20f990c 100644 --- a/compiler-rt/test/tsan/fd_close_norace.cc +++ b/compiler-rt/test/tsan/fd_close_norace.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" #include #include #include @@ -9,17 +7,19 @@ void *Thread1(void *x) { int f = open("/dev/random", O_RDONLY); close(f); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); int f = open("/dev/random", O_RDONLY); close(f); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/fd_location.cc b/compiler-rt/test/tsan/fd_location.cc index 535329e06409..1861c89cba9b 100644 --- a/compiler-rt/test/tsan/fd_location.cc +++ b/compiler-rt/test/tsan/fd_location.cc @@ -1,23 +1,23 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int fds[2]; void *Thread1(void *x) { write(fds[1], "a", 1); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); close(fds[0]); close(fds[1]); return NULL; } int main() { + barrier_init(&barrier, 2); pipe(fds); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); diff --git a/compiler-rt/test/tsan/fd_pipe_race.cc b/compiler-rt/test/tsan/fd_pipe_race.cc index 88c4ed4aa398..b94893b93691 100644 --- a/compiler-rt/test/tsan/fd_pipe_race.cc +++ b/compiler-rt/test/tsan/fd_pipe_race.cc @@ -1,23 +1,23 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int fds[2]; void *Thread1(void *x) { write(fds[1], "a", 1); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); close(fds[0]); close(fds[1]); return NULL; } int main() { + barrier_init(&barrier, 2); pipe(fds); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); diff --git a/compiler-rt/test/tsan/fd_stdout_race.cc b/compiler-rt/test/tsan/fd_stdout_race.cc index d6a2c7c796f1..fcf8c21300c6 100644 --- a/compiler-rt/test/tsan/fd_stdout_race.cc +++ b/compiler-rt/test/tsan/fd_stdout_race.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include #include #include @@ -9,7 +7,7 @@ int X; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); int f = open("/dev/random", O_RDONLY); char buf; read(f, &buf, 1); @@ -21,10 +19,12 @@ void *Thread1(void *x) { void *Thread2(void *x) { X = 43; write(STDOUT_FILENO, "a", 1); + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/fork_deadlock.cc b/compiler-rt/test/tsan/fork_deadlock.cc index cc5b12214cf9..9418800bd336 100644 --- a/compiler-rt/test/tsan/fork_deadlock.cc +++ b/compiler-rt/test/tsan/fork_deadlock.cc @@ -1,9 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="atexit_sleep_ms=50" %run %t 2>&1 | FileCheck %s -#include -#include +#include "test.h" #include -#include -#include #include #include @@ -16,13 +13,14 @@ static void *incrementer(void *p) { } static void *watchdog(void *p) { - sleep(100); + sleep(100); // is not intended to exit fprintf(stderr, "timed out after 100 seconds\n"); exit(1); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t th1, th2; pthread_create(&th1, 0, incrementer, 0); pthread_create(&th2, 0, watchdog, 0); diff --git a/compiler-rt/test/tsan/fork_multithreaded.cc b/compiler-rt/test/tsan/fork_multithreaded.cc index 5176a14d6a65..3ddb417c7cb5 100644 --- a/compiler-rt/test/tsan/fork_multithreaded.cc +++ b/compiler-rt/test/tsan/fork_multithreaded.cc @@ -1,19 +1,21 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-DIE // RUN: %clangxx_tsan -O1 %s -o %t && TSAN_OPTIONS="die_after_fork=0" %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-NODIE -#include -#include +#include "test.h" #include -#include -#include #include #include static void *sleeper(void *p) { - sleep(10); + sleep(10); // not intended to exit during test + return 0; +} + +static void *nop(void *p) { return 0; } int main() { + barrier_init(&barrier, 2); pthread_t th; pthread_create(&th, 0, sleeper, 0); switch (fork()) { @@ -23,7 +25,7 @@ int main() { case 0: // child { pthread_t th2; - pthread_create(&th2, 0, sleeper, 0); + pthread_create(&th2, 0, nop, 0); exit(0); break; } diff --git a/compiler-rt/test/tsan/free_race.c b/compiler-rt/test/tsan/free_race.c index 0fcfa4e90f8e..63cee8c4adc5 100644 --- a/compiler-rt/test/tsan/free_race.c +++ b/compiler-rt/test/tsan/free_race.c @@ -2,11 +2,7 @@ // RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOZUPP // RUN: TSAN_OPTIONS="suppressions='%s.supp' print_suppressions=1" %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP -#include -#include -#include -#include -#include +#include "test.h" int *mem; pthread_mutex_t mtx; @@ -15,11 +11,12 @@ void *Thread1(void *x) { pthread_mutex_lock(&mtx); free(mem); pthread_mutex_unlock(&mtx); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(&mtx); mem[0] = 42; pthread_mutex_unlock(&mtx); @@ -27,6 +24,7 @@ void *Thread2(void *x) { } int main() { + barrier_init(&barrier, 2); mem = (int*)malloc(100); pthread_mutex_init(&mtx, 0); pthread_t t; diff --git a/compiler-rt/test/tsan/global_race.cc b/compiler-rt/test/tsan/global_race.cc index e12bb1d220f8..d70bee4a556b 100644 --- a/compiler-rt/test/tsan/global_race.cc +++ b/compiler-rt/test/tsan/global_race.cc @@ -1,24 +1,23 @@ // RUN: %clangxx_tsan -O1 %s -o %T/global_race.cc.exe && %deflake %run %T/global_race.cc.exe | FileCheck %s -#include -#include -#include -#include +#include "test.h" int GlobalData[10]; void *Thread(void *a) { - sleep(1); + barrier_wait(&barrier); GlobalData[2] = 42; return 0; } int main() { + barrier_init(&barrier, 2); // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not // match to the format used in the diagnotic message. fprintf(stderr, "addr=0x%012lx\n", (unsigned long) GlobalData); pthread_t t; pthread_create(&t, 0, Thread, 0); GlobalData[2] = 43; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/global_race2.cc b/compiler-rt/test/tsan/global_race2.cc index ac994cc0f4c4..6631008d85a5 100644 --- a/compiler-rt/test/tsan/global_race2.cc +++ b/compiler-rt/test/tsan/global_race2.cc @@ -1,24 +1,23 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" int x; void *Thread(void *a) { - sleep(1); + barrier_wait(&barrier); x = 1; return 0; } int main() { + barrier_init(&barrier, 2); // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not // match to the format used in the diagnotic message. fprintf(stderr, "addr2=0x%012lx\n", (unsigned long) &x); pthread_t t; pthread_create(&t, 0, Thread, 0); x = 0; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/global_race3.cc b/compiler-rt/test/tsan/global_race3.cc index a3222bb3d8cb..e7e9a7fef028 100644 --- a/compiler-rt/test/tsan/global_race3.cc +++ b/compiler-rt/test/tsan/global_race3.cc @@ -1,8 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" namespace XXX { struct YYY { @@ -12,18 +9,20 @@ namespace XXX { } void *Thread(void *a) { - sleep(1); + barrier_wait(&barrier); XXX::YYY::ZZZ[0] = 1; return 0; } int main() { + barrier_init(&barrier, 2); // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not // match to the format used in the diagnotic message. fprintf(stderr, "addr3=0x%012lx\n", (unsigned long) XXX::YYY::ZZZ); pthread_t t; pthread_create(&t, 0, Thread, 0); XXX::YYY::ZZZ[0] = 0; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/halt_on_error.cc b/compiler-rt/test/tsan/halt_on_error.cc index 3c55c60a457e..e55454b57c1d 100644 --- a/compiler-rt/test/tsan/halt_on_error.cc +++ b/compiler-rt/test/tsan/halt_on_error.cc @@ -1,21 +1,21 @@ // RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS halt_on_error=1" %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int X; void *Thread(void *x) { - sleep(1); + barrier_wait(&barrier); X = 42; return 0; } int main() { + barrier_init(&barrier, 2); fprintf(stderr, "BEFORE\n"); pthread_t t; pthread_create(&t, 0, Thread, 0); X = 43; + barrier_wait(&barrier); pthread_join(t, 0); fprintf(stderr, "AFTER\n"); return 0; diff --git a/compiler-rt/test/tsan/ignore_free.cc b/compiler-rt/test/tsan/ignore_free.cc index 1df6dce2f5e0..bb6c6ee14364 100644 --- a/compiler-rt/test/tsan/ignore_free.cc +++ b/compiler-rt/test/tsan/ignore_free.cc @@ -1,8 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include -#include +#include "test.h" extern "C" { void AnnotateIgnoreReadsBegin(const char *f, int l); @@ -13,14 +10,16 @@ void AnnotateIgnoreWritesEnd(const char *f, int l); void *Thread(void *p) { *(int*)p = 42; + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); int *p = new int(0); pthread_t t; pthread_create(&t, 0, Thread, p); - sleep(1); + barrier_wait(&barrier); AnnotateIgnoreReadsBegin(__FILE__, __LINE__); AnnotateIgnoreWritesBegin(__FILE__, __LINE__); free(p); diff --git a/compiler-rt/test/tsan/ignore_malloc.cc b/compiler-rt/test/tsan/ignore_malloc.cc index 0f1fb5e3dfdc..1f633f062d0e 100644 --- a/compiler-rt/test/tsan/ignore_malloc.cc +++ b/compiler-rt/test/tsan/ignore_malloc.cc @@ -1,8 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include -#include +#include "test.h" extern "C" { void AnnotateIgnoreReadsBegin(const char *f, int l); @@ -16,7 +13,7 @@ int *g; void *Thread(void *a) { int *p = 0; while ((p = __atomic_load_n(&g, __ATOMIC_RELAXED)) == 0) - usleep(100); + usleep(100); // spin-wait *p = 42; return 0; } diff --git a/compiler-rt/test/tsan/ignore_race.cc b/compiler-rt/test/tsan/ignore_race.cc index c6e067fabec0..cc33b66b27d4 100644 --- a/compiler-rt/test/tsan/ignore_race.cc +++ b/compiler-rt/test/tsan/ignore_race.cc @@ -1,7 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; @@ -16,13 +14,15 @@ void *Thread(void *x) { Global = 42; AnnotateIgnoreReadsEnd(__FILE__, __LINE__); AnnotateIgnoreWritesEnd(__FILE__, __LINE__); + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); Global = 43; pthread_join(t, 0); printf("OK\n"); diff --git a/compiler-rt/test/tsan/inlined_memcpy_race.cc b/compiler-rt/test/tsan/inlined_memcpy_race.cc index a95576a83c9a..e3ed07abcf89 100644 --- a/compiler-rt/test/tsan/inlined_memcpy_race.cc +++ b/compiler-rt/test/tsan/inlined_memcpy_race.cc @@ -1,24 +1,23 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include -#include int x[4], z[4]; void *MemCpyThread(void *a) { memcpy((int*)a, z, 16); + barrier_wait(&barrier); return NULL; } void *MemSetThread(void *a) { - sleep(1); + barrier_wait(&barrier); memset((int*)a, 0, 16); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; // Race on x between memcpy and memset pthread_create(&t[0], NULL, MemCpyThread, x); diff --git a/compiler-rt/test/tsan/inlined_memcpy_race2.cc b/compiler-rt/test/tsan/inlined_memcpy_race2.cc index 63b560f02269..37414ba5d3db 100644 --- a/compiler-rt/test/tsan/inlined_memcpy_race2.cc +++ b/compiler-rt/test/tsan/inlined_memcpy_race2.cc @@ -1,24 +1,23 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include -#include int y[4], z[4]; void *MemMoveThread(void *a) { memmove((int*)a, z, 16); + barrier_wait(&barrier); return NULL; } void *MemSetThread(void *a) { - sleep(1); + barrier_wait(&barrier); memset((int*)a, 0, 16); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; // Race on y between memmove and memset pthread_create(&t[0], NULL, MemMoveThread, y); diff --git a/compiler-rt/test/tsan/java.h b/compiler-rt/test/tsan/java.h index 66f46239a7c3..35fdbc1e7bb1 100644 --- a/compiler-rt/test/tsan/java.h +++ b/compiler-rt/test/tsan/java.h @@ -1,7 +1,4 @@ -#include -#include -#include -#include +#include "test.h" extern "C" { typedef unsigned long jptr; // NOLINT diff --git a/compiler-rt/test/tsan/java_finalizer.cc b/compiler-rt/test/tsan/java_finalizer.cc index d5c6a22d1e16..acbbf08ad711 100644 --- a/compiler-rt/test/tsan/java_finalizer.cc +++ b/compiler-rt/test/tsan/java_finalizer.cc @@ -2,13 +2,14 @@ #include "java.h" void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); __tsan_java_finalize(); *(int*)p = 42; return 0; } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -17,6 +18,7 @@ int main() { pthread_t th; pthread_create(&th, 0, Thread, (void*)jheap); *(int*)jheap = 43; + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(jheap, kBlockSize); fprintf(stderr, "DONE\n"); diff --git a/compiler-rt/test/tsan/java_lock.cc b/compiler-rt/test/tsan/java_lock.cc index 36a0f8b7bff3..f1720529523c 100644 --- a/compiler-rt/test/tsan/java_lock.cc +++ b/compiler-rt/test/tsan/java_lock.cc @@ -1,12 +1,11 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s #include "java.h" -#include jptr varaddr; jptr lockaddr; void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); __tsan_java_mutex_lock(lockaddr); *(int*)varaddr = 42; __tsan_java_mutex_unlock(lockaddr); @@ -14,6 +13,7 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -26,6 +26,7 @@ int main() { __tsan_java_mutex_lock(lockaddr); *(int*)varaddr = 43; __tsan_java_mutex_unlock(lockaddr); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(jheap, kBlockSize); fprintf(stderr, "DONE\n"); diff --git a/compiler-rt/test/tsan/java_lock_move.cc b/compiler-rt/test/tsan/java_lock_move.cc index 19c3e35d6633..fe5491dc2aa0 100644 --- a/compiler-rt/test/tsan/java_lock_move.cc +++ b/compiler-rt/test/tsan/java_lock_move.cc @@ -7,7 +7,7 @@ jptr varaddr2; jptr lockaddr2; void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); __tsan_java_mutex_lock(lockaddr2); *(int*)varaddr2 = 42; __tsan_java_mutex_unlock(lockaddr2); @@ -15,6 +15,7 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -31,6 +32,7 @@ int main() { *(int*)varaddr = 43; __tsan_java_mutex_unlock(lockaddr); __tsan_java_move(varaddr, varaddr2, kBlockSize); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(varaddr2, kBlockSize); printf("DONE\n"); diff --git a/compiler-rt/test/tsan/java_lock_rec.cc b/compiler-rt/test/tsan/java_lock_rec.cc index 2b0ab0eb92d0..f0bf40196e9f 100644 --- a/compiler-rt/test/tsan/java_lock_rec.cc +++ b/compiler-rt/test/tsan/java_lock_rec.cc @@ -1,6 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s #include "java.h" -#include jptr varaddr; jptr lockaddr; @@ -14,7 +13,8 @@ void *Thread(void *p) { printf("FAILED 0 rec=%d\n", rec); exit(1); } - sleep(2); + barrier_wait(&barrier); + barrier_wait(&barrier); __tsan_java_mutex_lock_rec(lockaddr, rec); if (*(int*)varaddr != 43) { printf("FAILED 3 var=%d\n", *(int*)varaddr); @@ -26,6 +26,7 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -36,7 +37,7 @@ int main() { lockaddr = jheap + 8; pthread_t th; pthread_create(&th, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); __tsan_java_mutex_lock(lockaddr); if (*(int*)varaddr != 42) { printf("FAILED 1 var=%d\n", *(int*)varaddr); @@ -44,6 +45,7 @@ int main() { } *(int*)varaddr = 43; __tsan_java_mutex_unlock(lockaddr); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(jheap, kBlockSize); printf("DONE\n"); diff --git a/compiler-rt/test/tsan/java_lock_rec_race.cc b/compiler-rt/test/tsan/java_lock_rec_race.cc index 841aa396360d..3da8ad076990 100644 --- a/compiler-rt/test/tsan/java_lock_rec_race.cc +++ b/compiler-rt/test/tsan/java_lock_rec_race.cc @@ -1,6 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s #include "java.h" -#include jptr varaddr; jptr lockaddr; @@ -15,7 +14,8 @@ void *Thread(void *p) { exit(1); } *(int*)varaddr = 42; - sleep(2); + barrier_wait(&barrier); + barrier_wait(&barrier); __tsan_java_mutex_lock_rec(lockaddr, rec); __tsan_java_mutex_unlock(lockaddr); __tsan_java_mutex_unlock(lockaddr); @@ -24,6 +24,7 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -34,10 +35,11 @@ int main() { lockaddr = jheap + 8; pthread_t th; pthread_create(&th, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); __tsan_java_mutex_lock(lockaddr); *(int*)varaddr = 43; __tsan_java_mutex_unlock(lockaddr); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(jheap, kBlockSize); printf("DONE\n"); diff --git a/compiler-rt/test/tsan/java_move_overlap.cc b/compiler-rt/test/tsan/java_move_overlap.cc index 12955b4ba0de..7ed98ef1a210 100644 --- a/compiler-rt/test/tsan/java_move_overlap.cc +++ b/compiler-rt/test/tsan/java_move_overlap.cc @@ -13,7 +13,7 @@ jptr lockaddr1_new; jptr lockaddr2_new; void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); __tsan_java_mutex_lock(lockaddr1_new); *(char*)varaddr1_new = 43; __tsan_java_mutex_unlock(lockaddr1_new); @@ -24,6 +24,7 @@ void *Thread(void *p) { } int main(int argc, char **argv) { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; void *jheap = malloc(kHeapSize); jheap = (char*)jheap + 8; @@ -62,6 +63,7 @@ int main(int argc, char **argv) { __tsan_java_mutex_unlock(lockaddr2_old); __tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(varaddr1_new, kBlockSize); printf("DONE\n"); diff --git a/compiler-rt/test/tsan/java_move_overlap_race.cc b/compiler-rt/test/tsan/java_move_overlap_race.cc index 2b3769be6117..874b90b26341 100644 --- a/compiler-rt/test/tsan/java_move_overlap_race.cc +++ b/compiler-rt/test/tsan/java_move_overlap_race.cc @@ -9,13 +9,14 @@ jptr varaddr1_new; jptr varaddr2_new; void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); *(int*)varaddr1_new = 43; *(int*)varaddr2_new = 43; return 0; } int main(int argc, char **argv) { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; void *jheap = malloc(kHeapSize); jheap = (char*)jheap + 8; @@ -42,6 +43,7 @@ int main(int argc, char **argv) { *(int*)varaddr2_old = 43; __tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(varaddr1_new, kBlockSize); printf("DONE\n"); diff --git a/compiler-rt/test/tsan/java_race_move.cc b/compiler-rt/test/tsan/java_race_move.cc index 8a51be92aa10..6d1b092160e0 100644 --- a/compiler-rt/test/tsan/java_race_move.cc +++ b/compiler-rt/test/tsan/java_race_move.cc @@ -5,12 +5,13 @@ jptr varaddr; jptr varaddr2; void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); *(int*)varaddr2 = 42; return 0; } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -23,6 +24,7 @@ int main() { pthread_create(&th, 0, Thread, 0); *(int*)varaddr = 43; __tsan_java_move(varaddr, varaddr2, kBlockSize); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(varaddr2, kBlockSize); fprintf(stderr, "DONE\n"); diff --git a/compiler-rt/test/tsan/java_rwlock.cc b/compiler-rt/test/tsan/java_rwlock.cc index b03afa6e092d..a4cc92a13635 100644 --- a/compiler-rt/test/tsan/java_rwlock.cc +++ b/compiler-rt/test/tsan/java_rwlock.cc @@ -1,12 +1,11 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s #include "java.h" -#include jptr varaddr; jptr lockaddr; void *Thread(void *p) { - sleep(1); + barrier_wait(&barrier); __tsan_java_mutex_read_lock(lockaddr); *(int*)varaddr = 42; __tsan_java_mutex_read_unlock(lockaddr); @@ -14,6 +13,7 @@ void *Thread(void *p) { } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); @@ -26,6 +26,7 @@ int main() { __tsan_java_mutex_lock(lockaddr); *(int*)varaddr = 43; __tsan_java_mutex_unlock(lockaddr); + barrier_wait(&barrier); pthread_join(th, 0); __tsan_java_free(jheap, kBlockSize); printf("DONE\n"); diff --git a/compiler-rt/test/tsan/java_volatile.cc b/compiler-rt/test/tsan/java_volatile.cc index 56f4c2dd481c..885b4f241712 100644 --- a/compiler-rt/test/tsan/java_volatile.cc +++ b/compiler-rt/test/tsan/java_volatile.cc @@ -1,19 +1,19 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s #include "java.h" -#include jptr varaddr; jptr lockaddr; void *Thread(void *p) { while (__atomic_load_n((int*)lockaddr, __ATOMIC_RELAXED) == 0) - usleep(1000); + usleep(1000); // spin-wait __tsan_java_acquire(lockaddr); *(int*)varaddr = 42; return 0; } int main() { + barrier_init(&barrier, 2); int const kHeapSize = 1024 * 1024; jptr jheap = (jptr)malloc(kHeapSize + 8) + 8; __tsan_java_init(jheap, kHeapSize); diff --git a/compiler-rt/test/tsan/load_shared_lib.cc b/compiler-rt/test/tsan/load_shared_lib.cc index a27dc1cc6ffb..b7934b82df73 100644 --- a/compiler-rt/test/tsan/load_shared_lib.cc +++ b/compiler-rt/test/tsan/load_shared_lib.cc @@ -7,35 +7,39 @@ #ifdef BUILD_SO -#include -#include +#include "test.h" int GLOB_SHARED = 0; +extern "C" +void init_so() { + barrier_init(&barrier, 2); +} + extern "C" void *write_from_so(void *unused) { - if (unused) - sleep(1); + if (unused == 0) + barrier_wait(&barrier); GLOB_SHARED++; + if (unused != 0) + barrier_wait(&barrier); return NULL; } #else // BUILD_SO +#include "test.h" #include -#include -#include -#include -#include - #include int GLOB = 0; void *write_glob(void *unused) { - if (unused) - sleep(1); + if (unused == 0) + barrier_wait(&barrier); GLOB++; + if (unused != 0) + barrier_wait(&barrier); return NULL; } @@ -48,6 +52,7 @@ void race_two_threads(void *(*access_callback)(void *unused)) { } int main(int argc, char *argv[]) { + barrier_init(&barrier, 2); std::string path = std::string(argv[0]) + std::string("-so.so"); race_two_threads(write_glob); // CHECK: write_glob @@ -56,6 +61,9 @@ int main(int argc, char *argv[]) { printf("error in dlopen(): %s\n", dlerror()); return 1; } + void (*init_so)(); + *(void **)&init_so = dlsym(lib, "init_so"); + init_so(); void *(*write_from_so)(void *unused); *(void **)&write_from_so = dlsym(lib, "write_from_so"); race_two_threads(write_from_so); diff --git a/compiler-rt/test/tsan/malloc_stack.cc b/compiler-rt/test/tsan/malloc_stack.cc index 6027360754aa..ba1d62bcd9e7 100644 --- a/compiler-rt/test/tsan/malloc_stack.cc +++ b/compiler-rt/test/tsan/malloc_stack.cc @@ -1,20 +1,21 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" _Atomic(int*) p; void *thr(void *a) { - sleep(1); + barrier_wait(&barrier); int *pp = __c11_atomic_load(&p, __ATOMIC_RELAXED); *pp = 42; return 0; } int main() { + barrier_init(&barrier, 2); pthread_t th; pthread_create(&th, 0, thr, p); __c11_atomic_store(&p, new int, __ATOMIC_RELAXED); + barrier_wait(&barrier); pthread_join(th, 0); } diff --git a/compiler-rt/test/tsan/map32bit.cc b/compiler-rt/test/tsan/map32bit.cc index 3a76fa2f6d62..9dae6880e7fe 100644 --- a/compiler-rt/test/tsan/map32bit.cc +++ b/compiler-rt/test/tsan/map32bit.cc @@ -1,9 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" #include -#include #include #include @@ -12,10 +9,12 @@ void *Thread(void *ptr) { *(int*)ptr = 42; + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); void *ptr = mmap(0, 128 << 10, PROT_READ|PROT_WRITE, MAP_32BIT|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); fprintf(stderr, "ptr=%p\n", ptr); @@ -29,7 +28,7 @@ int main() { } pthread_t t; pthread_create(&t, 0, Thread, ptr); - sleep(1); + barrier_wait(&barrier); *(int*)ptr = 42; pthread_join(t, 0); munmap(ptr, 128 << 10); diff --git a/compiler-rt/test/tsan/memcpy_race.cc b/compiler-rt/test/tsan/memcpy_race.cc index 8ec8e0a3e6a5..d49577306d6c 100644 --- a/compiler-rt/test/tsan/memcpy_race.cc +++ b/compiler-rt/test/tsan/memcpy_race.cc @@ -1,9 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include -#include char *data = new char[10]; char *data1 = new char[10]; @@ -12,17 +9,19 @@ char *data2 = new char[10]; void *Thread1(void *x) { static volatile int size = 1; memcpy(data+5, data1, size); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { static volatile int size = 4; - sleep(1); + barrier_wait(&barrier); memcpy(data+3, data2, size); return NULL; } int main() { + barrier_init(&barrier, 2); fprintf(stderr, "addr=%p\n", &data[5]); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); diff --git a/compiler-rt/test/tsan/mop_with_offset.cc b/compiler-rt/test/tsan/mop_with_offset.cc index e44c78b7d1b4..c67e81e09cda 100644 --- a/compiler-rt/test/tsan/mop_with_offset.cc +++ b/compiler-rt/test/tsan/mop_with_offset.cc @@ -1,23 +1,22 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" void *Thread1(void *x) { int *p = (int*)x; p[0] = 1; + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); char *p = (char*)x; p[2] = 1; return NULL; } int main() { + barrier_init(&barrier, 2); int *data = new int(42); fprintf(stderr, "ptr1=%p\n", data); fprintf(stderr, "ptr2=%p\n", (char*)data + 2); diff --git a/compiler-rt/test/tsan/mop_with_offset2.cc b/compiler-rt/test/tsan/mop_with_offset2.cc index a465d5f09471..460267359cec 100644 --- a/compiler-rt/test/tsan/mop_with_offset2.cc +++ b/compiler-rt/test/tsan/mop_with_offset2.cc @@ -1,11 +1,8 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); int *p = (int*)x; p[0] = 1; return NULL; @@ -14,10 +11,12 @@ void *Thread1(void *x) { void *Thread2(void *x) { char *p = (char*)x; p[2] = 1; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); int *data = new int(42); fprintf(stderr, "ptr1=%p\n", data); fprintf(stderr, "ptr2=%p\n", (char*)data + 2); diff --git a/compiler-rt/test/tsan/mutexset1.cc b/compiler-rt/test/tsan/mutexset1.cc index 72964edfb1e7..407cfe5bd9f1 100644 --- a/compiler-rt/test/tsan/mutexset1.cc +++ b/compiler-rt/test/tsan/mutexset1.cc @@ -1,13 +1,11 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t mtx; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(&mtx); Global++; pthread_mutex_unlock(&mtx); @@ -16,10 +14,12 @@ void *Thread1(void *x) { void *Thread2(void *x) { Global--; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T1 // CHECK: (mutexes: write [[M1:M[0-9]+]]): diff --git a/compiler-rt/test/tsan/mutexset2.cc b/compiler-rt/test/tsan/mutexset2.cc index 01a5f5df6e94..2a3e5bb95e87 100644 --- a/compiler-rt/test/tsan/mutexset2.cc +++ b/compiler-rt/test/tsan/mutexset2.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t mtx; @@ -10,16 +8,18 @@ void *Thread1(void *x) { pthread_mutex_lock(&mtx); Global++; pthread_mutex_unlock(&mtx); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); Global--; return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T2: // CHECK: Previous write of size 4 at {{.*}} by thread T1 diff --git a/compiler-rt/test/tsan/mutexset3.cc b/compiler-rt/test/tsan/mutexset3.cc index e14bb1111e32..ce64cf86e37c 100644 --- a/compiler-rt/test/tsan/mutexset3.cc +++ b/compiler-rt/test/tsan/mutexset3.cc @@ -1,14 +1,12 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t mtx1; pthread_mutex_t mtx2; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(&mtx1); pthread_mutex_lock(&mtx2); Global++; @@ -19,10 +17,12 @@ void *Thread1(void *x) { void *Thread2(void *x) { Global--; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T1 // CHECK: (mutexes: write [[M1:M[0-9]+]], write [[M2:M[0-9]+]]): diff --git a/compiler-rt/test/tsan/mutexset4.cc b/compiler-rt/test/tsan/mutexset4.cc index db860e005d67..b961efd2136c 100644 --- a/compiler-rt/test/tsan/mutexset4.cc +++ b/compiler-rt/test/tsan/mutexset4.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t mtx1; @@ -13,16 +11,18 @@ void *Thread1(void *x) { Global++; pthread_mutex_unlock(&mtx2); pthread_mutex_unlock(&mtx1); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); Global--; return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T2: // CHECK: Previous write of size 4 at {{.*}} by thread T1 diff --git a/compiler-rt/test/tsan/mutexset5.cc b/compiler-rt/test/tsan/mutexset5.cc index e1cc2fcacf62..8ef9af0ced52 100644 --- a/compiler-rt/test/tsan/mutexset5.cc +++ b/compiler-rt/test/tsan/mutexset5.cc @@ -1,14 +1,12 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t mtx1; pthread_mutex_t mtx2; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(&mtx1); Global++; pthread_mutex_unlock(&mtx1); @@ -19,10 +17,12 @@ void *Thread2(void *x) { pthread_mutex_lock(&mtx2); Global--; pthread_mutex_unlock(&mtx2); + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T1 // CHECK: (mutexes: write [[M1:M[0-9]+]]): diff --git a/compiler-rt/test/tsan/mutexset6.cc b/compiler-rt/test/tsan/mutexset6.cc index 07dcc0a7394d..f4251db6970e 100644 --- a/compiler-rt/test/tsan/mutexset6.cc +++ b/compiler-rt/test/tsan/mutexset6.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t mtx1; @@ -9,7 +7,7 @@ pthread_spinlock_t mtx2; pthread_rwlock_t mtx3; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(&mtx1); Global++; pthread_mutex_unlock(&mtx1); @@ -24,10 +22,12 @@ void *Thread2(void *x) { Global--; pthread_spin_unlock(&mtx2); pthread_rwlock_unlock(&mtx3); + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T1 // CHECK: (mutexes: write [[M1:M[0-9]+]]): diff --git a/compiler-rt/test/tsan/mutexset7.cc b/compiler-rt/test/tsan/mutexset7.cc index 12174844c799..d3a221d1b421 100644 --- a/compiler-rt/test/tsan/mutexset7.cc +++ b/compiler-rt/test/tsan/mutexset7.cc @@ -1,13 +1,11 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; __thread int huge[1024*1024]; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); Global++; return NULL; } @@ -20,10 +18,12 @@ void *Thread2(void *x) { pthread_mutex_unlock(mtx); pthread_mutex_destroy(mtx); delete mtx; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/mutexset8.cc b/compiler-rt/test/tsan/mutexset8.cc index 3e1ab8c5a744..40d5d043dedd 100644 --- a/compiler-rt/test/tsan/mutexset8.cc +++ b/compiler-rt/test/tsan/mutexset8.cc @@ -1,13 +1,11 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; pthread_mutex_t *mtx; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(mtx); Global++; pthread_mutex_unlock(mtx); @@ -16,10 +14,12 @@ void *Thread1(void *x) { void *Thread2(void *x) { Global--; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T1 // CHECK: (mutexes: write [[M1:M[0-9]+]]): diff --git a/compiler-rt/test/tsan/process_sleep.h b/compiler-rt/test/tsan/process_sleep.h deleted file mode 100644 index 5938a42bf8b2..000000000000 --- a/compiler-rt/test/tsan/process_sleep.h +++ /dev/null @@ -1,7 +0,0 @@ -#include - -static void process_sleep(int sec) { - clock_t beg = clock(); - while((clock() - beg) / CLOCKS_PER_SEC < sec) - usleep(100); -} diff --git a/compiler-rt/test/tsan/pthread_atfork_deadlock.c b/compiler-rt/test/tsan/pthread_atfork_deadlock.c index 0f33b9022e5f..4aeec82b6850 100644 --- a/compiler-rt/test/tsan/pthread_atfork_deadlock.c +++ b/compiler-rt/test/tsan/pthread_atfork_deadlock.c @@ -4,14 +4,12 @@ // When the data race was reported, pthread_atfork() handler used to be // executed which caused another race report in the same thread, which resulted // in a deadlock. -#include -#include -#include +#include "test.h" int glob = 0; void *worker(void *unused) { - sleep(1); + barrier_wait(&barrier); glob++; return NULL; } @@ -22,10 +20,12 @@ void atfork() { } int main() { + barrier_init(&barrier, 2); pthread_atfork(atfork, NULL, NULL); pthread_t t; pthread_create(&t, NULL, worker, NULL); glob++; + barrier_wait(&barrier); pthread_join(t, NULL); // CHECK: ThreadSanitizer: data race // CHECK-NOT: ATFORK diff --git a/compiler-rt/test/tsan/race_on_barrier.c b/compiler-rt/test/tsan/race_on_barrier.c index 99b18fe4d8e6..cf8a4cb99274 100644 --- a/compiler-rt/test/tsan/race_on_barrier.c +++ b/compiler-rt/test/tsan/race_on_barrier.c @@ -1,25 +1,24 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" pthread_barrier_t B; int Global; void *Thread1(void *x) { pthread_barrier_init(&B, 0, 2); + barrier_wait(&barrier); pthread_barrier_wait(&B); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_barrier_wait(&B); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, NULL, Thread1, NULL); Thread2(0); diff --git a/compiler-rt/test/tsan/race_on_mutex.c b/compiler-rt/test/tsan/race_on_mutex.c index b4adeeb4df72..7bd461bf3731 100644 --- a/compiler-rt/test/tsan/race_on_mutex.c +++ b/compiler-rt/test/tsan/race_on_mutex.c @@ -1,8 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" pthread_mutex_t Mtx; int Global; @@ -12,11 +9,12 @@ void *Thread1(void *x) { pthread_mutex_lock(&Mtx); Global = 42; pthread_mutex_unlock(&Mtx); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); pthread_mutex_lock(&Mtx); Global = 43; pthread_mutex_unlock(&Mtx); @@ -24,6 +22,7 @@ void *Thread2(void *x) { } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); @@ -36,7 +35,7 @@ int main() { // CHECK: WARNING: ThreadSanitizer: data race // CHECK-NEXT: Atomic read of size 1 at {{.*}} by thread T2: // CHECK-NEXT: #0 pthread_mutex_lock -// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:20{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #1 Thread2{{.*}} {{.*}}race_on_mutex.c:18{{(:3)?}} ({{.*}}) // CHECK: Previous write of size 1 at {{.*}} by thread T1: // CHECK-NEXT: #0 pthread_mutex_init {{.*}} ({{.*}}) -// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:11{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #1 Thread1{{.*}} {{.*}}race_on_mutex.c:8{{(:3)?}} ({{.*}}) diff --git a/compiler-rt/test/tsan/race_on_mutex2.c b/compiler-rt/test/tsan/race_on_mutex2.c index 1796d0c6480b..6ee5438f566e 100644 --- a/compiler-rt/test/tsan/race_on_mutex2.c +++ b/compiler-rt/test/tsan/race_on_mutex2.c @@ -1,21 +1,20 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include +#include "test.h" void *Thread(void *x) { pthread_mutex_lock((pthread_mutex_t*)x); pthread_mutex_unlock((pthread_mutex_t*)x); + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); pthread_mutex_t Mtx; pthread_mutex_init(&Mtx, 0); pthread_t t; pthread_create(&t, 0, Thread, &Mtx); - sleep(1); + barrier_wait(&barrier); pthread_mutex_destroy(&Mtx); pthread_join(t, 0); return 0; diff --git a/compiler-rt/test/tsan/race_on_puts.cc b/compiler-rt/test/tsan/race_on_puts.cc index 1f2b4db836ed..f2541823bf0c 100644 --- a/compiler-rt/test/tsan/race_on_puts.cc +++ b/compiler-rt/test/tsan/race_on_puts.cc @@ -1,21 +1,22 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" char s[] = "abracadabra"; void *Thread0(void *p) { puts(s); + barrier_wait(&barrier); return 0; } void *Thread1(void *p) { + barrier_wait(&barrier); s[3] = 'z'; return 0; } int main() { + barrier_init(&barrier, 2); pthread_t th[2]; pthread_create(&th[0], 0, Thread0, 0); pthread_create(&th[1], 0, Thread1, 0); diff --git a/compiler-rt/test/tsan/race_on_read.cc b/compiler-rt/test/tsan/race_on_read.cc index 1ec0522b9035..d388bbacde5b 100644 --- a/compiler-rt/test/tsan/race_on_read.cc +++ b/compiler-rt/test/tsan/race_on_read.cc @@ -1,31 +1,35 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include #include #include -#include #include int fd; char buf; -void *Thread(void *x) { - sleep(1); +void *Thread1(void *x) { + barrier_wait(&barrier); read(fd, &buf, 1); return NULL; } +void *Thread2(void *x) { + read(fd, &buf, 1); + barrier_wait(&barrier); + return NULL; +} + int main() { + barrier_init(&barrier, 2); fd = open("/dev/random", O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open /dev/random (%d)\n", errno); return 1; } pthread_t t[2]; - pthread_create(&t[0], NULL, Thread, NULL); - pthread_create(&t[1], NULL, Thread, NULL); + pthread_create(&t[0], NULL, Thread1, NULL); + pthread_create(&t[1], NULL, Thread2, NULL); pthread_join(t[0], NULL); pthread_join(t[1], NULL); close(fd); diff --git a/compiler-rt/test/tsan/race_on_speculative_load.cc b/compiler-rt/test/tsan/race_on_speculative_load.cc index f816db9e8853..b50b69677d4b 100644 --- a/compiler-rt/test/tsan/race_on_speculative_load.cc +++ b/compiler-rt/test/tsan/race_on_speculative_load.cc @@ -1,9 +1,8 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %run %t | FileCheck %s // Regtest for https://code.google.com/p/thread-sanitizer/issues/detail?id=40 // This is a correct program and tsan should not report a race. -#include -#include -#include +#include "test.h" + int g; __attribute__((noinline)) int foo(int cond) { @@ -11,17 +10,21 @@ int foo(int cond) { return g; return 0; } + void *Thread1(void *p) { + barrier_wait(&barrier); long res = foo((long)p); - sleep(1); return (void*) res; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread1, 0); g = 1; + barrier_wait(&barrier); pthread_join(t, 0); printf("PASS\n"); + // CHECK-NOT: ThreadSanitizer: data race // CHECK: PASS } diff --git a/compiler-rt/test/tsan/race_on_write.cc b/compiler-rt/test/tsan/race_on_write.cc index 484bbb7ae022..147591a39b9b 100644 --- a/compiler-rt/test/tsan/race_on_write.cc +++ b/compiler-rt/test/tsan/race_on_write.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include #include #include @@ -11,7 +9,7 @@ char buf; void *Thread1(void *x) { buf = 1; - sleep(1); + barrier_wait(&barrier); return NULL; } @@ -21,11 +19,12 @@ void *Thread2(void *x) { } int main() { + barrier_init(&barrier, 2); fd = open("/dev/null", O_WRONLY); if (fd < 0) return 1; pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); - sleep(1); + barrier_wait(&barrier); pthread_create(&t[1], NULL, Thread2, NULL); pthread_join(t[0], NULL); pthread_join(t[1], NULL); diff --git a/compiler-rt/test/tsan/race_with_finished_thread.cc b/compiler-rt/test/tsan/race_with_finished_thread.cc index d28760093c42..755a7bd982bb 100644 --- a/compiler-rt/test/tsan/race_with_finished_thread.cc +++ b/compiler-rt/test/tsan/race_with_finished_thread.cc @@ -1,9 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include -#include -#include +#include "test.h" // Ensure that we can restore a stack of a finished thread. @@ -15,16 +11,19 @@ void __attribute__((noinline)) foobar(int *p) { void *Thread1(void *x) { foobar(&g_data); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); + sleep(1); // let the thread finish and exit g_data = 43; return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/restore_stack.cc b/compiler-rt/test/tsan/restore_stack.cc index 5dbc279a485f..39c11011ca49 100644 --- a/compiler-rt/test/tsan/restore_stack.cc +++ b/compiler-rt/test/tsan/restore_stack.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; volatile int x; @@ -17,18 +15,21 @@ void *Thread(void *a) { __atomic_store_n(&x, 1, __ATOMIC_RELEASE); foo(); data[0]++; + if (a != 0) + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); for (int i = 0; i < 50; i++) { pthread_t t; pthread_create(&t, 0, Thread, 0); pthread_join(t, 0); } pthread_t t; - pthread_create(&t, 0, Thread, 0); - sleep(5); + pthread_create(&t, 0, Thread, (void*)1); + barrier_wait(&barrier); for (int i = 0; i < kSize; i++) data[i]++; pthread_join(t, 0); diff --git a/compiler-rt/test/tsan/signal_errno.cc b/compiler-rt/test/tsan/signal_errno.cc index 1fa20f36810b..8305e84930f3 100644 --- a/compiler-rt/test/tsan/signal_errno.cc +++ b/compiler-rt/test/tsan/signal_errno.cc @@ -1,10 +1,7 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include #include -#include #include pthread_t mainth; @@ -16,12 +13,13 @@ static void MyHandler(int, siginfo_t *s, void *c) { } static void* sendsignal(void *p) { - sleep(1); + barrier_wait(&barrier); pthread_kill(mainth, SIGPROF); return 0; } static __attribute__((noinline)) void loop() { + barrier_wait(&barrier); while (done == 0) { volatile char *p = (char*)malloc(1); p[0] = 0; @@ -31,6 +29,7 @@ static __attribute__((noinline)) void loop() { } int main() { + barrier_init(&barrier, 2); mainth = pthread_self(); struct sigaction act = {}; act.sa_sigaction = &MyHandler; diff --git a/compiler-rt/test/tsan/signal_malloc.cc b/compiler-rt/test/tsan/signal_malloc.cc index 06932fba42db..1dccb139c415 100644 --- a/compiler-rt/test/tsan/signal_malloc.cc +++ b/compiler-rt/test/tsan/signal_malloc.cc @@ -1,9 +1,7 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" #include #include -#include static void handler(int, siginfo_t*, void*) { // CHECK: WARNING: ThreadSanitizer: signal-unsafe call inside of a signal @@ -20,7 +18,7 @@ int main() { act.sa_sigaction = &handler; sigaction(SIGPROF, &act, 0); kill(getpid(), SIGPROF); - sleep(1); + sleep(1); // let the signal handler run return 0; } diff --git a/compiler-rt/test/tsan/signal_recursive.cc b/compiler-rt/test/tsan/signal_recursive.cc index bbb6807586a5..825338de9fba 100644 --- a/compiler-rt/test/tsan/signal_recursive.cc +++ b/compiler-rt/test/tsan/signal_recursive.cc @@ -3,19 +3,13 @@ // Test case for recursive signal handlers, adopted from: // https://code.google.com/p/thread-sanitizer/issues/detail?id=71 -#include +#include "test.h" #include #include -#include #include -#include -#include - -#include "process_sleep.h" static const int kSigSuspend = SIGUSR1; static const int kSigRestart = SIGUSR2; -static sigset_t g_suspend_handler_mask; static sem_t g_thread_suspend_ack_sem; @@ -27,7 +21,7 @@ static void SaveRegistersInStack() { // Mono walks thread stacks to detect unreferenced objects. // If last object reference is kept in register the object will be collected // This is why threads can't be suspended with something like pthread_suspend -}; +} static void fail(const char *what) { fprintf(stderr, "FAILED: %s (errno=%d)\n", what, errno); @@ -37,15 +31,19 @@ static void fail(const char *what) { static void SuspendHandler(int sig) { int old_errno = errno; SaveRegistersInStack(); + + // Enable kSigRestart handling, tsan disables signals around signal handlers. + sigset_t sigset; + sigemptyset(&sigset); + pthread_sigmask(SIG_SETMASK, &sigset, 0); + // Acknowledge that thread is saved and suspended if (sem_post(&g_thread_suspend_ack_sem) != 0) fail("sem_post failed"); - do { - g_busy_thread_received_restart = false; - if (sigsuspend(&g_suspend_handler_mask) != -1 || errno != EINTR) - fail("sigsuspend failed"); - } while (!g_busy_thread_received_restart); + // Wait for wakeup signal. + while (!g_busy_thread_received_restart) + usleep(100); // wait for kSigRestart signal // Acknowledge that thread restarted if (sem_post(&g_thread_suspend_ack_sem) != 0) @@ -83,21 +81,15 @@ static void StartWorld(pthread_t thread) { static void CollectGarbage(pthread_t thread) { StopWorld(thread); // Walk stacks - process_sleep(1); StartWorld(thread); } static void Init() { - if (sigfillset(&g_suspend_handler_mask) != 0) - fail("sigfillset failed"); - if (sigdelset(&g_suspend_handler_mask, kSigRestart) != 0) - fail("sigdelset failed"); if (sem_init(&g_thread_suspend_ack_sem, 0, 0) != 0) fail("sem_init failed"); struct sigaction act = {}; act.sa_flags = SA_RESTART; - sigfillset(&act.sa_mask); act.sa_handler = &SuspendHandler; if (sigaction(kSigSuspend, &act, NULL) != 0) fail("sigaction failed"); diff --git a/compiler-rt/test/tsan/signal_sync.cc b/compiler-rt/test/tsan/signal_sync.cc index 15387b754dfb..6ff19d3bd120 100644 --- a/compiler-rt/test/tsan/signal_sync.cc +++ b/compiler-rt/test/tsan/signal_sync.cc @@ -1,11 +1,8 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" #include #include #include -#include #include volatile int X; @@ -18,7 +15,7 @@ static void handler(int sig) { static void* thr(void *p) { for (int i = 0; i != 1000; i++) - usleep(1000); + usleep(1000); // process signals return 0; } diff --git a/compiler-rt/test/tsan/signal_write.cc b/compiler-rt/test/tsan/signal_write.cc index 626d87a7acc7..edb3d2356bd2 100644 --- a/compiler-rt/test/tsan/signal_write.cc +++ b/compiler-rt/test/tsan/signal_write.cc @@ -16,7 +16,7 @@ int main() { act.sa_sigaction = &handler; sigaction(SIGPROF, &act, 0); kill(getpid(), SIGPROF); - sleep(1); + sleep(1); // let the signal handler run, can't use barrier in sig handler fprintf(stderr, "DONE\n"); return 0; } diff --git a/compiler-rt/test/tsan/simple_race.c b/compiler-rt/test/tsan/simple_race.c index 7b60c5ec249e..b4234acd7f89 100644 --- a/compiler-rt/test/tsan/simple_race.c +++ b/compiler-rt/test/tsan/simple_race.c @@ -1,22 +1,22 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); Global = 42; return NULL; } void *Thread2(void *x) { Global = 43; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/simple_race.cc b/compiler-rt/test/tsan/simple_race.cc index f711bb5d114d..612ce2dc0c4f 100644 --- a/compiler-rt/test/tsan/simple_race.cc +++ b/compiler-rt/test/tsan/simple_race.cc @@ -1,22 +1,22 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); Global++; return NULL; } void *Thread2(void *x) { Global--; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/simple_stack.c b/compiler-rt/test/tsan/simple_stack.c index 62840c27dc14..fd8f8ac49589 100644 --- a/compiler-rt/test/tsan/simple_stack.c +++ b/compiler-rt/test/tsan/simple_stack.c @@ -1,7 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" int Global; @@ -24,13 +22,14 @@ void __attribute__((noinline)) bar2() { } void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); bar1(); return NULL; } void *Thread2(void *x) { bar2(); + barrier_wait(&barrier); return NULL; } @@ -39,6 +38,7 @@ void StartThread(pthread_t *t, void *(*f)(void*)) { } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; StartThread(&t[0], Thread1); StartThread(&t[1], Thread2); @@ -49,18 +49,18 @@ int main() { // CHECK: WARNING: ThreadSanitizer: data race // CHECK-NEXT: Write of size 4 at {{.*}} by thread T1: -// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:9{{(:3)?}} ({{.*}}) -// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:14{{(:3)?}} ({{.*}}) -// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:28{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack.c:7{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack.c:12{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack.c:26{{(:3)?}} ({{.*}}) // CHECK: Previous read of size 4 at {{.*}} by thread T2: -// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:18{{(:20)?}} ({{.*}}) -// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:23{{(:3)?}} ({{.*}}) -// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:33{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:16{{(:20)?}} ({{.*}}) +// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:21{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:31{{(:3)?}} ({{.*}}) // CHECK: Thread T1 (tid={{.*}}, running) created by main thread at: // CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}}) -// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:37{{(:3)?}} ({{.*}}) // CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:43{{(:3)?}} ({{.*}}) // CHECK: Thread T2 ({{.*}}) created by main thread at: // CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}}) -// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}}) +// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:37{{(:3)?}} ({{.*}}) // CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:44{{(:3)?}} ({{.*}}) diff --git a/compiler-rt/test/tsan/simple_stack2.cc b/compiler-rt/test/tsan/simple_stack2.cc index 7044b82a1048..719efdf053b4 100644 --- a/compiler-rt/test/tsan/simple_stack2.cc +++ b/compiler-rt/test/tsan/simple_stack2.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %T/simple_stack2.cc.exe && %deflake %run %T/simple_stack2.cc.exe | FileCheck %s -#include -#include -#include +#include "test.h" int Global; @@ -30,24 +28,26 @@ void __attribute__((noinline)) bar2() { } void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); bar1(); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, NULL, Thread1, NULL); bar2(); + barrier_wait(&barrier); pthread_join(t, NULL); } // CHECK: WARNING: ThreadSanitizer: data race // CHECK-NEXT: Write of size 4 at {{.*}} by thread T1: -// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:9{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) -// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:16{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) -// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:34{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) +// CHECK-NEXT: #0 foo1{{.*}} {{.*}}simple_stack2.cc:7{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) +// CHECK-NEXT: #1 bar1{{.*}} {{.*}}simple_stack2.cc:14{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) +// CHECK-NEXT: #2 Thread1{{.*}} {{.*}}simple_stack2.cc:32{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) // CHECK: Previous read of size 4 at {{.*}} by main thread: -// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:20{{(:22)?}} (simple_stack2.cc.exe+{{.*}}) -// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:29{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) -// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:41{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) +// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack2.cc:18{{(:22)?}} (simple_stack2.cc.exe+{{.*}}) +// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack2.cc:27{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) +// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack2.cc:40{{(:3)?}} (simple_stack2.cc.exe+{{.*}}) diff --git a/compiler-rt/test/tsan/sleep_sync.cc b/compiler-rt/test/tsan/sleep_sync.cc index c7614e16bf3e..b2c6a1220f42 100644 --- a/compiler-rt/test/tsan/sleep_sync.cc +++ b/compiler-rt/test/tsan/sleep_sync.cc @@ -1,23 +1,25 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" int X = 0; void MySleep() { - sleep(1); + sleep(1); // the sleep that must appear in the report } void *Thread(void *p) { + barrier_wait(&barrier); MySleep(); // Assume the main thread has done the write. X = 42; return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); X = 43; + barrier_wait(&barrier); pthread_join(t, 0); return 0; } diff --git a/compiler-rt/test/tsan/sleep_sync2.cc b/compiler-rt/test/tsan/sleep_sync2.cc index 4e616992ecc9..a1a7a3accb48 100644 --- a/compiler-rt/test/tsan/sleep_sync2.cc +++ b/compiler-rt/test/tsan/sleep_sync2.cc @@ -1,18 +1,20 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" int X = 0; void *Thread(void *p) { X = 42; + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; - sleep(1); + sleep(1); // must not appear in the report pthread_create(&t, 0, Thread, 0); + barrier_wait(&barrier); X = 43; pthread_join(t, 0); return 0; diff --git a/compiler-rt/test/tsan/stack_race.cc b/compiler-rt/test/tsan/stack_race.cc index 2e02f46a281f..1ada2953547b 100644 --- a/compiler-rt/test/tsan/stack_race.cc +++ b/compiler-rt/test/tsan/stack_race.cc @@ -1,19 +1,19 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" void *Thread(void *a) { - sleep(1); + barrier_wait(&barrier); *(int*)a = 43; return 0; } int main() { + barrier_init(&barrier, 2); int Var = 42; pthread_t t; pthread_create(&t, 0, Thread, &Var); Var = 43; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/stack_race2.cc b/compiler-rt/test/tsan/stack_race2.cc index 818db367bab6..00e31fb96b08 100644 --- a/compiler-rt/test/tsan/stack_race2.cc +++ b/compiler-rt/test/tsan/stack_race2.cc @@ -1,10 +1,8 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" void *Thread2(void *a) { - sleep(1); + barrier_wait(&barrier); *(int*)a = 43; return 0; } @@ -14,11 +12,13 @@ void *Thread(void *a) { pthread_t t; pthread_create(&t, 0, Thread2, &Var); Var = 42; + barrier_wait(&barrier); pthread_join(t, 0); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); pthread_join(t, 0); diff --git a/compiler-rt/test/tsan/stack_sync_reuse.cc b/compiler-rt/test/tsan/stack_sync_reuse.cc index b1d5619df271..5ea9e84b085a 100644 --- a/compiler-rt/test/tsan/stack_sync_reuse.cc +++ b/compiler-rt/test/tsan/stack_sync_reuse.cc @@ -1,8 +1,5 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include -#include +#include "test.h" // Test case https://code.google.com/p/thread-sanitizer/issues/detail?id=87 // Tsan sees false HB edge on address pointed to by syncp variable. @@ -26,7 +23,7 @@ long sink; void *Thread(void *x) { while (__atomic_load_n(&syncp, __ATOMIC_ACQUIRE) == 0) - usleep(1000); + usleep(1000); // spin wait global = 42; __atomic_store_n(syncp, 1, __ATOMIC_RELEASE); __atomic_store_n(&syncp, 0, __ATOMIC_RELAXED); @@ -39,7 +36,7 @@ void __attribute__((noinline)) foobar() { __atomic_store_n(&s, 0, __ATOMIC_RELAXED); __atomic_store_n(&syncp, &s, __ATOMIC_RELEASE); while (__atomic_load_n(&syncp, __ATOMIC_RELAXED) != 0) - usleep(1000); + usleep(1000); // spin wait } void __attribute__((noinline)) barfoo() { diff --git a/compiler-rt/test/tsan/suppress_same_address.cc b/compiler-rt/test/tsan/suppress_same_address.cc index df19da1cc7ae..3ec13ee8302f 100644 --- a/compiler-rt/test/tsan/suppress_same_address.cc +++ b/compiler-rt/test/tsan/suppress_same_address.cc @@ -1,11 +1,10 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" volatile int X; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); X = 42; X = 66; X = 78; @@ -16,10 +15,12 @@ void *Thread2(void *x) { X = 11; X = 99; X = 73; + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread1, 0); Thread2(0); diff --git a/compiler-rt/test/tsan/suppressions_race.cc b/compiler-rt/test/tsan/suppressions_race.cc index 4a35c276e067..45c30481f0cd 100644 --- a/compiler-rt/test/tsan/suppressions_race.cc +++ b/compiler-rt/test/tsan/suppressions_race.cc @@ -1,22 +1,22 @@ // RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); Global = 42; return NULL; } void *Thread2(void *x) { Global = 43; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/suppressions_race2.cc b/compiler-rt/test/tsan/suppressions_race2.cc index f9827796f965..24ecd8ef119f 100644 --- a/compiler-rt/test/tsan/suppressions_race2.cc +++ b/compiler-rt/test/tsan/suppressions_race2.cc @@ -1,22 +1,22 @@ // RUN: %clang_tsan -O1 %s -o %t && TSAN_OPTIONS="$TSAN_OPTIONS suppressions='%s.supp'" %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { Global = 42; + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); Global = 43; return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/test.h b/compiler-rt/test/tsan/test.h new file mode 100644 index 000000000000..4496e56cda87 --- /dev/null +++ b/compiler-rt/test/tsan/test.h @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +// TSan-invisible barrier. +// Tests use it to establish necessary execution order in a way that does not +// interfere with tsan (does not establish synchronization between threads). +__typeof(pthread_barrier_wait) *barrier_wait; + +void barrier_init(pthread_barrier_t *barrier, unsigned count) { + if (barrier_wait == 0) { + void *h = dlopen("libpthread.so.0", RTLD_LAZY); + if (h == 0) { + fprintf(stderr, "failed to dlopen libpthread.so.0, exiting\n"); + exit(1); + } + barrier_wait = (__typeof(barrier_wait))dlsym(h, "pthread_barrier_wait"); + if (barrier_wait == 0) { + fprintf(stderr, "failed to resolve pthread_barrier_wait, exiting\n"); + exit(1); + } + } + pthread_barrier_init(barrier, 0, count); +} + +// Default instance of the barrier, but a test can declare more manually. +pthread_barrier_t barrier; + diff --git a/compiler-rt/test/tsan/thread_detach.c b/compiler-rt/test/tsan/thread_detach.c index 32cf641b141a..802d8ded0fad 100644 --- a/compiler-rt/test/tsan/thread_detach.c +++ b/compiler-rt/test/tsan/thread_detach.c @@ -1,16 +1,16 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" void *Thread(void *x) { + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); pthread_detach(t); printf("PASS\n"); return 0; diff --git a/compiler-rt/test/tsan/thread_leak3.c b/compiler-rt/test/tsan/thread_leak3.c index f4db484219a0..c09fb714d7ab 100644 --- a/compiler-rt/test/tsan/thread_leak3.c +++ b/compiler-rt/test/tsan/thread_leak3.c @@ -1,15 +1,17 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" void *Thread(void *x) { + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); - sleep(1); + barrier_wait(&barrier); + sleep(1); // wait for the thread to finish and exit return 0; } diff --git a/compiler-rt/test/tsan/thread_leak4.c b/compiler-rt/test/tsan/thread_leak4.c index 0d3b8307000a..1ebca58871ac 100644 --- a/compiler-rt/test/tsan/thread_leak4.c +++ b/compiler-rt/test/tsan/thread_leak4.c @@ -1,18 +1,18 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include -#include +#include "test.h" void *Thread(void *x) { - sleep(10); + sleep(100); // leave the thread "running" return 0; } int main() { pthread_t t; pthread_create(&t, 0, Thread, 0); - printf("OK\n"); + printf("DONE\n"); return 0; } +// CHECK: DONE // CHECK-NOT: WARNING: ThreadSanitizer: thread leak + diff --git a/compiler-rt/test/tsan/thread_leak5.c b/compiler-rt/test/tsan/thread_leak5.c index ca244a9f24e1..acdbd1d38a9b 100644 --- a/compiler-rt/test/tsan/thread_leak5.c +++ b/compiler-rt/test/tsan/thread_leak5.c @@ -1,18 +1,20 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" void *Thread(void *x) { + barrier_wait(&barrier); return 0; } int main() { volatile int N = 5; // prevent loop unrolling + barrier_init(&barrier, N + 1); for (int i = 0; i < N; i++) { pthread_t t; pthread_create(&t, 0, Thread, 0); } - sleep(1); + barrier_wait(&barrier); + sleep(1); // wait for the threads to finish and exit return 0; } diff --git a/compiler-rt/test/tsan/thread_name.cc b/compiler-rt/test/tsan/thread_name.cc index a790c668c084..80d30b82d8b5 100644 --- a/compiler-rt/test/tsan/thread_name.cc +++ b/compiler-rt/test/tsan/thread_name.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #if defined(__linux__) #define USE_PTHREAD_SETNAME_NP __GLIBC_PREREQ(2, 12) @@ -18,7 +16,7 @@ extern "C" void AnnotateThreadName(const char *f, int l, const char *name); int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); AnnotateThreadName(__FILE__, __LINE__, "Thread1"); Global++; return NULL; @@ -31,10 +29,12 @@ void *Thread2(void *x) { AnnotateThreadName(__FILE__, __LINE__, "Thread2"); #endif Global--; + barrier_wait(&barrier); return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/thread_name2.cc b/compiler-rt/test/tsan/thread_name2.cc index 6a3dafe9c763..a44f4b9d3247 100644 --- a/compiler-rt/test/tsan/thread_name2.cc +++ b/compiler-rt/test/tsan/thread_name2.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #if defined(__FreeBSD__) #include @@ -11,7 +9,7 @@ int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); Global++; return 0; } @@ -19,14 +17,17 @@ void *Thread1(void *x) { void *Thread2(void *x) { pthread_setname_np(pthread_self(), "foobar2"); Global--; + barrier_wait(&barrier); return 0; } int main() { + barrier_init(&barrier, 3); pthread_t t[2]; pthread_create(&t[0], 0, Thread1, 0); pthread_create(&t[1], 0, Thread2, 0); pthread_setname_np(t[0], "foobar1"); + barrier_wait(&barrier); pthread_join(t[0], NULL); pthread_join(t[1], NULL); } diff --git a/compiler-rt/test/tsan/tiny_race.c b/compiler-rt/test/tsan/tiny_race.c index c10eab15c5a9..b6937febd117 100644 --- a/compiler-rt/test/tsan/tiny_race.c +++ b/compiler-rt/test/tsan/tiny_race.c @@ -1,19 +1,20 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" int Global; void *Thread1(void *x) { - sleep(1); + barrier_wait(&barrier); Global = 42; return x; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread1, 0); Global = 43; + barrier_wait(&barrier); pthread_join(t, 0); return Global; } diff --git a/compiler-rt/test/tsan/tls_race.cc b/compiler-rt/test/tsan/tls_race.cc index 18589347e806..5e8172276708 100644 --- a/compiler-rt/test/tsan/tls_race.cc +++ b/compiler-rt/test/tsan/tls_race.cc @@ -1,19 +1,19 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" void *Thread(void *a) { - sleep(1); + barrier_wait(&barrier); *(int*)a = 43; return 0; } int main() { + barrier_init(&barrier, 2); static __thread int Var = 42; pthread_t t; pthread_create(&t, 0, Thread, &Var); Var = 43; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/tls_race2.cc b/compiler-rt/test/tsan/tls_race2.cc index 0ca629ada5cc..d0f7b03e09a1 100644 --- a/compiler-rt/test/tsan/tls_race2.cc +++ b/compiler-rt/test/tsan/tls_race2.cc @@ -1,10 +1,8 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" void *Thread2(void *a) { - sleep(1); + barrier_wait(&barrier); *(int*)a = 43; return 0; } @@ -14,11 +12,13 @@ void *Thread(void *a) { pthread_t t; pthread_create(&t, 0, Thread2, &Var); Var = 42; + barrier_wait(&barrier); pthread_join(t, 0); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t t; pthread_create(&t, 0, Thread, 0); pthread_join(t, 0); diff --git a/compiler-rt/test/tsan/unaligned_race.cc b/compiler-rt/test/tsan/unaligned_race.cc index 6e9b5a33f0da..030642a4ddfb 100644 --- a/compiler-rt/test/tsan/unaligned_race.cc +++ b/compiler-rt/test/tsan/unaligned_race.cc @@ -1,9 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" #include -#include #define NOINLINE __attribute__((noinline)) @@ -123,15 +120,17 @@ NOINLINE void Test(bool main) { void *Thread(void *p) { (void)p; - sleep(1); + barrier_wait(&barrier); Test(false); return 0; } int main() { + barrier_init(&barrier, 2); pthread_t th; pthread_create(&th, 0, Thread, 0); Test(true); + barrier_wait(&barrier); pthread_join(th, 0); } diff --git a/compiler-rt/test/tsan/vptr_harmful_race.cc b/compiler-rt/test/tsan/vptr_harmful_race.cc index 68e12e8e7e89..d15b3969ab81 100644 --- a/compiler-rt/test/tsan/vptr_harmful_race.cc +++ b/compiler-rt/test/tsan/vptr_harmful_race.cc @@ -1,8 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include +#include "test.h" #include -#include -#include struct A { A() { @@ -31,16 +29,18 @@ static A *obj = new B; void *Thread1(void *x) { obj->F(); obj->Done(); + barrier_wait(&barrier); return NULL; } void *Thread2(void *x) { - sleep(1); + barrier_wait(&barrier); delete obj; return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/vptr_harmful_race2.cc b/compiler-rt/test/tsan/vptr_harmful_race2.cc index aa53bbb90fcf..a56b74c09689 100644 --- a/compiler-rt/test/tsan/vptr_harmful_race2.cc +++ b/compiler-rt/test/tsan/vptr_harmful_race2.cc @@ -1,8 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include +#include "test.h" #include -#include -#include struct A { A() { @@ -29,18 +27,20 @@ struct B : A { static A *obj = new B; void *Thread1(void *x) { - sleep(1); obj->F(); + barrier_wait(&barrier); obj->Done(); return NULL; } void *Thread2(void *x) { + barrier_wait(&barrier); delete obj; return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/vptr_harmful_race3.cc b/compiler-rt/test/tsan/vptr_harmful_race3.cc index ac6ea94e51eb..3810a1068d64 100644 --- a/compiler-rt/test/tsan/vptr_harmful_race3.cc +++ b/compiler-rt/test/tsan/vptr_harmful_race3.cc @@ -1,8 +1,6 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include +#include "test.h" #include -#include -#include struct A { A() { @@ -30,18 +28,20 @@ static A *obj = new B; static void (A::*fn)() = &A::F; void *Thread1(void *x) { - sleep(1); (obj->*fn)(); + barrier_wait(&barrier); obj->Done(); return NULL; } void *Thread2(void *x) { + barrier_wait(&barrier); delete obj; return NULL; } int main() { + barrier_init(&barrier, 2); pthread_t t[2]; pthread_create(&t[0], NULL, Thread1, NULL); pthread_create(&t[1], NULL, Thread2, NULL); diff --git a/compiler-rt/test/tsan/vptr_harmful_race4.cc b/compiler-rt/test/tsan/vptr_harmful_race4.cc index 969c9d58a016..543514de8387 100644 --- a/compiler-rt/test/tsan/vptr_harmful_race4.cc +++ b/compiler-rt/test/tsan/vptr_harmful_race4.cc @@ -1,7 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include -#include +#include "test.h" struct A { virtual void F() { @@ -17,16 +15,18 @@ struct B : A { }; void *Thread(void *x) { - sleep(1); + barrier_wait(&barrier); ((A*)x)->F(); return 0; } int main() { + barrier_init(&barrier, 2); A *obj = new B; pthread_t t; pthread_create(&t, 0, Thread, obj); delete obj; + barrier_wait(&barrier); pthread_join(t, 0); } diff --git a/compiler-rt/test/tsan/write_in_reader_lock.cc b/compiler-rt/test/tsan/write_in_reader_lock.cc index 55882139b153..3f7cb3579f77 100644 --- a/compiler-rt/test/tsan/write_in_reader_lock.cc +++ b/compiler-rt/test/tsan/write_in_reader_lock.cc @@ -1,6 +1,5 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s -#include -#include +#include "test.h" pthread_rwlock_t rwlock; int GLOB; @@ -8,14 +7,15 @@ int GLOB; void *Thread1(void *p) { (void)p; pthread_rwlock_rdlock(&rwlock); + barrier_wait(&barrier); // Write under reader lock. - sleep(1); GLOB++; pthread_rwlock_unlock(&rwlock); return 0; } int main(int argc, char *argv[]) { + barrier_init(&barrier, 2); pthread_rwlock_init(&rwlock, NULL); pthread_rwlock_rdlock(&rwlock); pthread_t t; @@ -23,6 +23,7 @@ int main(int argc, char *argv[]) { volatile int x = GLOB; (void)x; pthread_rwlock_unlock(&rwlock); + barrier_wait(&barrier); pthread_join(t, 0); pthread_rwlock_destroy(&rwlock); return 0; @@ -30,6 +31,6 @@ int main(int argc, char *argv[]) { // CHECK: WARNING: ThreadSanitizer: data race // CHECK: Write of size 4 at {{.*}} by thread T1{{.*}}: -// CHECK: #0 Thread1(void*) {{.*}}write_in_reader_lock.cc:13 +// CHECK: #0 Thread1(void*) {{.*}}write_in_reader_lock.cc:12 // CHECK: Previous read of size 4 at {{.*}} by main thread{{.*}}: // CHECK: #0 main {{.*}}write_in_reader_lock.cc:23