summaryrefslogtreecommitdiff
path: root/lib/tsan/rtl/tsan_sync.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2012-08-15 17:27:20 +0000
committerDmitry Vyukov <dvyukov@google.com>2012-08-15 17:27:20 +0000
commit9bbc579e11900741551b81b5e91d22ca47d70b26 (patch)
tree4af5dc08244ac32e188cee9eef2a6dfe1a59e4cc /lib/tsan/rtl/tsan_sync.cc
parent26af89330051837bab68dcf25cf669c194b4e310 (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.cc51
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;
{