diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2017-07-12 12:28:23 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2017-07-12 12:28:23 +0000 |
commit | 5de8108ffc5363bc87abe057ba65b4a3fb0c1801 (patch) | |
tree | 610dd83175c20312ff8c18243e9970e8960c22df | |
parent | 38ecb5de33e6ce0e9a2d60f3571e268801eda8b3 (diff) | |
download | compiler-rt-5de8108ffc5363bc87abe057ba65b4a3fb0c1801.tar.gz |
tsan: don't create sync objects on acquire-load
Don't create sync object if it does not exist yet. For example, an atomic
pointer is initialized to nullptr and then periodically acquire-loaded.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@307778 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/tsan/rtl/tsan_interface_atomic.cc | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/lib/tsan/rtl/tsan_interface_atomic.cc b/lib/tsan/rtl/tsan_interface_atomic.cc index b22d5c1ec..d334394f5 100644 --- a/lib/tsan/rtl/tsan_interface_atomic.cc +++ b/lib/tsan/rtl/tsan_interface_atomic.cc @@ -220,8 +220,7 @@ static a128 NoTsanAtomicLoad(const volatile a128 *a, morder mo) { #endif template<typename T> -static T AtomicLoad(ThreadState *thr, uptr pc, const volatile T *a, - morder mo) { +static T AtomicLoad(ThreadState *thr, uptr pc, const volatile T *a, morder mo) { CHECK(IsLoadOrder(mo)); // This fast-path is critical for performance. // Assume the access is atomic. @@ -229,10 +228,17 @@ static T AtomicLoad(ThreadState *thr, uptr pc, const volatile T *a, MemoryReadAtomic(thr, pc, (uptr)a, SizeLog<T>()); return NoTsanAtomicLoad(a, mo); } - SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, (uptr)a, false); - AcquireImpl(thr, pc, &s->clock); + // Don't create sync object if it does not exist yet. For example, an atomic + // pointer is initialized to nullptr and then periodically acquire-loaded. T v = NoTsanAtomicLoad(a, mo); - s->mtx.ReadUnlock(); + SyncVar *s = ctx->metamap.GetIfExistsAndLock((uptr)a, false); + if (s) { + AcquireImpl(thr, pc, &s->clock); + // Re-read under sync mutex because we need a consistent snapshot + // of the value and the clock we acquire. + v = NoTsanAtomicLoad(a, mo); + s->mtx.ReadUnlock(); + } MemoryReadAtomic(thr, pc, (uptr)a, SizeLog<T>()); return v; } |