diff options
Diffstat (limited to 'test/tsan/cond_race.cc')
-rw-r--r-- | test/tsan/cond_race.cc | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/test/tsan/cond_race.cc b/test/tsan/cond_race.cc new file mode 100644 index 000000000000..fa42fafca4d2 --- /dev/null +++ b/test/tsan/cond_race.cc @@ -0,0 +1,40 @@ +// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s +// CHECK-NOT: unlock of unlocked mutex +// CHECK: ThreadSanitizer: data race +// CHECK: pthread_cond_signal + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> + +struct Ctx { + pthread_mutex_t m; + pthread_cond_t c; + bool done; +}; + +void *thr(void *p) { + Ctx *c = (Ctx*)p; + pthread_mutex_lock(&c->m); + c->done = true; + pthread_mutex_unlock(&c->m); + pthread_cond_signal(&c->c); + return 0; +} + +int main() { + Ctx *c = new Ctx(); + pthread_mutex_init(&c->m, 0); + pthread_cond_init(&c->c, 0); + pthread_t th; + pthread_create(&th, 0, thr, c); + pthread_mutex_lock(&c->m); + 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); + delete c; + pthread_join(th, 0); +} |