forked from OSchip/llvm-project
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
This commit is contained in:
parent
79ca0fd1a0
commit
3ab6b2347e
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]+]]):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]+]]):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]+]]):
|
||||
|
|
|
@ -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]+]]):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]+]]):
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)?}} ({{.*}})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)?}} ({{.*}})
|
||||
|
|
|
@ -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+{{.*}})
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue