summaryrefslogtreecommitdiff
path: root/lib/tsan/rtl
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-10-20 12:08:53 +0000
committerDmitry Vyukov <dvyukov@google.com>2017-10-20 12:08:53 +0000
commit87a6e96366be745ed2a37c772b9bd24387134b72 (patch)
treebf12bd9f1da79596e80ed652cb51e0eaf7a4e865 /lib/tsan/rtl
parent98adaa2097783c0fe3a4c948397e3f2182dcc5d2 (diff)
[tsan] Add Mutex annotation flag for constant-initialized __tsan_mutex_linker_init behavior
Add a new flag, _⁠_tsan_mutex_not_static, which has the opposite sense of _⁠_tsan_mutex_linker_init. When the new _⁠_tsan_mutex_not_static flag is passed to _⁠_tsan_mutex_destroy, tsan ignores the destruction unless the mutex was also created with the _⁠_tsan_mutex_not_static flag. This is useful for constructors that otherwise woud set _⁠_tsan_mutex_linker_init but cannot, because they are declared constexpr. Google has a custom mutex with two constructors, a "linker initialized" constructor that relies on zero-initialization and sets ⁠_⁠_tsan_mutex_linker_init, and a normal one which sets no tsan flags. The "linker initialized" constructor is morally constexpr, but we can't declare it constexpr because of the need to call into tsan as a side effect. With this new flag, the normal c'tor can set _⁠_tsan_mutex_not_static, the "linker initialized" constructor can rely on tsan's lazy initialization, and _⁠_tsan_mutex_destroy can still handle both cases correctly. Author: Greg Falcon (gfalcon) Reviewed in: https://reviews.llvm.org/D39095 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316209 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl')
-rw-r--r--lib/tsan/rtl/tsan_rtl_mutex.cc4
-rw-r--r--lib/tsan/rtl/tsan_sync.h4
2 files changed, 6 insertions, 2 deletions
diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cc
index 2f8581162..152b965ad 100644
--- a/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/lib/tsan/rtl/tsan_rtl_mutex.cc
@@ -84,7 +84,9 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) {
SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr, true);
if (s == 0)
return;
- if ((flagz & MutexFlagLinkerInit) || s->IsFlagSet(MutexFlagLinkerInit)) {
+ if ((flagz & MutexFlagLinkerInit)
+ || s->IsFlagSet(MutexFlagLinkerInit)
+ || ((flagz & MutexFlagNotStatic) && !s->IsFlagSet(MutexFlagNotStatic))) {
// Destroy is no-op for linker-initialized mutexes.
s->mtx.Unlock();
return;
diff --git a/lib/tsan/rtl/tsan_sync.h b/lib/tsan/rtl/tsan_sync.h
index b83c09ff7..9039970bc 100644
--- a/lib/tsan/rtl/tsan_sync.h
+++ b/lib/tsan/rtl/tsan_sync.h
@@ -34,6 +34,7 @@ enum MutexFlags {
MutexFlagTryLockFailed = 1 << 5, // __tsan_mutex_try_lock_failed
MutexFlagRecursiveLock = 1 << 6, // __tsan_mutex_recursive_lock
MutexFlagRecursiveUnlock = 1 << 7, // __tsan_mutex_recursive_unlock
+ MutexFlagNotStatic = 1 << 8, // __tsan_mutex_not_static
// The following flags are runtime private.
// Mutex API misuse was detected, so don't report any more.
@@ -43,7 +44,8 @@ enum MutexFlags {
// Must list all mutex creation flags.
MutexCreationFlagMask = MutexFlagLinkerInit |
MutexFlagWriteReentrant |
- MutexFlagReadReentrant,
+ MutexFlagReadReentrant |
+ MutexFlagNotStatic,
};
struct SyncVar {