tsan: do not allocate sync vars on relaxed atomic operations

helps to reduce memory consumption if an atomic is used only with relaxed ops (stats)

llvm-svn: 177381
This commit is contained in:
Dmitry Vyukov 2013-03-19 09:15:31 +00:00
parent 227eb6fc5f
commit b59fa875ad
1 changed files with 26 additions and 18 deletions

View File

@ -290,7 +290,9 @@ static void AtomicStore(ThreadState *thr, uptr pc, volatile T *a, T v,
template<typename T, T (*F)(volatile T *v, T op)> template<typename T, T (*F)(volatile T *v, T op)>
static T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) { static T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) {
MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>()); MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());
SyncVar *s = CTX()->synctab.GetOrCreateAndLock(thr, pc, (uptr)a, true); SyncVar *s = 0;
if (mo != mo_relaxed) {
s = CTX()->synctab.GetOrCreateAndLock(thr, pc, (uptr)a, true);
thr->clock.set(thr->tid, thr->fast_state.epoch()); thr->clock.set(thr->tid, thr->fast_state.epoch());
if (IsAcqRelOrder(mo)) if (IsAcqRelOrder(mo))
thr->clock.acq_rel(&s->clock); thr->clock.acq_rel(&s->clock);
@ -298,7 +300,9 @@ static T AtomicRMW(ThreadState *thr, uptr pc, volatile T *a, T v, morder mo) {
thr->clock.release(&s->clock); thr->clock.release(&s->clock);
else if (IsAcquireOrder(mo)) else if (IsAcquireOrder(mo))
thr->clock.acquire(&s->clock); thr->clock.acquire(&s->clock);
}
v = F(a, v); v = F(a, v);
if (s)
s->mtx.Unlock(); s->mtx.Unlock();
return v; return v;
} }
@ -350,7 +354,9 @@ static bool AtomicCAS(ThreadState *thr, uptr pc,
volatile T *a, T *c, T v, morder mo, morder fmo) { volatile T *a, T *c, T v, morder mo, morder fmo) {
(void)fmo; // Unused because llvm does not pass it yet. (void)fmo; // Unused because llvm does not pass it yet.
MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>()); MemoryWriteAtomic(thr, pc, (uptr)a, SizeLog<T>());
SyncVar *s = CTX()->synctab.GetOrCreateAndLock(thr, pc, (uptr)a, true); SyncVar *s = 0;
if (mo != mo_relaxed) {
s = CTX()->synctab.GetOrCreateAndLock(thr, pc, (uptr)a, true);
thr->clock.set(thr->tid, thr->fast_state.epoch()); thr->clock.set(thr->tid, thr->fast_state.epoch());
if (IsAcqRelOrder(mo)) if (IsAcqRelOrder(mo))
thr->clock.acq_rel(&s->clock); thr->clock.acq_rel(&s->clock);
@ -358,8 +364,10 @@ static bool AtomicCAS(ThreadState *thr, uptr pc,
thr->clock.release(&s->clock); thr->clock.release(&s->clock);
else if (IsAcquireOrder(mo)) else if (IsAcquireOrder(mo))
thr->clock.acquire(&s->clock); thr->clock.acquire(&s->clock);
}
T cc = *c; T cc = *c;
T pr = func_cas(a, cc, v); T pr = func_cas(a, cc, v);
if (s)
s->mtx.Unlock(); s->mtx.Unlock();
if (pr == cc) if (pr == cc)
return true; return true;