From 7bf9ee041a3e2ea1e12bc5336c20ca9538e56c11 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 12 Jul 2017 12:28:23 +0000 Subject: [PATCH] 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. llvm-svn: 307778 --- compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc b/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc index b22d5c1..d334394 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc @@ -220,8 +220,7 @@ static a128 NoTsanAtomicLoad(const volatile a128 *a, morder mo) { #endif template -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()); 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()); return v; } -- 2.7.4