[compiler-rt] r316209 - [tsan] Add Mutex annotation flag for constant-initialized __tsan_mutex_linker_init behavior
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 20 05:08:53 PDT 2017
Author: dvyukov
Date: Fri Oct 20 05:08:53 2017
New Revision: 316209
URL: http://llvm.org/viewvc/llvm-project?rev=316209&view=rev
Log:
[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
Modified:
compiler-rt/trunk/include/sanitizer/tsan_interface.h
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
compiler-rt/trunk/test/tsan/custom_mutex.h
Modified: compiler-rt/trunk/include/sanitizer/tsan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/tsan_interface.h?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/tsan_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/tsan_interface.h Fri Oct 20 05:08:53 2017
@@ -44,6 +44,11 @@ const unsigned __tsan_mutex_linker_init
const unsigned __tsan_mutex_write_reentrant = 1 << 1;
// Mutex is read reentrant.
const unsigned __tsan_mutex_read_reentrant = 1 << 2;
+// Mutex does not have static storage duration, and must not be used after
+// its destructor runs. The opposite of __tsan_mutex_linker_init.
+// If this flag is passed to __tsan_mutex_destroy, then the destruction
+// is ignored unless this flag was previously set on the mutex.
+const unsigned __tsan_mutex_not_static = 1 << 8;
// Mutex operation flags:
@@ -70,6 +75,7 @@ void __tsan_mutex_create(void *addr, uns
// Annotate destruction of a mutex.
// Supported flags:
// - __tsan_mutex_linker_init
+// - __tsan_mutex_not_static
void __tsan_mutex_destroy(void *addr, unsigned flags);
// Annotate start of lock operation.
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Oct 20 05:08:53 2017
@@ -84,7 +84,9 @@ void MutexDestroy(ThreadState *thr, uptr
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;
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h Fri Oct 20 05:08:53 2017
@@ -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 {
Modified: compiler-rt/trunk/test/tsan/custom_mutex.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/custom_mutex.h?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/test/tsan/custom_mutex.h (original)
+++ compiler-rt/trunk/test/tsan/custom_mutex.h Fri Oct 20 05:08:53 2017
@@ -6,15 +6,16 @@
// A very primitive mutex annotated with tsan annotations.
class Mutex {
public:
- Mutex(bool prof, unsigned flags)
+ Mutex(bool prof, unsigned create_flags, unsigned destroy_flags=0)
: prof_(prof)
, locked_(false)
- , seq_(0) {
- __tsan_mutex_create(this, flags);
+ , seq_(0)
+ , destroy_flags_(destroy_flags) {
+ __tsan_mutex_create(this, create_flags);
}
~Mutex() {
- __tsan_mutex_destroy(this, 0);
+ __tsan_mutex_destroy(this, destroy_flags_);
}
void Lock() {
@@ -57,6 +58,7 @@ class Mutex {
const bool prof_;
std::atomic<bool> locked_;
int seq_;
+ unsigned destroy_flags_;
// This models mutex profiling subsystem.
static Mutex prof_mu_;
More information about the llvm-commits
mailing list