diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2012-08-15 17:27:20 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2012-08-15 17:27:20 +0000 |
commit | 9bbc579e11900741551b81b5e91d22ca47d70b26 (patch) | |
tree | 4af5dc08244ac32e188cee9eef2a6dfe1a59e4cc /lib/tsan/rtl/tsan_sync.cc | |
parent | 26af89330051837bab68dcf25cf669c194b4e310 (diff) |
tsan: store sync objects in memory block headers + delete them when the block is freed
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@161959 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl/tsan_sync.cc')
-rw-r--r-- | lib/tsan/rtl/tsan_sync.cc | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/tsan/rtl/tsan_sync.cc b/lib/tsan/rtl/tsan_sync.cc index abb5a2ad2..2f8e785c1 100644 --- a/lib/tsan/rtl/tsan_sync.cc +++ b/lib/tsan/rtl/tsan_sync.cc @@ -47,6 +47,31 @@ SyncTab::~SyncTab() { SyncVar* SyncTab::GetAndLock(ThreadState *thr, uptr pc, uptr addr, bool write_lock) { +#ifndef TSAN_GO + if (PrimaryAllocator::PointerIsMine((void*)addr)) { + MBlock *b = user_mblock(thr, (void*)addr); + Lock l(&b->mtx); + SyncVar *res = 0; + for (res = b->head; res; res = res->next) { + if (res->addr == addr) + break; + } + if (res == 0) { + StatInc(thr, StatSyncCreated); + void *mem = internal_alloc(MBlockSync, sizeof(SyncVar)); + res = new(mem) SyncVar(addr); + res->creation_stack.ObtainCurrent(thr, pc); + res->next = b->head; + b->head = res; + } + if (write_lock) + res->mtx.Lock(); + else + res->mtx.ReadLock(); + return res; + } +#endif + Part *p = &tab_[PartIdx(addr)]; { ReadLock l(&p->mtx); @@ -86,6 +111,32 @@ SyncVar* SyncTab::GetAndLock(ThreadState *thr, uptr pc, } SyncVar* SyncTab::GetAndRemove(ThreadState *thr, uptr pc, uptr addr) { +#ifndef TSAN_GO + if (PrimaryAllocator::PointerIsMine((void*)addr)) { + MBlock *b = user_mblock(thr, (void*)addr); + SyncVar *res = 0; + { + Lock l(&b->mtx); + SyncVar **prev = &b->head; + res = *prev; + while (res) { + if (res->addr == addr) { + *prev = res->next; + break; + } + prev = &res->next; + res = *prev; + } + } + if (res) { + StatInc(thr, StatSyncDestroyed); + res->mtx.Lock(); + res->mtx.Unlock(); + } + return res; + } +#endif + Part *p = &tab_[PartIdx(addr)]; SyncVar *res = 0; { |