[compiler-rt] 0118a64 - tsan: switch to the new sanitizer_common mutex
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 23 00:13:31 PDT 2021
Author: Dmitry Vyukov
Date: 2021-07-23T09:13:26+02:00
New Revision: 0118a649348b4a2079911037c8d1d3ed648ec25e
URL: https://github.com/llvm/llvm-project/commit/0118a649348b4a2079911037c8d1d3ed648ec25e
DIFF: https://github.com/llvm/llvm-project/commit/0118a649348b4a2079911037c8d1d3ed648ec25e.diff
LOG: tsan: switch to the new sanitizer_common mutex
Now that sanitizer_common mutex has feature-parity with tsan mutex,
switch tsan to the sanitizer_common mutex and remove tsan's custom mutex.
Reviewed By: vitalybuka, melver
Differential Revision: https://reviews.llvm.org/D106379
Added:
Modified:
compiler-rt/lib/sanitizer_common/sanitizer_mutex.h
compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp
compiler-rt/lib/tsan/CMakeLists.txt
compiler-rt/lib/tsan/go/build.bat
compiler-rt/lib/tsan/go/buildgo.sh
compiler-rt/lib/tsan/rtl/tsan_defs.h
compiler-rt/lib/tsan/rtl/tsan_dense_alloc.h
compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp
compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
compiler-rt/lib/tsan/rtl/tsan_sync.h
compiler-rt/lib/tsan/rtl/tsan_trace.h
compiler-rt/lib/tsan/tests/unit/CMakeLists.txt
Removed:
compiler-rt/lib/tsan/rtl/tsan_mutex.cpp
compiler-rt/lib/tsan/rtl/tsan_mutex.h
compiler-rt/lib/tsan/tests/unit/tsan_mutex_test.cpp
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h
index c15b1ca08de1e..a78eb4a7f9964 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h
@@ -149,9 +149,9 @@ class CheckedMutex {
};
// Reader-writer mutex.
-class MUTEX Mutex2 {
+class MUTEX Mutex {
public:
- constexpr Mutex2(MutexType type = MutexUnchecked) : checked_(type) {}
+ constexpr Mutex(MutexType type = MutexUnchecked) : checked_(type) {}
void Lock() ACQUIRE() {
checked_.Lock();
@@ -329,8 +329,8 @@ class MUTEX Mutex2 {
static constexpr u64 kWriterLock = 1ull << (3 * kCounterWidth);
static constexpr u64 kWriterSpinWait = 1ull << (3 * kCounterWidth + 1);
- Mutex2(const Mutex2 &) = delete;
- void operator=(const Mutex2 &) = delete;
+ Mutex(const Mutex &) = delete;
+ void operator=(const Mutex &) = delete;
};
void FutexWait(atomic_uint32_t *p, u32 cmp);
@@ -477,6 +477,8 @@ typedef GenericScopedLock<StaticSpinMutex> SpinMutexLock;
typedef GenericScopedLock<BlockingMutex> BlockingMutexLock;
typedef GenericScopedLock<RWMutex> RWMutexLock;
typedef GenericScopedReadLock<RWMutex> RWMutexReadLock;
+typedef GenericScopedLock<Mutex> Lock;
+typedef GenericScopedReadLock<Mutex> ReadLock;
} // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp
index f943e22da2150..1595677503a69 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp
@@ -158,12 +158,12 @@ TEST(SanitizerCommon, BlockingMutex) {
check_locked(mtx);
}
-TEST(SanitizerCommon, Mutex2) {
- Mutex2 mtx;
- TestData<Mutex2> data(&mtx);
+TEST(SanitizerCommon, Mutex) {
+ Mutex mtx;
+ TestData<Mutex> data(&mtx);
pthread_t threads[kThreads];
for (int i = 0; i < kThreads; i++)
- PTHREAD_CREATE(&threads[i], 0, read_write_thread<Mutex2>, &data);
+ PTHREAD_CREATE(&threads[i], 0, read_write_thread<Mutex>, &data);
for (int i = 0; i < kThreads; i++) PTHREAD_JOIN(threads[i], 0);
}
diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt
index fffa9d07ac778..a60c8f842a2d7 100644
--- a/compiler-rt/lib/tsan/CMakeLists.txt
+++ b/compiler-rt/lib/tsan/CMakeLists.txt
@@ -39,7 +39,6 @@ set(TSAN_SOURCES
rtl/tsan_malloc_mac.cpp
rtl/tsan_md5.cpp
rtl/tsan_mman.cpp
- rtl/tsan_mutex.cpp
rtl/tsan_mutexset.cpp
rtl/tsan_preinit.cpp
rtl/tsan_report.cpp
@@ -94,7 +93,6 @@ set(TSAN_HEADERS
rtl/tsan_interface_inl.h
rtl/tsan_interface_java.h
rtl/tsan_mman.h
- rtl/tsan_mutex.h
rtl/tsan_mutexset.h
rtl/tsan_platform.h
rtl/tsan_ppc_regs.h
diff --git a/compiler-rt/lib/tsan/go/build.bat b/compiler-rt/lib/tsan/go/build.bat
index 242535f24cba8..8409c7e12ba82 100644
--- a/compiler-rt/lib/tsan/go/build.bat
+++ b/compiler-rt/lib/tsan/go/build.bat
@@ -4,7 +4,6 @@ type ^
..\rtl\tsan_clock.cpp ^
..\rtl\tsan_flags.cpp ^
..\rtl\tsan_md5.cpp ^
- ..\rtl\tsan_mutex.cpp ^
..\rtl\tsan_report.cpp ^
..\rtl\tsan_rtl.cpp ^
..\rtl\tsan_rtl_mutex.cpp ^
diff --git a/compiler-rt/lib/tsan/go/buildgo.sh b/compiler-rt/lib/tsan/go/buildgo.sh
index d3771e985a436..e15f993f2703d 100755
--- a/compiler-rt/lib/tsan/go/buildgo.sh
+++ b/compiler-rt/lib/tsan/go/buildgo.sh
@@ -9,7 +9,6 @@ SRCS="
../rtl/tsan_flags.cpp
../rtl/tsan_interface_atomic.cpp
../rtl/tsan_md5.cpp
- ../rtl/tsan_mutex.cpp
../rtl/tsan_report.cpp
../rtl/tsan_rtl.cpp
../rtl/tsan_rtl_mutex.cpp
diff --git a/compiler-rt/lib/tsan/rtl/tsan_defs.h b/compiler-rt/lib/tsan/rtl/tsan_defs.h
index 5c8f2801b0c2b..f2fb7b1a213f2 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_defs.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_defs.h
@@ -15,6 +15,7 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_mutex.h"
#include "ubsan/ubsan_platform.h"
// Setup defaults for compile definitions.
@@ -172,6 +173,17 @@ enum ExternalTag : uptr {
// as 16-bit values, see tsan_defs.h.
};
+enum MutexType {
+ MutexTypeTrace = MutexLastCommon,
+ MutexTypeReport,
+ MutexTypeSyncVar,
+ MutexTypeAnnotations,
+ MutexTypeAtExit,
+ MutexTypeFired,
+ MutexTypeRacy,
+ MutexTypeGlobalProc,
+};
+
} // namespace __tsan
#endif // TSAN_DEFS_H
diff --git a/compiler-rt/lib/tsan/rtl/tsan_dense_alloc.h b/compiler-rt/lib/tsan/rtl/tsan_dense_alloc.h
index 6c89e40598042..68ded43c4f6bc 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_dense_alloc.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_dense_alloc.h
@@ -20,7 +20,6 @@
#include "sanitizer_common/sanitizer_common.h"
#include "tsan_defs.h"
-#include "tsan_mutex.h"
namespace __tsan {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index c7ba686e7c83d..aaca967c38745 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -267,7 +267,7 @@ ScopedInterceptor::~ScopedInterceptor() {
if (!thr_->ignore_interceptors) {
ProcessPendingSignals(thr_);
FuncExit(thr_);
- CheckNoLocks(thr_);
+ CheckedMutex::CheckNoLocks();
}
}
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp
index 175855f66c8cb..47314f5ad812a 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp
@@ -15,7 +15,6 @@
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_vector.h"
#include "tsan_interface_ann.h"
-#include "tsan_mutex.h"
#include "tsan_report.h"
#include "tsan_rtl.h"
#include "tsan_mman.h"
@@ -38,7 +37,7 @@ class ScopedAnnotation {
~ScopedAnnotation() {
FuncExit(thr_);
- CheckNoLocks(thr_);
+ CheckedMutex::CheckNoLocks();
}
private:
ThreadState *const thr_;
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
index 081c6ff1022e8..6aa8a7b1d6a75 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
@@ -12,7 +12,6 @@
#include "tsan_interface_java.h"
#include "tsan_rtl.h"
-#include "tsan_mutex.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
diff --git a/compiler-rt/lib/tsan/rtl/tsan_mutex.cpp b/compiler-rt/lib/tsan/rtl/tsan_mutex.cpp
deleted file mode 100644
index d8b1826ee47bb..0000000000000
--- a/compiler-rt/lib/tsan/rtl/tsan_mutex.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-//===-- tsan_mutex.cpp ----------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_libc.h"
-#include "tsan_mutex.h"
-#include "tsan_platform.h"
-#include "tsan_rtl.h"
-
-namespace __tsan {
-
-// Simple reader-writer spin-mutex. Optimized for not-so-contended case.
-// Readers have preference, can possibly starvate writers.
-
-// The table fixes what mutexes can be locked under what mutexes.
-// E.g. if the row for MutexTypeThreads contains MutexTypeReport,
-// then Report mutex can be locked while under Threads mutex.
-// The leaf mutexes can be locked under any other mutexes.
-// Recursive locking is not supported.
-#if SANITIZER_DEBUG && !SANITIZER_GO
-const MutexType MutexTypeLeaf = (MutexType)-1;
-static MutexType CanLockTab[MutexTypeCount][MutexTypeCount] = {
- /*0 MutexTypeInvalid*/ {},
- /*1 MutexTypeTrace*/ {MutexTypeLeaf},
- /*2 MutexTypeThreads*/ {MutexTypeReport},
- /*3 MutexTypeReport*/ {MutexTypeSyncVar,
- MutexTypeMBlock, MutexTypeJavaMBlock},
- /*4 MutexTypeSyncVar*/ {MutexTypeDDetector},
- /*5 MutexTypeSyncTab*/ {}, // unused
- /*6 MutexTypeSlab*/ {MutexTypeLeaf},
- /*7 MutexTypeAnnotations*/ {},
- /*8 MutexTypeAtExit*/ {MutexTypeSyncVar},
- /*9 MutexTypeMBlock*/ {MutexTypeSyncVar},
- /*10 MutexTypeJavaMBlock*/ {MutexTypeSyncVar},
- /*11 MutexTypeDDetector*/ {},
- /*12 MutexTypeFired*/ {MutexTypeLeaf},
- /*13 MutexTypeRacy*/ {MutexTypeLeaf},
- /*14 MutexTypeGlobalProc*/ {},
-};
-
-static bool CanLockAdj[MutexTypeCount][MutexTypeCount];
-#endif
-
-void InitializeMutex() {
-#if SANITIZER_DEBUG && !SANITIZER_GO
- // Build the "can lock" adjacency matrix.
- // If [i][j]==true, then one can lock mutex j while under mutex i.
- const int N = MutexTypeCount;
- int cnt[N] = {};
- bool leaf[N] = {};
- for (int i = 1; i < N; i++) {
- for (int j = 0; j < N; j++) {
- MutexType z = CanLockTab[i][j];
- if (z == MutexTypeInvalid)
- continue;
- if (z == MutexTypeLeaf) {
- CHECK(!leaf[i]);
- leaf[i] = true;
- continue;
- }
- CHECK(!CanLockAdj[i][(int)z]);
- CanLockAdj[i][(int)z] = true;
- cnt[i]++;
- }
- }
- for (int i = 0; i < N; i++) {
- CHECK(!leaf[i] || cnt[i] == 0);
- }
- // Add leaf mutexes.
- for (int i = 0; i < N; i++) {
- if (!leaf[i])
- continue;
- for (int j = 0; j < N; j++) {
- if (i == j || leaf[j] || j == MutexTypeInvalid)
- continue;
- CHECK(!CanLockAdj[j][i]);
- CanLockAdj[j][i] = true;
- }
- }
- // Build the transitive closure.
- bool CanLockAdj2[MutexTypeCount][MutexTypeCount];
- for (int i = 0; i < N; i++) {
- for (int j = 0; j < N; j++) {
- CanLockAdj2[i][j] = CanLockAdj[i][j];
- }
- }
- for (int k = 0; k < N; k++) {
- for (int i = 0; i < N; i++) {
- for (int j = 0; j < N; j++) {
- if (CanLockAdj2[i][k] && CanLockAdj2[k][j]) {
- CanLockAdj2[i][j] = true;
- }
- }
- }
- }
-#if 0
- Printf("Can lock graph:\n");
- for (int i = 0; i < N; i++) {
- for (int j = 0; j < N; j++) {
- Printf("%d ", CanLockAdj[i][j]);
- }
- Printf("\n");
- }
- Printf("Can lock graph closure:\n");
- for (int i = 0; i < N; i++) {
- for (int j = 0; j < N; j++) {
- Printf("%d ", CanLockAdj2[i][j]);
- }
- Printf("\n");
- }
-#endif
- // Verify that the graph is acyclic.
- for (int i = 0; i < N; i++) {
- if (CanLockAdj2[i][i]) {
- Printf("Mutex %d participates in a cycle\n", i);
- Die();
- }
- }
-#endif
-}
-
-InternalDeadlockDetector::InternalDeadlockDetector() {
- // Rely on zero initialization because some mutexes can be locked before ctor.
-}
-
-#if SANITIZER_DEBUG && !SANITIZER_GO
-void InternalDeadlockDetector::Lock(MutexType t) {
- // Printf("LOCK %d @%zu\n", t, seq_ + 1);
- CHECK_GT(t, MutexTypeInvalid);
- CHECK_LT(t, MutexTypeCount);
- u64 max_seq = 0;
- u64 max_idx = MutexTypeInvalid;
- for (int i = 0; i != MutexTypeCount; i++) {
- if (locked_[i] == 0)
- continue;
- CHECK_NE(locked_[i], max_seq);
- if (max_seq < locked_[i]) {
- max_seq = locked_[i];
- max_idx = i;
- }
- }
- locked_[t] = ++seq_;
- if (max_idx == MutexTypeInvalid)
- return;
- // Printf(" last %d @%zu\n", max_idx, max_seq);
- if (!CanLockAdj[max_idx][t]) {
- Printf("ThreadSanitizer: internal deadlock detected\n");
- Printf("ThreadSanitizer: can't lock %d while under %zu\n",
- t, (uptr)max_idx);
- CHECK(0);
- }
-}
-
-void InternalDeadlockDetector::Unlock(MutexType t) {
- // Printf("UNLO %d @%zu #%zu\n", t, seq_, locked_[t]);
- CHECK(locked_[t]);
- locked_[t] = 0;
-}
-
-void InternalDeadlockDetector::CheckNoLocks() {
- for (int i = 0; i != MutexTypeCount; i++) {
- CHECK_EQ(locked_[i], 0);
- }
-}
-#endif
-
-void CheckNoLocks(ThreadState *thr) {
-#if SANITIZER_DEBUG && !SANITIZER_GO
- thr->internal_deadlock_detector.CheckNoLocks();
-#endif
-}
-
-const uptr kUnlocked = 0;
-const uptr kWriteLock = 1;
-const uptr kReadLock = 2;
-
-class Backoff {
- public:
- Backoff()
- : iter_() {
- }
-
- bool Do() {
- if (iter_++ < kActiveSpinIters)
- proc_yield(kActiveSpinCnt);
- else
- internal_sched_yield();
- return true;
- }
-
- u64 Contention() const {
- u64 active = iter_ % kActiveSpinIters;
- u64 passive = iter_ - active;
- return active + 10 * passive;
- }
-
- private:
- int iter_;
- static const int kActiveSpinIters = 10;
- static const int kActiveSpinCnt = 20;
-};
-
-Mutex::Mutex(MutexType type) {
- CHECK_GT(type, MutexTypeInvalid);
- CHECK_LT(type, MutexTypeCount);
-#if SANITIZER_DEBUG
- type_ = type;
-#endif
- atomic_store(&state_, kUnlocked, memory_order_relaxed);
-}
-
-Mutex::~Mutex() {
- CHECK_EQ(atomic_load(&state_, memory_order_relaxed), kUnlocked);
-}
-
-void Mutex::Lock() {
-#if SANITIZER_DEBUG && !SANITIZER_GO
- cur_thread()->internal_deadlock_detector.Lock(type_);
-#endif
- uptr cmp = kUnlocked;
- if (atomic_compare_exchange_strong(&state_, &cmp, kWriteLock,
- memory_order_acquire))
- return;
- for (Backoff backoff; backoff.Do();) {
- if (atomic_load(&state_, memory_order_relaxed) == kUnlocked) {
- cmp = kUnlocked;
- if (atomic_compare_exchange_weak(&state_, &cmp, kWriteLock,
- memory_order_acquire)) {
- return;
- }
- }
- }
-}
-
-void Mutex::Unlock() {
- uptr prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release);
- (void)prev;
- DCHECK_NE(prev & kWriteLock, 0);
-#if SANITIZER_DEBUG && !SANITIZER_GO
- cur_thread()->internal_deadlock_detector.Unlock(type_);
-#endif
-}
-
-void Mutex::ReadLock() {
-#if SANITIZER_DEBUG && !SANITIZER_GO
- cur_thread()->internal_deadlock_detector.Lock(type_);
-#endif
- uptr prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire);
- if ((prev & kWriteLock) == 0)
- return;
- for (Backoff backoff; backoff.Do();) {
- prev = atomic_load(&state_, memory_order_acquire);
- if ((prev & kWriteLock) == 0) {
- return;
- }
- }
-}
-
-void Mutex::ReadUnlock() {
- uptr prev = atomic_fetch_sub(&state_, kReadLock, memory_order_release);
- (void)prev;
- DCHECK_EQ(prev & kWriteLock, 0);
- DCHECK_GT(prev & ~kWriteLock, 0);
-#if SANITIZER_DEBUG && !SANITIZER_GO
- cur_thread()->internal_deadlock_detector.Unlock(type_);
-#endif
-}
-
-void Mutex::CheckLocked() {
- CHECK_NE(atomic_load(&state_, memory_order_relaxed), 0);
-}
-
-} // namespace __tsan
diff --git a/compiler-rt/lib/tsan/rtl/tsan_mutex.h b/compiler-rt/lib/tsan/rtl/tsan_mutex.h
deleted file mode 100644
index 9a579eaf9144a..0000000000000
--- a/compiler-rt/lib/tsan/rtl/tsan_mutex.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- tsan_mutex.h --------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#ifndef TSAN_MUTEX_H
-#define TSAN_MUTEX_H
-
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "tsan_defs.h"
-
-namespace __tsan {
-
-enum MutexType {
- MutexTypeInvalid,
- MutexTypeTrace,
- MutexTypeThreads,
- MutexTypeReport,
- MutexTypeSyncVar,
- MutexTypeSyncTab,
- MutexTypeSlab,
- MutexTypeAnnotations,
- MutexTypeAtExit,
- MutexTypeMBlock,
- MutexTypeJavaMBlock,
- MutexTypeDDetector,
- MutexTypeFired,
- MutexTypeRacy,
- MutexTypeGlobalProc,
-
- // This must be the last.
- MutexTypeCount
-};
-
-class Mutex {
- public:
- explicit Mutex(MutexType type);
- ~Mutex();
-
- void Lock();
- void Unlock();
-
- void ReadLock();
- void ReadUnlock();
-
- void CheckLocked();
-
- private:
- atomic_uintptr_t state_;
-#if SANITIZER_DEBUG
- MutexType type_;
-#endif
-
- Mutex(const Mutex&);
- void operator = (const Mutex&);
-};
-
-typedef GenericScopedLock<Mutex> Lock;
-typedef GenericScopedReadLock<Mutex> ReadLock;
-
-class InternalDeadlockDetector {
- public:
- InternalDeadlockDetector();
- void Lock(MutexType t);
- void Unlock(MutexType t);
- void CheckNoLocks();
- private:
- u64 seq_;
- u64 locked_[MutexTypeCount];
-};
-
-void InitializeMutex();
-
-// Checks that the current thread does not hold any runtime locks
-// (e.g. when returning from an interceptor).
-void CheckNoLocks(ThreadState *thr);
-
-} // namespace __tsan
-
-#endif // TSAN_MUTEX_H
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index bcf489a71d55b..a21da9c81c6fc 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -422,7 +422,6 @@ void Initialize(ThreadState *thr) {
InitializeInterceptors();
CheckShadowMapping();
InitializePlatform();
- InitializeMutex();
InitializeDynamicAnnotations();
#if !SANITIZER_GO
InitializeShadowMemory();
@@ -1133,7 +1132,28 @@ void build_consistency_release() {}
} // namespace __tsan
+#if SANITIZER_CHECK_DEADLOCKS
+namespace __sanitizer {
+using namespace __tsan;
+MutexMeta mutex_meta[] = {
+ {MutexInvalid, "Invalid", {}},
+ {MutexThreadRegistry, "ThreadRegistry", {}},
+ {MutexTypeTrace, "Trace", {MutexLeaf}},
+ {MutexTypeReport, "Report", {MutexTypeSyncVar}},
+ {MutexTypeSyncVar, "SyncVar", {}},
+ {MutexTypeAnnotations, "Annotations", {}},
+ {MutexTypeAtExit, "AtExit", {MutexTypeSyncVar}},
+ {MutexTypeFired, "Fired", {MutexLeaf}},
+ {MutexTypeRacy, "Racy", {MutexLeaf}},
+ {MutexTypeGlobalProc, "GlobalProc", {}},
+ {},
+};
+
+void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); }
+} // namespace __sanitizer
+#endif
+
#if !SANITIZER_GO
// Must be included in this file to make sure everything is inlined.
-#include "tsan_interface_inl.h"
+# include "tsan_interface_inl.h"
#endif
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
index 26ee2a9e27549..3e809e653c704 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
@@ -129,7 +129,7 @@ bool ShouldReport(ThreadState *thr, ReportType typ) {
// We set thr->suppress_reports in the fork context.
// Taking any locking in the fork context can lead to deadlocks.
// If any locks are already taken, it's too late to do this check.
- CheckNoLocks(thr);
+ CheckedMutex::CheckNoLocks();
// For the same reason check we didn't lock thread_registry yet.
if (SANITIZER_DEBUG)
ThreadRegistryLock l(ctx->thread_registry);
@@ -596,7 +596,7 @@ static bool RaceBetweenAtomicAndFree(ThreadState *thr) {
}
void ReportRace(ThreadState *thr) {
- CheckNoLocks(thr);
+ CheckedMutex::CheckNoLocks();
// Symbolizer makes lots of intercepted calls. If we try to process them,
// at best it will cause deadlocks on internal mutexes.
diff --git a/compiler-rt/lib/tsan/rtl/tsan_sync.h b/compiler-rt/lib/tsan/rtl/tsan_sync.h
index c4056f684d7e8..324aa1b0cea16 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_sync.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_sync.h
@@ -17,7 +17,6 @@
#include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
#include "tsan_defs.h"
#include "tsan_clock.h"
-#include "tsan_mutex.h"
#include "tsan_dense_alloc.h"
namespace __tsan {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_trace.h b/compiler-rt/lib/tsan/rtl/tsan_trace.h
index 9f2677b778de5..f5e0c407cda86 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_trace.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_trace.h
@@ -13,7 +13,6 @@
#define TSAN_TRACE_H
#include "tsan_defs.h"
-#include "tsan_mutex.h"
#include "tsan_stack_trace.h"
#include "tsan_mutexset.h"
diff --git a/compiler-rt/lib/tsan/tests/unit/CMakeLists.txt b/compiler-rt/lib/tsan/tests/unit/CMakeLists.txt
index a2ada411db524..b52b451afb9ef 100644
--- a/compiler-rt/lib/tsan/tests/unit/CMakeLists.txt
+++ b/compiler-rt/lib/tsan/tests/unit/CMakeLists.txt
@@ -3,7 +3,6 @@ set(TSAN_UNIT_TEST_SOURCES
tsan_dense_alloc_test.cpp
tsan_flags_test.cpp
tsan_mman_test.cpp
- tsan_mutex_test.cpp
tsan_shadow_test.cpp
tsan_stack_test.cpp
tsan_sync_test.cpp
diff --git a/compiler-rt/lib/tsan/tests/unit/tsan_mutex_test.cpp b/compiler-rt/lib/tsan/tests/unit/tsan_mutex_test.cpp
deleted file mode 100644
index e9f4fba09d04f..0000000000000
--- a/compiler-rt/lib/tsan/tests/unit/tsan_mutex_test.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===-- tsan_mutex_test.cpp -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "tsan_mutex.h"
-#include "gtest/gtest.h"
-
-namespace __tsan {
-
-template<typename MutexType>
-class TestData {
- public:
- explicit TestData(MutexType *mtx)
- : mtx_(mtx) {
- for (int i = 0; i < kSize; i++)
- data_[i] = 0;
- }
-
- void Write() {
- Lock l(mtx_);
- T v0 = data_[0];
- for (int i = 0; i < kSize; i++) {
- CHECK_EQ(data_[i], v0);
- data_[i]++;
- }
- }
-
- void Read() {
- ReadLock l(mtx_);
- T v0 = data_[0];
- for (int i = 0; i < kSize; i++) {
- CHECK_EQ(data_[i], v0);
- }
- }
-
- void Backoff() {
- volatile T data[kSize] = {};
- for (int i = 0; i < kSize; i++) {
- data[i]++;
- CHECK_EQ(data[i], 1);
- }
- }
-
- private:
- typedef GenericScopedLock<MutexType> Lock;
- static const int kSize = 64;
- typedef u64 T;
- MutexType *mtx_;
- char pad_[kCacheLineSize];
- T data_[kSize];
-};
-
-const int kThreads = 8;
-const int kWriteRate = 1024;
-#if SANITIZER_DEBUG
-const int kIters = 16*1024;
-#else
-const int kIters = 64*1024;
-#endif
-
-template<typename MutexType>
-static void *write_mutex_thread(void *param) {
- TestData<MutexType> *data = (TestData<MutexType>*)param;
- for (int i = 0; i < kIters; i++) {
- data->Write();
- data->Backoff();
- }
- return 0;
-}
-
-template<typename MutexType>
-static void *read_mutex_thread(void *param) {
- TestData<MutexType> *data = (TestData<MutexType>*)param;
- for (int i = 0; i < kIters; i++) {
- if ((i % kWriteRate) == 0)
- data->Write();
- else
- data->Read();
- data->Backoff();
- }
- return 0;
-}
-
-TEST(Mutex, Write) {
- Mutex mtx(MutexTypeAnnotations);
- TestData<Mutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- pthread_create(&threads[i], 0, write_mutex_thread<Mutex>, &data);
- for (int i = 0; i < kThreads; i++)
- pthread_join(threads[i], 0);
-}
-
-TEST(Mutex, ReadWrite) {
- Mutex mtx(MutexTypeAnnotations);
- TestData<Mutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- pthread_create(&threads[i], 0, read_mutex_thread<Mutex>, &data);
- for (int i = 0; i < kThreads; i++)
- pthread_join(threads[i], 0);
-}
-
-TEST(Mutex, SpinWrite) {
- SpinMutex mtx;
- TestData<SpinMutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- pthread_create(&threads[i], 0, write_mutex_thread<SpinMutex>, &data);
- for (int i = 0; i < kThreads; i++)
- pthread_join(threads[i], 0);
-}
-
-} // namespace __tsan
More information about the llvm-commits
mailing list