1 // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s 2 // CHECK-NOT: unlock of unlocked mutex 3 // CHECK: ThreadSanitizer: data race 4 // CHECK: pthread_cond_signal 5 6 #include "test.h" 7 8 struct Ctx { 9 pthread_mutex_t m; 10 pthread_cond_t c; 11 bool done; 12 }; 13 thr(void * p)14void *thr(void *p) { 15 Ctx *c = (Ctx*)p; 16 pthread_mutex_lock(&c->m); 17 c->done = true; 18 pthread_mutex_unlock(&c->m); 19 pthread_cond_signal(&c->c); 20 barrier_wait(&barrier); 21 return 0; 22 } 23 main()24int main() { 25 barrier_init(&barrier, 2); 26 Ctx *c = new Ctx(); 27 pthread_mutex_init(&c->m, 0); 28 pthread_cond_init(&c->c, 0); 29 pthread_t th; 30 pthread_create(&th, 0, thr, c); 31 pthread_mutex_lock(&c->m); 32 while (!c->done) 33 pthread_cond_wait(&c->c, &c->m); 34 pthread_mutex_unlock(&c->m); 35 // otherwise it can be reported as use-after-free 36 barrier_wait(&barrier); 37 delete c; 38 pthread_join(th, 0); 39 } 40