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)14 void *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()24 int 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