summaryrefslogtreecommitdiff
path: root/test/tsan
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-13 09:37:51 +0000
committerDmitry Vyukov <dvyukov@google.com>2017-06-13 09:37:51 +0000
commit81825ab6eab9b060f549a94c281c7cc3cc4f1b4f (patch)
treef11f0295dbb96e3fed597a56c319a6a93af1bbd3 /test/tsan
parent247f914543e89003c932df550a91de37ec19ca8a (diff)
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
Diffstat (limited to 'test/tsan')
-rw-r--r--test/tsan/custom_mutex.h6
-rw-r--r--test/tsan/custom_mutex0.cc2
-rw-r--r--test/tsan/custom_mutex1.cc2
-rw-r--r--test/tsan/custom_mutex2.cc2
-rw-r--r--test/tsan/custom_mutex3.cc46
5 files changed, 52 insertions, 6 deletions
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