tsan_barrier.h: New.
2015-01-08 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-c++-common/tsan/tsan_barrier.h: New. * c-c++-common/tsan/atomic_stack.c: Reworked to not depend on sleep. * c-c++-common/tsan/bitfield_race.c: Likewise. * c-c++-common/tsan/fd_pipe_race.c: Likewise. * c-c++-common/tsan/mutexset1.c: Likewise. * c-c++-common/tsan/race_on_barrier.c: Likewise. * c-c++-common/tsan/race_on_mutex.c: Likewise. * c-c++-common/tsan/race_on_mutex2.c: Likewise. * c-c++-common/tsan/simple_race.c: Likewise. * c-c++-common/tsan/simple_stack.c: Likewise. * c-c++-common/tsan/sleep_sync.c: Likewise. * c-c++-common/tsan/tiny_race.c: Likewise. * c-c++-common/tsan/tls_race.c: Likewise. * c-c++-common/tsan/write_in_reader_lock.c: Likewise. * g++.dg/tsan/aligned_vs_unaligned_race.C: Likewise. * g++.dg/tsan/atomic_free.C: Likewise. * g++.dg/tsan/atomic_free2.C: Likewise. * g++.dg/tsan/cond_race.C: Likewise. * g++.dg/tsan/tsan_barrier.h: Copied from c-c++-common/tsan. From-SVN: r219367
This commit is contained in:
parent
7c8db13ee3
commit
75d1c391e4
@ -1,3 +1,25 @@
|
||||
2015-01-08 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
* c-c++-common/tsan/tsan_barrier.h: New.
|
||||
* c-c++-common/tsan/atomic_stack.c: Reworked to not depend on sleep.
|
||||
* c-c++-common/tsan/bitfield_race.c: Likewise.
|
||||
* c-c++-common/tsan/fd_pipe_race.c: Likewise.
|
||||
* c-c++-common/tsan/mutexset1.c: Likewise.
|
||||
* c-c++-common/tsan/race_on_barrier.c: Likewise.
|
||||
* c-c++-common/tsan/race_on_mutex.c: Likewise.
|
||||
* c-c++-common/tsan/race_on_mutex2.c: Likewise.
|
||||
* c-c++-common/tsan/simple_race.c: Likewise.
|
||||
* c-c++-common/tsan/simple_stack.c: Likewise.
|
||||
* c-c++-common/tsan/sleep_sync.c: Likewise.
|
||||
* c-c++-common/tsan/tiny_race.c: Likewise.
|
||||
* c-c++-common/tsan/tls_race.c: Likewise.
|
||||
* c-c++-common/tsan/write_in_reader_lock.c: Likewise.
|
||||
* g++.dg/tsan/aligned_vs_unaligned_race.C: Likewise.
|
||||
* g++.dg/tsan/atomic_free.C: Likewise.
|
||||
* g++.dg/tsan/atomic_free2.C: Likewise.
|
||||
* g++.dg/tsan/cond_race.C: Likewise.
|
||||
* g++.dg/tsan/tsan_barrier.h: Copied from c-c++-common/tsan.
|
||||
|
||||
2015-01-08 Hans-Peter Nilsson <hp@axis.com>
|
||||
|
||||
PR testsuite/62250
|
||||
|
@ -1,22 +1,26 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
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,8 +1,10 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
struct bitfield
|
||||
{
|
||||
int a:10;
|
||||
@ -10,15 +12,17 @@ struct bitfield
|
||||
} Global;
|
||||
|
||||
void *Thread1(void *x) {
|
||||
sleep(1);
|
||||
barrier_wait(&barrier);
|
||||
Global.a = 42;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
barrier_init(&barrier, 2);
|
||||
pthread_t t;
|
||||
pthread_create(&t, 0, Thread1, 0);
|
||||
Global.b = 43;
|
||||
barrier_wait(&barrier);
|
||||
pthread_join(t, 0);
|
||||
return Global.a;
|
||||
}
|
||||
|
@ -1,30 +1,35 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
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);
|
||||
pthread_create(&t[1], NULL, Thread2, NULL);
|
||||
pthread_join(t[0], NULL);
|
||||
pthread_join(t[1], NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*\n" } */
|
||||
|
@ -1,14 +1,15 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
int Global;
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
void *Thread1(void *x) {
|
||||
sleep(1);
|
||||
barrier_wait(&barrier);
|
||||
pthread_mutex_lock(&mtx);
|
||||
Global++;
|
||||
pthread_mutex_unlock(&mtx);
|
||||
@ -17,11 +18,13 @@ void *Thread1(void *x) {
|
||||
|
||||
void *Thread2(void *x) {
|
||||
Global--;
|
||||
barrier_wait(&barrier);
|
||||
return NULL;/* { dg-output ".*" } */
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
barrier_init(&barrier, 2);
|
||||
pthread_mutex_init(&mtx, 0);
|
||||
pthread_t t[2];
|
||||
pthread_create(&t[0], NULL, Thread1, NULL);
|
||||
|
@ -1,26 +1,28 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
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,10 +1,10 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
pthread_mutex_t Mtx;
|
||||
int Global;
|
||||
|
||||
@ -13,11 +13,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);
|
||||
@ -25,6 +26,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);
|
||||
@ -37,7 +39,7 @@ int main() {
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
|
||||
/* { dg-output " Atomic read of size 1 at .* by thread T2:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 pthread_mutex_lock.*" } */
|
||||
/* { dg-output " #1 Thread2.* .*(race_on_mutex.c:21|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " Previous write of size 1 at .* by thread T1:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 pthread_mutex_init .* (.)*" } */
|
||||
/* { dg-output " #1 Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */
|
||||
|
@ -1,22 +1,25 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
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,13 +1,15 @@
|
||||
/* { dg-set-target-env-var TSAN_OPTIONS "halt_on_error=1" } */
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
#define MAX_ITERATIONS_NUMBER 100
|
||||
#define SLEEP_STEP 128000
|
||||
#define MAX_ITERATIONS_NUMBER 1
|
||||
#define SLEEP_STEP 128000
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
unsigned int delay_time = 1000;
|
||||
|
||||
static inline void delay () {
|
||||
@ -17,6 +19,7 @@ static inline void delay () {
|
||||
extern int main_1();
|
||||
|
||||
int main() {
|
||||
barrier_init(&barrier, 2);
|
||||
int i;
|
||||
for (i = 0; i < MAX_ITERATIONS_NUMBER; i++) {
|
||||
main_1();
|
||||
@ -28,6 +31,7 @@ int main() {
|
||||
int Global;
|
||||
|
||||
void *Thread1(void *x) {
|
||||
barrier_wait(&barrier);
|
||||
delay();
|
||||
Global = 42;
|
||||
return NULL;
|
||||
@ -35,6 +39,7 @@ void *Thread1(void *x) {
|
||||
|
||||
void *Thread2(void *x) {
|
||||
Global = 43;
|
||||
barrier_wait(&barrier);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
int Global;
|
||||
|
||||
void __attribute__((noinline)) foo1() {
|
||||
@ -25,13 +26,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;
|
||||
}
|
||||
|
||||
@ -40,6 +42,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);
|
||||
@ -50,16 +53,16 @@ int main() {
|
||||
|
||||
/* { dg-output "WARNING: ThreadSanitizer: data race.*" } */
|
||||
/* { dg-output " Write of size 4 at .* by thread T1:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 foo1.* .*(simple_stack.c:10|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 bar1.* .*(simple_stack.c:15|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #2 Thread1.* .*(simple_stack.c:29|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #0 foo1.* .*(simple_stack.c:11|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 bar1.* .*(simple_stack.c:16|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #2 Thread1.* .*(simple_stack.c:30|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " Previous read of size 4 at .* by thread T2:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 foo2.* .*(simple_stack.c:19|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 bar2.* .*(simple_stack.c:24|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #2 Thread2.* .*(simple_stack.c:34|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #0 foo2.* .*(simple_stack.c:20|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 bar2.* .*(simple_stack.c:25|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #2 Thread2.* .*(simple_stack.c:35|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " Thread T1 \\(tid=.*, running\\) created by main thread at:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 pthread_create .* (.*)" } */
|
||||
/* { dg-output " #1 StartThread.* .*(simple_stack.c:39|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 StartThread.* .*(simple_stack.c:41|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " Thread T2 (.*) created by main thread at:(\n|\r\n|\r)" } */
|
||||
/* { dg-output " #0 pthread_create .* (.*)" } */
|
||||
/* { dg-output " #1 StartThread.* .*(simple_stack.c:39|\\?{2}:0) (.*)" } */
|
||||
/* { dg-output " #1 StartThread.* .*(simple_stack.c:41|\\?{2}:0) (.*)" } */
|
||||
|
@ -1,8 +1,11 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
int X = 0;
|
||||
|
||||
void MySleep() {
|
||||
@ -10,15 +13,18 @@ void MySleep() {
|
||||
}
|
||||
|
||||
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,20 +1,24 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
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,18 +1,24 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
void *Thread(void *a) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
14
gcc/testsuite/c-c++-common/tsan/tsan_barrier.h
Normal file
14
gcc/testsuite/c-c++-common/tsan/tsan_barrier.h
Normal file
@ -0,0 +1,14 @@
|
||||
/* TSAN-invisible barriers. Link with -ldl. */
|
||||
#include <pthread.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static __typeof(pthread_barrier_wait) *barrier_wait;
|
||||
|
||||
static
|
||||
void barrier_init (pthread_barrier_t *barrier, unsigned count)
|
||||
{
|
||||
void *h = dlopen ("libpthread.so.0", RTLD_LAZY);
|
||||
barrier_wait = (__typeof (pthread_barrier_wait) *)
|
||||
dlsym (h, "pthread_barrier_wait");
|
||||
pthread_barrier_init (barrier, NULL, count);
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
pthread_rwlock_t rwlock;
|
||||
int GLOB;
|
||||
|
||||
@ -10,13 +12,14 @@ void *Thread1(void *p) {
|
||||
(void)p;
|
||||
pthread_rwlock_rdlock(&rwlock);
|
||||
// Write under reader lock.
|
||||
sleep(1);
|
||||
barrier_wait(&barrier);
|
||||
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;
|
||||
@ -24,6 +27,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;
|
||||
|
@ -1,11 +1,16 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
uint64_t Global[2];
|
||||
|
||||
void *Thread1(void *x) {
|
||||
barrier_wait(&barrier);
|
||||
Global[1]++;
|
||||
return NULL;
|
||||
}
|
||||
@ -15,10 +20,12 @@ void *Thread2(void *x) {
|
||||
struct __attribute__((packed, aligned(1))) u_uint64_t { uint64_t val; };
|
||||
u_uint64_t *p4 = reinterpret_cast<u_uint64_t *>(p1 + 1);
|
||||
(*p4).val++;
|
||||
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,18 +1,23 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
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,19 +1,24 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
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,10 +1,12 @@
|
||||
/* { dg-shouldfail "tsan" } */
|
||||
/* { dg-additional-options "-ldl" } */
|
||||
/* { dg-output "ThreadSanitizer: data race.*" } */
|
||||
/* { dg-output "pthread_cond_signal.*" } */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "tsan_barrier.h"
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
struct Ctx {
|
||||
pthread_mutex_t m;
|
||||
@ -18,10 +20,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);
|
||||
@ -31,6 +35,7 @@ int main() {
|
||||
while (!c->done)
|
||||
pthread_cond_wait(&c->c, &c->m);
|
||||
pthread_mutex_unlock(&c->m);
|
||||
barrier_wait(&barrier);
|
||||
delete c;
|
||||
pthread_join(th, 0);
|
||||
}
|
||||
|
14
gcc/testsuite/g++.dg/tsan/tsan_barrier.h
Normal file
14
gcc/testsuite/g++.dg/tsan/tsan_barrier.h
Normal file
@ -0,0 +1,14 @@
|
||||
/* TSAN-invisible barriers. Link with -ldl. */
|
||||
#include <pthread.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static __typeof(pthread_barrier_wait) *barrier_wait;
|
||||
|
||||
static
|
||||
void barrier_init (pthread_barrier_t *barrier, unsigned count)
|
||||
{
|
||||
void *h = dlopen ("libpthread.so.0", RTLD_LAZY);
|
||||
barrier_wait = (__typeof (pthread_barrier_wait) *)
|
||||
dlsym (h, "pthread_barrier_wait");
|
||||
pthread_barrier_init (barrier, NULL, count);
|
||||
}
|
Loading…
Reference in New Issue
Block a user