[llvm-commits] [compiler-rt] r170891 - in /compiler-rt/trunk/lib/tsan: lit_tests/java_lock_move.cc rtl/tsan_interface_java.cc rtl/tsan_sync.h
Dmitry Vyukov
dvyukov at google.com
Fri Dec 21 05:23:48 PST 2012
Author: dvyukov
Date: Fri Dec 21 07:23:48 2012
New Revision: 170891
URL: http://llvm.org/viewvc/llvm-project?rev=170891&view=rev
Log:
tsan: fix Java memory move operations and add the test
Added:
compiler-rt/trunk/lib/tsan/lit_tests/java_lock_move.cc
Modified:
compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
Added: compiler-rt/trunk/lib/tsan/lit_tests/java_lock_move.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/java_lock_move.cc?rev=170891&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/lit_tests/java_lock_move.cc (added)
+++ compiler-rt/trunk/lib/tsan/lit_tests/java_lock_move.cc Fri Dec 21 07:23:48 2012
@@ -0,0 +1,54 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern "C" {
+typedef unsigned long jptr; // NOLINT
+void __tsan_java_init(jptr heap_begin, jptr heap_size);
+int __tsan_java_fini();
+void __tsan_java_alloc(jptr ptr, jptr size);
+void __tsan_java_free(jptr ptr, jptr size);
+void __tsan_java_move(jptr src, jptr dst, jptr size);
+void __tsan_java_mutex_lock(jptr addr);
+void __tsan_java_mutex_unlock(jptr addr);
+void __tsan_java_mutex_read_lock(jptr addr);
+void __tsan_java_mutex_read_unlock(jptr addr);
+}
+
+jptr varaddr;
+jptr lockaddr;
+jptr varaddr2;
+jptr lockaddr2;
+
+void *Thread(void *p) {
+ sleep(1);
+ __tsan_java_mutex_lock(lockaddr2);
+ *(int*)varaddr2 = 42;
+ __tsan_java_mutex_unlock(lockaddr2);
+ return 0;
+}
+
+int main() {
+ int const kHeapSize = 1024 * 1024;
+ void *jheap = malloc(kHeapSize);
+ __tsan_java_init((jptr)jheap, kHeapSize);
+ const int kBlockSize = 64;
+ int const kMove = 1024;
+ __tsan_java_alloc((jptr)jheap, kBlockSize);
+ varaddr = (jptr)jheap;
+ lockaddr = (jptr)jheap + 46;
+ varaddr2 = varaddr + kMove;
+ lockaddr2 = lockaddr + kMove;
+ pthread_t th;
+ pthread_create(&th, 0, Thread, 0);
+ __tsan_java_mutex_lock(lockaddr);
+ *(int*)varaddr = 43;
+ __tsan_java_mutex_unlock(lockaddr);
+ __tsan_java_move(varaddr, varaddr2, kBlockSize);
+ pthread_join(th, 0);
+ __tsan_java_free(varaddr2, kBlockSize);
+ return __tsan_java_fini();
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc?rev=170891&r1=170890&r2=170891&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interface_java.cc Fri Dec 21 07:23:48 2012
@@ -37,14 +37,6 @@
begin = true;
}
- explicit BlockDesc(BlockDesc *b)
- : mtx(MutexTypeJavaMBlock, StatMtxJavaMBlock)
- , head(b->head) {
- CHECK_EQ(begin, false);
- begin = true;
- b->head = 0;
- }
-
~BlockDesc() {
CHECK_EQ(begin, true);
begin = false;
@@ -108,6 +100,14 @@
return &jctx->heap_shadow[i];
}
+static uptr USED getmem(BlockDesc *b) {
+ uptr i = b - jctx->heap_shadow;
+ uptr p = jctx->heap_begin + i * kHeapAlignment;
+ CHECK_GE(p, jctx->heap_begin);
+ CHECK_LT(p, jctx->heap_begin + jctx->heap_size);
+ return p;
+}
+
static BlockDesc *getblockbegin(uptr addr) {
for (BlockDesc *b = getblock(addr);; b--) {
CHECK_GE(b, jctx->heap_shadow);
@@ -123,13 +123,17 @@
|| addr >= jctx->heap_begin + jctx->heap_size)
return 0;
BlockDesc *b = getblockbegin(addr);
+ DPrintf("#%d: GetJavaSync %p->%p\n", thr->tid, addr, b);
Lock l(&b->mtx);
SyncVar *s = b->head;
for (; s; s = s->next) {
- if (s->addr == addr)
+ if (s->addr == addr) {
+ DPrintf("#%d: found existing sync for %p\n", thr->tid, addr);
break;
+ }
}
if (s == 0 && create) {
+ DPrintf("#%d: creating new sync for %p\n", thr->tid, addr);
s = CTX()->synctab.Create(thr, pc, addr);
s->next = b->head;
b->head = s;
@@ -233,8 +237,17 @@
BlockDesc *d = getblock(dst);
BlockDesc *send = getblock(src + size);
for (; s != send; s++, d++) {
+ CHECK_EQ(d->begin, false);
if (s->begin) {
- new(d) BlockDesc(s);
+ DPrintf("#%d: moving block %p->%p\n", thr->tid, getmem(s), getmem(d));
+ new(d) BlockDesc;
+ d->head = s->head;
+ for (SyncVar *sync = d->head; sync; sync = sync->next) {
+ uptr newaddr = sync->addr - src + dst;
+ DPrintf("#%d: moving sync %p->%p\n", thr->tid, sync->addr, newaddr);
+ sync->addr = newaddr;
+ }
+ s->head = 0;
s->~BlockDesc();
}
}
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h?rev=170891&r1=170890&r2=170891&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h Fri Dec 21 07:23:48 2012
@@ -55,7 +55,7 @@
static const int kInvalidTid = -1;
Mutex mtx;
- const uptr addr;
+ uptr addr;
const u64 uid; // Globally unique id.
SyncClock clock;
SyncClock read_clock; // Used for rw mutexes only.
More information about the llvm-commits
mailing list