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