From 81825ab6eab9b060f549a94c281c7cc3cc4f1b4f Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 13 Jun 2017 09:37:51 +0000 Subject: tsan: fix reading of mutex flags SyncVar::IsFlagSet returns true if any flag is set. This is wrong. Check the actual requested flag. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@305281 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/tsan/custom_mutex.h | 6 +++--- test/tsan/custom_mutex0.cc | 2 +- test/tsan/custom_mutex1.cc | 2 +- test/tsan/custom_mutex2.cc | 2 +- test/tsan/custom_mutex3.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 test/tsan/custom_mutex3.cc (limited to 'test/tsan') diff --git a/test/tsan/custom_mutex.h b/test/tsan/custom_mutex.h index 675ad59b3..e3ac7a9a5 100644 --- a/test/tsan/custom_mutex.h +++ b/test/tsan/custom_mutex.h @@ -6,11 +6,11 @@ // A very primitive mutex annotated with tsan annotations. class Mutex { public: - Mutex(bool prof = true) + Mutex(bool prof, unsigned flags) : prof_(prof) , locked_(false) , seq_(0) { - __tsan_mutex_create(this, 0); + __tsan_mutex_create(this, flags); } ~Mutex() { @@ -87,5 +87,5 @@ class Mutex { } }; -Mutex Mutex::prof_mu_(false); +Mutex Mutex::prof_mu_(false, __tsan_mutex_linker_init); int Mutex::prof_data_; diff --git a/test/tsan/custom_mutex0.cc b/test/tsan/custom_mutex0.cc index 998385ca1..8302fd884 100644 --- a/test/tsan/custom_mutex0.cc +++ b/test/tsan/custom_mutex0.cc @@ -4,7 +4,7 @@ // Test that custom annoations provide normal mutex synchronization // (no race reports for properly protected critical sections). -Mutex mu; +Mutex mu(true, 0); long data; void *thr(void *arg) { diff --git a/test/tsan/custom_mutex1.cc b/test/tsan/custom_mutex1.cc index 06186515f..1c879f502 100644 --- a/test/tsan/custom_mutex1.cc +++ b/test/tsan/custom_mutex1.cc @@ -3,7 +3,7 @@ // Test that failed TryLock does not induce parasitic synchronization. -Mutex mu; +Mutex mu(true, 0); long data; void *thr(void *arg) { diff --git a/test/tsan/custom_mutex2.cc b/test/tsan/custom_mutex2.cc index 9329cbc3f..d4aca7e03 100644 --- a/test/tsan/custom_mutex2.cc +++ b/test/tsan/custom_mutex2.cc @@ -3,7 +3,7 @@ // Test that Broadcast does not induce parasitic synchronization. -Mutex mu; +Mutex mu(true, 0); long data; void *thr(void *arg) { diff --git a/test/tsan/custom_mutex3.cc b/test/tsan/custom_mutex3.cc new file mode 100644 index 000000000..6e99926ad --- /dev/null +++ b/test/tsan/custom_mutex3.cc @@ -0,0 +1,46 @@ +// RUN: %clangxx_tsan -O1 --std=c++11 %s -o %t +// RUN: %env_tsan_opts=report_destroy_locked=0 %run %t 2>&1 | FileCheck %s +#include "custom_mutex.h" + +// Regression test for a bug. +// Thr1 destroys a locked mutex, previously such mutex was not removed from +// sync map and as the result subsequent uses of a mutex located at the same +// address caused false race reports. + +Mutex mu(false, __tsan_mutex_write_reentrant); +long data; + +void *thr1(void *arg) { + mu.Lock(); + mu.~Mutex(); + new(&mu) Mutex(true, __tsan_mutex_write_reentrant); + return 0; +} + +void *thr2(void *arg) { + barrier_wait(&barrier); + mu.Lock(); + data++; + mu.Unlock(); + return 0; +} + +int main() { + barrier_init(&barrier, 2); + pthread_t th; + pthread_create(&th, 0, thr1, 0); + pthread_join(th, 0); + + barrier_init(&barrier, 2); + pthread_create(&th, 0, thr2, 0); + mu.Lock(); + data++; + mu.Unlock(); + barrier_wait(&barrier); + pthread_join(th, 0); + fprintf(stderr, "DONE\n"); + return 0; +} + +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK: DONE -- cgit v1.2.3