1/* { dg-shouldfail "tsan" } */ 2/* { dg-additional-options "-ldl" } */ 3 4#include <pthread.h> 5#include "tsan_barrier.h" 6 7static pthread_barrier_t barrier; 8pthread_mutex_t Mtx; 9int Global; 10 11void *Thread1(void *x) { 12 pthread_mutex_init(&Mtx, 0); 13 pthread_mutex_lock(&Mtx); 14 Global = 42; 15 pthread_mutex_unlock(&Mtx); 16 barrier_wait(&barrier); 17 return NULL; 18} 19 20void *Thread2(void *x) { 21 barrier_wait(&barrier); 22 pthread_mutex_lock(&Mtx); 23 Global = 43; 24 pthread_mutex_unlock(&Mtx); 25 return NULL; 26} 27 28int main() { 29 barrier_init(&barrier, 2); 30 pthread_t t[2]; 31 pthread_create(&t[0], NULL, Thread1, NULL); 32 pthread_create(&t[1], NULL, Thread2, NULL); 33 pthread_join(t[0], NULL); 34 pthread_join(t[1], NULL); 35 pthread_mutex_destroy(&Mtx); 36 return 0; 37} 38 39/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ 40/* { dg-output " Atomic read of size 1 at .* by thread T2:(\n|\r\n|\r)" } */ 41/* { dg-output " #0 pthread_mutex_lock.*" } */ 42/* { dg-output " #1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */ 43/* { dg-output " Previous write of size 1 at .* by thread T1:(\n|\r\n|\r)" } */ 44/* { dg-output " #0 pthread_mutex_init .* (.)*" } */ 45/* { dg-output " #1 Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */ 46