summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/tsan/atomic_free.cc7
-rw-r--r--test/tsan/atomic_free2.cc7
-rw-r--r--test/tsan/atomic_norace.cc11
-rw-r--r--test/tsan/atomic_race.cc11
-rw-r--r--test/tsan/atomic_stack.cc7
-rw-r--r--test/tsan/benign_race.cc8
-rw-r--r--test/tsan/blacklist2.cc8
-rw-r--r--test/tsan/cond_cancel.c9
-rw-r--r--test/tsan/cond_race.cc11
-rw-r--r--test/tsan/deadlock_detector_stress_test.cc25
-rw-r--r--test/tsan/deep_stack1.cc16
-rw-r--r--test/tsan/fd_close_norace.cc8
-rw-r--r--test/tsan/fd_location.cc8
-rw-r--r--test/tsan/fd_pipe_race.cc8
-rw-r--r--test/tsan/fd_stdout_race.cc8
-rw-r--r--test/tsan/fork_deadlock.cc8
-rw-r--r--test/tsan/fork_multithreaded.cc14
-rw-r--r--test/tsan/free_race.c10
-rw-r--r--test/tsan/global_race.cc9
-rw-r--r--test/tsan/global_race2.cc9
-rw-r--r--test/tsan/global_race3.cc9
-rw-r--r--test/tsan/halt_on_error.cc8
-rw-r--r--test/tsan/ignore_free.cc9
-rw-r--r--test/tsan/ignore_malloc.cc7
-rw-r--r--test/tsan/ignore_race.cc8
-rw-r--r--test/tsan/inlined_memcpy_race.cc9
-rw-r--r--test/tsan/inlined_memcpy_race2.cc9
-rw-r--r--test/tsan/java.h5
-rw-r--r--test/tsan/java_finalizer.cc4
-rw-r--r--test/tsan/java_lock.cc5
-rw-r--r--test/tsan/java_lock_move.cc4
-rw-r--r--test/tsan/java_lock_rec.cc8
-rw-r--r--test/tsan/java_lock_rec_race.cc8
-rw-r--r--test/tsan/java_move_overlap.cc4
-rw-r--r--test/tsan/java_move_overlap_race.cc4
-rw-r--r--test/tsan/java_race_move.cc4
-rw-r--r--test/tsan/java_rwlock.cc5
-rw-r--r--test/tsan/java_volatile.cc4
-rw-r--r--test/tsan/load_shared_lib.cc30
-rw-r--r--test/tsan/malloc_stack.cc7
-rw-r--r--test/tsan/map32bit.cc9
-rw-r--r--test/tsan/memcpy_race.cc9
-rw-r--r--test/tsan/mop_with_offset.cc9
-rw-r--r--test/tsan/mop_with_offset2.cc9
-rw-r--r--test/tsan/mutexset1.cc8
-rw-r--r--test/tsan/mutexset2.cc8
-rw-r--r--test/tsan/mutexset3.cc8
-rw-r--r--test/tsan/mutexset4.cc8
-rw-r--r--test/tsan/mutexset5.cc8
-rw-r--r--test/tsan/mutexset6.cc8
-rw-r--r--test/tsan/mutexset7.cc8
-rw-r--r--test/tsan/mutexset8.cc8
-rw-r--r--test/tsan/process_sleep.h7
-rw-r--r--test/tsan/pthread_atfork_deadlock.c8
-rw-r--r--test/tsan/race_on_barrier.c9
-rw-r--r--test/tsan/race_on_mutex.c13
-rw-r--r--test/tsan/race_on_mutex2.c9
-rw-r--r--test/tsan/race_on_puts.cc7
-rw-r--r--test/tsan/race_on_read.cc20
-rw-r--r--test/tsan/race_on_speculative_load.cc11
-rw-r--r--test/tsan/race_on_write.cc9
-rw-r--r--test/tsan/race_with_finished_thread.cc11
-rw-r--r--test/tsan/restore_stack.cc11
-rw-r--r--test/tsan/signal_errno.cc9
-rw-r--r--test/tsan/signal_malloc.cc6
-rw-r--r--test/tsan/signal_recursive.cc30
-rw-r--r--test/tsan/signal_sync.cc7
-rw-r--r--test/tsan/signal_write.cc2
-rw-r--r--test/tsan/simple_race.c8
-rw-r--r--test/tsan/simple_race.cc8
-rw-r--r--test/tsan/simple_stack.c24
-rw-r--r--test/tsan/simple_stack2.cc20
-rw-r--r--test/tsan/sleep_sync.cc8
-rw-r--r--test/tsan/sleep_sync2.cc8
-rw-r--r--test/tsan/stack_race.cc8
-rw-r--r--test/tsan/stack_race2.cc8
-rw-r--r--test/tsan/stack_sync_reuse.cc9
-rw-r--r--test/tsan/suppress_same_address.cc7
-rw-r--r--test/tsan/suppressions_race.cc8
-rw-r--r--test/tsan/suppressions_race2.cc8
-rw-r--r--test/tsan/test.h31
-rw-r--r--test/tsan/thread_detach.c8
-rw-r--r--test/tsan/thread_leak3.c8
-rw-r--r--test/tsan/thread_leak4.c10
-rw-r--r--test/tsan/thread_leak5.c8
-rw-r--r--test/tsan/thread_name.cc8
-rw-r--r--test/tsan/thread_name2.cc9
-rw-r--r--test/tsan/tiny_race.c7
-rw-r--r--test/tsan/tls_race.cc8
-rw-r--r--test/tsan/tls_race2.cc8
-rw-r--r--test/tsan/unaligned_race.cc9
-rw-r--r--test/tsan/vptr_harmful_race.cc8
-rw-r--r--test/tsan/vptr_harmful_race2.cc8
-rw-r--r--test/tsan/vptr_harmful_race3.cc8
-rw-r--r--test/tsan/vptr_harmful_race4.cc8
-rw-r--r--test/tsan/write_in_reader_lock.cc9
96 files changed, 476 insertions, 425 deletions
diff --git a/test/tsan/atomic_free.cc b/test/tsan/atomic_free.cc
index 1dcf887c4..a0d8e426b 100644
--- a/test/tsan/atomic_free.cc
+++ b/test/tsan/atomic_free.cc
@@ -1,17 +1,18 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/atomic_free2.cc b/test/tsan/atomic_free2.cc
index c50be6bba..4a9f268a4 100644
--- a/test/tsan/atomic_free2.cc
+++ b/test/tsan/atomic_free2.cc
@@ -1,18 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/atomic_norace.cc b/test/tsan/atomic_norace.cc
index d9ccda588..625109b1f 100644
--- a/test/tsan/atomic_norace.cc
+++ b/test/tsan/atomic_norace.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/atomic_race.cc b/test/tsan/atomic_race.cc
index 9cee8ed82..5a0317c4a 100644
--- a/test/tsan/atomic_race.cc
+++ b/test/tsan/atomic_race.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
+#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/test/tsan/atomic_stack.cc b/test/tsan/atomic_stack.cc
index 7e3176f8e..979eaea8b 100644
--- a/test/tsan/atomic_stack.cc
+++ b/test/tsan/atomic_stack.cc
@@ -1,21 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/benign_race.cc b/test/tsan/benign_race.cc
index b6cba19aa..2f72fe186 100644
--- a/test/tsan/benign_race.cc
+++ b/test/tsan/benign_race.cc
@@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/blacklist2.cc b/test/tsan/blacklist2.cc
index 1092561e5..629b58821 100644
--- a/test/tsan/blacklist2.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/cond_cancel.c b/test/tsan/cond_cancel.c
index 397cad4b1..e744570b1 100644
--- a/test/tsan/cond_cancel.c
+++ b/test/tsan/cond_cancel.c
@@ -2,10 +2,7 @@
// CHECK-NOT: WARNING
// CHECK: OK
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/cond_race.cc b/test/tsan/cond_race.cc
index fa42fafca..52654f16e 100644
--- a/test/tsan/cond_race.cc
+++ b/test/tsan/cond_race.cc
@@ -3,10 +3,7 @@
// CHECK: ThreadSanitizer: data race
// CHECK: pthread_cond_signal
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/deadlock_detector_stress_test.cc b/test/tsan/deadlock_detector_stress_test.cc
index 53624782e..e02a9123f 100644
--- a/test/tsan/deadlock_detector_stress_test.cc
+++ b/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 <pthread.h>
+#include "test.h"
#undef NDEBUG
#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
#include <new>
#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<true>, &LockTest::Lock_1_0<true>);
// 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<bool wait = false>
+ void Lock_0_1() {
+ Lock2(0, 1);
+ if (wait)
+ barrier_wait(&barrier);
+ }
+
+ template<bool wait = false>
+ 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/test/tsan/deep_stack1.cc b/test/tsan/deep_stack1.cc
index 1d00a0e85..39185efee 100644
--- a/test/tsan/deep_stack1.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/fd_close_norace.cc b/test/tsan/fd_close_norace.cc
index 7238d64b4..1b52c20f9 100644
--- a/test/tsan/fd_close_norace.cc
+++ b/test/tsan/fd_close_norace.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -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/test/tsan/fd_location.cc b/test/tsan/fd_location.cc
index 535329e06..1861c89cb 100644
--- a/test/tsan/fd_location.cc
+++ b/test/tsan/fd_location.cc
@@ -1,23 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/fd_pipe_race.cc b/test/tsan/fd_pipe_race.cc
index 88c4ed4aa..b94893b93 100644
--- a/test/tsan/fd_pipe_race.cc
+++ b/test/tsan/fd_pipe_race.cc
@@ -1,23 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/fd_stdout_race.cc b/test/tsan/fd_stdout_race.cc
index d6a2c7c79..fcf8c2130 100644
--- a/test/tsan/fd_stdout_race.cc
+++ b/test/tsan/fd_stdout_race.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -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/test/tsan/fork_deadlock.cc b/test/tsan/fork_deadlock.cc
index cc5b12214..9418800bd 100644
--- a/test/tsan/fork_deadlock.cc
+++ b/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 <stdlib.h>
-#include <stdio.h>
+#include "test.h"
#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -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/test/tsan/fork_multithreaded.cc b/test/tsan/fork_multithreaded.cc
index 5176a14d6..3ddb417c7 100644
--- a/test/tsan/fork_multithreaded.cc
+++ b/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 <stdlib.h>
-#include <stdio.h>
+#include "test.h"
#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
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/test/tsan/free_race.c b/test/tsan/free_race.c
index 0fcfa4e90..63cee8c4a 100644
--- a/test/tsan/free_race.c
+++ b/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 <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/global_race.cc b/test/tsan/global_race.cc
index e12bb1d22..d70bee4a5 100644
--- a/test/tsan/global_race.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/global_race2.cc b/test/tsan/global_race2.cc
index ac994cc0f..6631008d8 100644
--- a/test/tsan/global_race2.cc
+++ b/test/tsan/global_race2.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/global_race3.cc b/test/tsan/global_race3.cc
index a3222bb3d..e7e9a7fef 100644
--- a/test/tsan/global_race3.cc
+++ b/test/tsan/global_race3.cc
@@ -1,8 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/halt_on_error.cc b/test/tsan/halt_on_error.cc
index 3c55c60a4..e55454b57 100644
--- a/test/tsan/halt_on_error.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/ignore_free.cc b/test/tsan/ignore_free.cc
index 1df6dce2f..bb6c6ee14 100644
--- a/test/tsan/ignore_free.cc
+++ b/test/tsan/ignore_free.cc
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/ignore_malloc.cc b/test/tsan/ignore_malloc.cc
index 0f1fb5e3d..1f633f062 100644
--- a/test/tsan/ignore_malloc.cc
+++ b/test/tsan/ignore_malloc.cc
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/ignore_race.cc b/test/tsan/ignore_race.cc
index c6e067fab..cc33b66b2 100644
--- a/test/tsan/ignore_race.cc
+++ b/test/tsan/ignore_race.cc
@@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/inlined_memcpy_race.cc b/test/tsan/inlined_memcpy_race.cc
index a95576a83..e3ed07abc 100644
--- a/test/tsan/inlined_memcpy_race.cc
+++ b/test/tsan/inlined_memcpy_race.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
+#include "test.h"
#include <string.h>
-#include <unistd.h>
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/test/tsan/inlined_memcpy_race2.cc b/test/tsan/inlined_memcpy_race2.cc
index 63b560f02..37414ba5d 100644
--- a/test/tsan/inlined_memcpy_race2.cc
+++ b/test/tsan/inlined_memcpy_race2.cc
@@ -1,24 +1,23 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
+#include "test.h"
#include <string.h>
-#include <unistd.h>
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/test/tsan/java.h b/test/tsan/java.h
index 66f46239a..35fdbc1e7 100644
--- a/test/tsan/java.h
+++ b/test/tsan/java.h
@@ -1,7 +1,4 @@
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
extern "C" {
typedef unsigned long jptr; // NOLINT
diff --git a/test/tsan/java_finalizer.cc b/test/tsan/java_finalizer.cc
index d5c6a22d1..acbbf08ad 100644
--- a/test/tsan/java_finalizer.cc
+++ b/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/test/tsan/java_lock.cc b/test/tsan/java_lock.cc
index 36a0f8b7b..f17205295 100644
--- a/test/tsan/java_lock.cc
+++ b/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 <unistd.h>
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/test/tsan/java_lock_move.cc b/test/tsan/java_lock_move.cc
index 19c3e35d6..fe5491dc2 100644
--- a/test/tsan/java_lock_move.cc
+++ b/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/test/tsan/java_lock_rec.cc b/test/tsan/java_lock_rec.cc
index 2b0ab0eb9..f0bf40196 100644
--- a/test/tsan/java_lock_rec.cc
+++ b/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 <unistd.h>
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/test/tsan/java_lock_rec_race.cc b/test/tsan/java_lock_rec_race.cc
index 841aa3963..3da8ad076 100644
--- a/test/tsan/java_lock_rec_race.cc
+++ b/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 <unistd.h>
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/test/tsan/java_move_overlap.cc b/test/tsan/java_move_overlap.cc
index 12955b4ba..7ed98ef1a 100644
--- a/test/tsan/java_move_overlap.cc
+++ b/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/test/tsan/java_move_overlap_race.cc b/test/tsan/java_move_overlap_race.cc
index 2b3769be6..874b90b26 100644
--- a/test/tsan/java_move_overlap_race.cc
+++ b/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/test/tsan/java_race_move.cc b/test/tsan/java_race_move.cc
index 8a51be92a..6d1b09216 100644
--- a/test/tsan/java_race_move.cc
+++ b/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/test/tsan/java_rwlock.cc b/test/tsan/java_rwlock.cc
index b03afa6e0..a4cc92a13 100644
--- a/test/tsan/java_rwlock.cc
+++ b/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 <unistd.h>
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/test/tsan/java_volatile.cc b/test/tsan/java_volatile.cc
index 56f4c2dd4..885b4f241 100644
--- a/test/tsan/java_volatile.cc
+++ b/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 <unistd.h>
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/test/tsan/load_shared_lib.cc b/test/tsan/load_shared_lib.cc
index a27dc1cc6..b7934b82d 100644
--- a/test/tsan/load_shared_lib.cc
+++ b/test/tsan/load_shared_lib.cc
@@ -7,35 +7,39 @@
#ifdef BUILD_SO
-#include <stddef.h>
-#include <unistd.h>
+#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 <dlfcn.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-
#include <string>
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/test/tsan/malloc_stack.cc b/test/tsan/malloc_stack.cc
index 602736075..ba1d62bcd 100644
--- a/test/tsan/malloc_stack.cc
+++ b/test/tsan/malloc_stack.cc
@@ -1,20 +1,21 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/map32bit.cc b/test/tsan/map32bit.cc
index 3a76fa2f6..9dae6880e 100644
--- a/test/tsan/map32bit.cc
+++ b/test/tsan/map32bit.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
+#include "test.h"
#include <stdint.h>
-#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
@@ -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/test/tsan/memcpy_race.cc b/test/tsan/memcpy_race.cc
index 8ec8e0a3e..d49577306 100644
--- a/test/tsan/memcpy_race.cc
+++ b/test/tsan/memcpy_race.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
+#include "test.h"
#include <string.h>
-#include <unistd.h>
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/test/tsan/mop_with_offset.cc b/test/tsan/mop_with_offset.cc
index e44c78b7d..c67e81e09 100644
--- a/test/tsan/mop_with_offset.cc
+++ b/test/tsan/mop_with_offset.cc
@@ -1,23 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mop_with_offset2.cc b/test/tsan/mop_with_offset2.cc
index a465d5f09..460267359 100644
--- a/test/tsan/mop_with_offset2.cc
+++ b/test/tsan/mop_with_offset2.cc
@@ -1,11 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset1.cc b/test/tsan/mutexset1.cc
index 72964edfb..407cfe5bd 100644
--- a/test/tsan/mutexset1.cc
+++ b/test/tsan/mutexset1.cc
@@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset2.cc b/test/tsan/mutexset2.cc
index 01a5f5df6..2a3e5bb95 100644
--- a/test/tsan/mutexset2.cc
+++ b/test/tsan/mutexset2.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset3.cc b/test/tsan/mutexset3.cc
index e14bb1111..ce64cf86e 100644
--- a/test/tsan/mutexset3.cc
+++ b/test/tsan/mutexset3.cc
@@ -1,14 +1,12 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset4.cc b/test/tsan/mutexset4.cc
index db860e005..b961efd21 100644
--- a/test/tsan/mutexset4.cc
+++ b/test/tsan/mutexset4.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset5.cc b/test/tsan/mutexset5.cc
index e1cc2fcac..8ef9af0ce 100644
--- a/test/tsan/mutexset5.cc
+++ b/test/tsan/mutexset5.cc
@@ -1,14 +1,12 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset6.cc b/test/tsan/mutexset6.cc
index 07dcc0a73..f4251db69 100644
--- a/test/tsan/mutexset6.cc
+++ b/test/tsan/mutexset6.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset7.cc b/test/tsan/mutexset7.cc
index 12174844c..d3a221d1b 100644
--- a/test/tsan/mutexset7.cc
+++ b/test/tsan/mutexset7.cc
@@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/mutexset8.cc b/test/tsan/mutexset8.cc
index 3e1ab8c5a..40d5d043d 100644
--- a/test/tsan/mutexset8.cc
+++ b/test/tsan/mutexset8.cc
@@ -1,13 +1,11 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/process_sleep.h b/test/tsan/process_sleep.h
deleted file mode 100644
index 5938a42bf..000000000
--- a/test/tsan/process_sleep.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <time.h>
-
-static void process_sleep(int sec) {
- clock_t beg = clock();
- while((clock() - beg) / CLOCKS_PER_SEC < sec)
- usleep(100);
-}
diff --git a/test/tsan/pthread_atfork_deadlock.c b/test/tsan/pthread_atfork_deadlock.c
index 0f33b9022..4aeec82b6 100644
--- a/test/tsan/pthread_atfork_deadlock.c
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/race_on_barrier.c b/test/tsan/race_on_barrier.c
index 99b18fe4d..cf8a4cb99 100644
--- a/test/tsan/race_on_barrier.c
+++ b/test/tsan/race_on_barrier.c
@@ -1,25 +1,24 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/race_on_mutex.c b/test/tsan/race_on_mutex.c
index b4adeeb4d..7bd461bf3 100644
--- a/test/tsan/race_on_mutex.c
+++ b/test/tsan/race_on_mutex.c
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/race_on_mutex2.c b/test/tsan/race_on_mutex2.c
index 1796d0c64..6ee5438f5 100644
--- a/test/tsan/race_on_mutex2.c
+++ b/test/tsan/race_on_mutex2.c
@@ -1,21 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/race_on_puts.cc b/test/tsan/race_on_puts.cc
index 1f2b4db83..f2541823b 100644
--- a/test/tsan/race_on_puts.cc
+++ b/test/tsan/race_on_puts.cc
@@ -1,21 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/race_on_read.cc b/test/tsan/race_on_read.cc
index 1ec0522b9..d388bbacd 100644
--- a/test/tsan/race_on_read.cc
+++ b/test/tsan/race_on_read.cc
@@ -1,31 +1,35 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <unistd.h>
#include <errno.h>
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/test/tsan/race_on_speculative_load.cc b/test/tsan/race_on_speculative_load.cc
index f816db9e8..b50b69677 100644
--- a/test/tsan/race_on_speculative_load.cc
+++ b/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 <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
+#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/test/tsan/race_on_write.cc b/test/tsan/race_on_write.cc
index 484bbb7ae..147591a39 100644
--- a/test/tsan/race_on_write.cc
+++ b/test/tsan/race_on_write.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -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/test/tsan/race_with_finished_thread.cc b/test/tsan/race_with_finished_thread.cc
index d28760093..755a7bd98 100644
--- a/test/tsan/race_with_finished_thread.cc
+++ b/test/tsan/race_with_finished_thread.cc
@@ -1,9 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
+#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/test/tsan/restore_stack.cc b/test/tsan/restore_stack.cc
index 5dbc279a4..39c11011c 100644
--- a/test/tsan/restore_stack.cc
+++ b/test/tsan/restore_stack.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/signal_errno.cc b/test/tsan/signal_errno.cc
index 1fa20f368..8305e8493 100644
--- a/test/tsan/signal_errno.cc
+++ b/test/tsan/signal_errno.cc
@@ -1,10 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <signal.h>
#include <sys/types.h>
-#include <unistd.h>
#include <errno.h>
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/test/tsan/signal_malloc.cc b/test/tsan/signal_malloc.cc
index 06932fba4..1dccb139c 100644
--- a/test/tsan/signal_malloc.cc
+++ b/test/tsan/signal_malloc.cc
@@ -1,9 +1,7 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <signal.h>
#include <sys/types.h>
-#include <unistd.h>
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/test/tsan/signal_recursive.cc b/test/tsan/signal_recursive.cc
index bbb680758..825338de9 100644
--- a/test/tsan/signal_recursive.cc
+++ b/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 <pthread.h>
+#include "test.h"
#include <semaphore.h>
#include <signal.h>
-#include <unistd.h>
#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#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/test/tsan/signal_sync.cc b/test/tsan/signal_sync.cc
index 15387b754..6ff19d3bd 100644
--- a/test/tsan/signal_sync.cc
+++ b/test/tsan/signal_sync.cc
@@ -1,11 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <unistd.h>
#include <errno.h>
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/test/tsan/signal_write.cc b/test/tsan/signal_write.cc
index 626d87a7a..edb3d2356 100644
--- a/test/tsan/signal_write.cc
+++ b/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/test/tsan/simple_race.c b/test/tsan/simple_race.c
index 7b60c5ec2..b4234acd7 100644
--- a/test/tsan/simple_race.c
+++ b/test/tsan/simple_race.c
@@ -1,22 +1,22 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/simple_race.cc b/test/tsan/simple_race.cc
index f711bb5d1..612ce2dc0 100644
--- a/test/tsan/simple_race.cc
+++ b/test/tsan/simple_race.cc
@@ -1,22 +1,22 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/simple_stack.c b/test/tsan/simple_stack.c
index 62840c27d..fd8f8ac49 100644
--- a/test/tsan/simple_stack.c
+++ b/test/tsan/simple_stack.c
@@ -1,7 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/simple_stack2.cc b/test/tsan/simple_stack2.cc
index 7044b82a1..719efdf05 100644
--- a/test/tsan/simple_stack2.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/sleep_sync.cc b/test/tsan/sleep_sync.cc
index c7614e16b..b2c6a1220 100644
--- a/test/tsan/sleep_sync.cc
+++ b/test/tsan/sleep_sync.cc
@@ -1,23 +1,25 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/sleep_sync2.cc b/test/tsan/sleep_sync2.cc
index 4e616992e..a1a7a3acc 100644
--- a/test/tsan/sleep_sync2.cc
+++ b/test/tsan/sleep_sync2.cc
@@ -1,18 +1,20 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/stack_race.cc b/test/tsan/stack_race.cc
index 2e02f46a2..1ada29535 100644
--- a/test/tsan/stack_race.cc
+++ b/test/tsan/stack_race.cc
@@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/stack_race2.cc b/test/tsan/stack_race2.cc
index 818db367b..00e31fb96 100644
--- a/test/tsan/stack_race2.cc
+++ b/test/tsan/stack_race2.cc
@@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/stack_sync_reuse.cc b/test/tsan/stack_sync_reuse.cc
index b1d5619df..5ea9e84b0 100644
--- a/test/tsan/stack_sync_reuse.cc
+++ b/test/tsan/stack_sync_reuse.cc
@@ -1,8 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+#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/test/tsan/suppress_same_address.cc b/test/tsan/suppress_same_address.cc
index df19da1cc..3ec13ee83 100644
--- a/test/tsan/suppress_same_address.cc
+++ b/test/tsan/suppress_same_address.cc
@@ -1,11 +1,10 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/suppressions_race.cc b/test/tsan/suppressions_race.cc
index 4a35c276e..45c30481f 100644
--- a/test/tsan/suppressions_race.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/suppressions_race2.cc b/test/tsan/suppressions_race2.cc
index f9827796f..24ecd8ef1 100644
--- a/test/tsan/suppressions_race2.cc
+++ b/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 <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/test.h b/test/tsan/test.h
new file mode 100644
index 000000000..4496e56cd
--- /dev/null
+++ b/test/tsan/test.h
@@ -0,0 +1,31 @@
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <stddef.h>
+
+// 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/test/tsan/thread_detach.c b/test/tsan/thread_detach.c
index 32cf641b1..802d8ded0 100644
--- a/test/tsan/thread_detach.c
+++ b/test/tsan/thread_detach.c
@@ -1,16 +1,16 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/thread_leak3.c b/test/tsan/thread_leak3.c
index f4db48421..c09fb714d 100644
--- a/test/tsan/thread_leak3.c
+++ b/test/tsan/thread_leak3.c
@@ -1,15 +1,17 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/thread_leak4.c b/test/tsan/thread_leak4.c
index 0d3b83070..1ebca5887 100644
--- a/test/tsan/thread_leak4.c
+++ b/test/tsan/thread_leak4.c
@@ -1,18 +1,18 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
+#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/test/tsan/thread_leak5.c b/test/tsan/thread_leak5.c
index ca244a9f2..acdbd1d38 100644
--- a/test/tsan/thread_leak5.c
+++ b/test/tsan/thread_leak5.c
@@ -1,18 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/thread_name.cc b/test/tsan/thread_name.cc
index a790c668c..80d30b82d 100644
--- a/test/tsan/thread_name.cc
+++ b/test/tsan/thread_name.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/thread_name2.cc b/test/tsan/thread_name2.cc
index 6a3dafe9c..a44f4b9d3 100644
--- a/test/tsan/thread_name2.cc
+++ b/test/tsan/thread_name2.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#include "test.h"
#if defined(__FreeBSD__)
#include <pthread_np.h>
@@ -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/test/tsan/tiny_race.c b/test/tsan/tiny_race.c
index c10eab15c..b6937febd 100644
--- a/test/tsan/tiny_race.c
+++ b/test/tsan/tiny_race.c
@@ -1,19 +1,20 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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/test/tsan/tls_race.cc b/test/tsan/tls_race.cc
index 18589347e..5e8172276 100644
--- a/test/tsan/tls_race.cc
+++ b/test/tsan/tls_race.cc
@@ -1,19 +1,19 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/tls_race2.cc b/test/tsan/tls_race2.cc
index 0ca629ada..d0f7b03e0 100644
--- a/test/tsan/tls_race2.cc
+++ b/test/tsan/tls_race2.cc
@@ -1,10 +1,8 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stddef.h>
-#include <unistd.h>
+#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/test/tsan/unaligned_race.cc b/test/tsan/unaligned_race.cc
index 6e9b5a33f..030642a4d 100644
--- a/test/tsan/unaligned_race.cc
+++ b/test/tsan/unaligned_race.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test.h"
#include <stdint.h>
-#include <unistd.h>
#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/test/tsan/vptr_harmful_race.cc b/test/tsan/vptr_harmful_race.cc
index 68e12e8e7..d15b3969a 100644
--- a/test/tsan/vptr_harmful_race.cc
+++ b/test/tsan/vptr_harmful_race.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
-#include <stdio.h>
-#include <unistd.h>
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/test/tsan/vptr_harmful_race2.cc b/test/tsan/vptr_harmful_race2.cc
index aa53bbb90..a56b74c09 100644
--- a/test/tsan/vptr_harmful_race2.cc
+++ b/test/tsan/vptr_harmful_race2.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
-#include <stdio.h>
-#include <unistd.h>
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/test/tsan/vptr_harmful_race3.cc b/test/tsan/vptr_harmful_race3.cc
index ac6ea94e5..3810a1068 100644
--- a/test/tsan/vptr_harmful_race3.cc
+++ b/test/tsan/vptr_harmful_race3.cc
@@ -1,8 +1,6 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
+#include "test.h"
#include <semaphore.h>
-#include <stdio.h>
-#include <unistd.h>
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/test/tsan/vptr_harmful_race4.cc b/test/tsan/vptr_harmful_race4.cc
index 969c9d58a..543514de8 100644
--- a/test/tsan/vptr_harmful_race4.cc
+++ b/test/tsan/vptr_harmful_race4.cc
@@ -1,7 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
+#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/test/tsan/write_in_reader_lock.cc b/test/tsan/write_in_reader_lock.cc
index 55882139b..3f7cb3579 100644
--- a/test/tsan/write_in_reader_lock.cc
+++ b/test/tsan/write_in_reader_lock.cc
@@ -1,6 +1,5 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-#include <pthread.h>
-#include <unistd.h>
+#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