summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/tsan/go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-04-27 12:30:48 +0000
committerDmitry Vyukov <dvyukov@google.com>2016-04-27 12:30:48 +0000
commit3efe395788e17f9be556b2570fb0cd9a1ae93796 (patch)
treee1e706b5b00c4b4018cd55b67b41a8739f702db8 /compiler-rt/lib/tsan/go
parent15cec298e64872b693430214980a822ee2044a5d (diff)
downloadbcm5719-llvm-3efe395788e17f9be556b2570fb0cd9a1ae93796.tar.gz
bcm5719-llvm-3efe395788e17f9be556b2570fb0cd9a1ae93796.zip
tsan: change tsan/Go interface for obtaining the current Processor
Current interface assumes that Go calls ProcWire/ProcUnwire to establish the association between thread and proc. With the wisdom of hindsight, this interface does not work very well. I had to sprinkle Go scheduler with wire/unwire calls, and any mistake leads to hard to debug crashes. This is not something one wants to maintian. Fortunately, there is a simpler solution. We can ask Go runtime as to what is the current Processor, and that question is very easy to answer on Go side. Switch to such interface. llvm-svn: 267703
Diffstat (limited to 'compiler-rt/lib/tsan/go')
-rw-r--r--compiler-rt/lib/tsan/go/test.c25
-rw-r--r--compiler-rt/lib/tsan/go/tsan_go.cc47
2 files changed, 40 insertions, 32 deletions
diff --git a/compiler-rt/lib/tsan/go/test.c b/compiler-rt/lib/tsan/go/test.c
index e59cca3ef96..51ccf29ead2 100644
--- a/compiler-rt/lib/tsan/go/test.c
+++ b/compiler-rt/lib/tsan/go/test.c
@@ -27,12 +27,21 @@ void __tsan_write(void *thr, void *addr, void *pc);
void __tsan_func_enter(void *thr, void *pc);
void __tsan_func_exit(void *thr);
void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz);
-void __tsan_free(void *proc, void *p, unsigned long sz);
+void __tsan_free(void *p, unsigned long sz);
void __tsan_acquire(void *thr, void *addr);
void __tsan_release(void *thr, void *addr);
void __tsan_release_merge(void *thr, void *addr);
-void symbolize_cb(long cmd, void *ctx) {}
+void *current_proc;
+
+void symbolize_cb(long cmd, void *ctx) {
+ switch (cmd) {
+ case 0:
+ if (current_proc == 0)
+ abort();
+ *(void**)ctx = current_proc;
+ }
+}
char buf0[100<<10];
@@ -43,11 +52,11 @@ int main(void) {
void *thr0 = 0;
void *proc0 = 0;
__tsan_init(&thr0, &proc0, symbolize_cb);
+ current_proc = proc0;
char *buf = (char*)((unsigned long)buf0 + (64<<10) - 1 & ~((64<<10) - 1));
__tsan_map_shadow(buf, 4096);
__tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
- __tsan_free(proc0, buf, 10);
- __tsan_free(thr0, buf, 10);
+ __tsan_free(buf, 10);
__tsan_func_enter(thr0, (char*)&main + 1);
__tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
__tsan_release(thr0, buf);
@@ -57,8 +66,6 @@ int main(void) {
void *thr2 = 0;
__tsan_go_start(thr0, &thr2, (char*)&barfoo + 1);
__tsan_func_exit(thr0);
- __tsan_proc_unwire(proc0, thr0);
- __tsan_proc_wire(proc0, thr1);
__tsan_func_enter(thr1, (char*)&foobar + 1);
__tsan_func_enter(thr1, (char*)&foobar + 1);
__tsan_write(thr1, buf, (char*)&barfoo + 1);
@@ -68,14 +75,14 @@ int main(void) {
__tsan_go_end(thr1);
void *proc1 = 0;
__tsan_proc_create(&proc1);
- __tsan_proc_wire(proc1, thr2);
+ current_proc = proc1;
__tsan_func_enter(thr2, (char*)&foobar + 1);
__tsan_read(thr2, buf, (char*)&barfoo + 1);
- __tsan_free(proc1, buf, 10);
+ __tsan_free(buf, 10);
__tsan_func_exit(thr2);
__tsan_go_end(thr2);
- __tsan_proc_destroy(proc0);
__tsan_proc_destroy(proc1);
+ current_proc = proc0;
__tsan_fini();
return 0;
}
diff --git a/compiler-rt/lib/tsan/go/tsan_go.cc b/compiler-rt/lib/tsan/go/tsan_go.cc
index 390c1b48a71..bc0d5530433 100644
--- a/compiler-rt/lib/tsan/go/tsan_go.cc
+++ b/compiler-rt/lib/tsan/go/tsan_go.cc
@@ -40,8 +40,9 @@ void internal_free(void *p) {
static void (*go_runtime_cb)(uptr cmd, void *ctx);
enum {
- CallbackSymbolizeCode = 0,
- CallbackSymbolizeData = 1,
+ CallbackGetProc = 0,
+ CallbackSymbolizeCode = 1,
+ CallbackSymbolizeData = 2,
};
struct SymbolizeCodeContext {
@@ -109,11 +110,27 @@ ReportLocation *SymbolizeData(uptr addr) {
}
}
-extern "C" {
-
static ThreadState *main_thr;
static bool inited;
+static Processor* get_cur_proc() {
+ if (UNLIKELY(!inited)) {
+ // Running Initialize().
+ // We have not yet returned the Processor to Go, so we cannot ask it back.
+ // Currently, Initialize() does not use the Processor, so return nullptr.
+ return nullptr;
+ }
+ Processor *proc;
+ go_runtime_cb(CallbackGetProc, &proc);
+ return proc;
+}
+
+Processor *ThreadState::proc() {
+ return get_cur_proc();
+}
+
+extern "C" {
+
static ThreadState *AllocGoroutine() {
ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex,
sizeof(ThreadState));
@@ -127,7 +144,7 @@ void __tsan_init(ThreadState **thrp, Processor **procp,
ThreadState *thr = AllocGoroutine();
main_thr = *thrp = thr;
Initialize(thr);
- *procp = thr->proc;
+ *procp = thr->proc1;
inited = true;
}
@@ -189,27 +206,19 @@ void __tsan_malloc(ThreadState *thr, uptr pc, uptr p, uptr sz) {
MemoryResetRange(0, 0, (uptr)p, sz);
}
-void __tsan_free(Processor *proc, uptr p, uptr sz) {
- ctx->metamap.FreeRange(proc, p, sz);
+void __tsan_free(uptr p, uptr sz) {
+ ctx->metamap.FreeRange(get_cur_proc(), p, sz);
}
void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) {
ThreadState *thr = AllocGoroutine();
*pthr = thr;
int goid = ThreadCreate(parent, (uptr)pc, 0, true);
- Processor *proc = parent->proc;
- // Temporary borrow proc to handle goroutine start.
- ProcUnwire(proc, parent);
- ProcWire(proc, thr);
ThreadStart(thr, goid, 0);
- ProcUnwire(proc, thr);
- ProcWire(proc, parent);
}
void __tsan_go_end(ThreadState *thr) {
- Processor *proc = thr->proc;
ThreadFinish(thr);
- ProcUnwire(proc, thr);
internal_free(thr);
}
@@ -221,14 +230,6 @@ void __tsan_proc_destroy(Processor *proc) {
ProcDestroy(proc);
}
-void __tsan_proc_wire(Processor *proc, ThreadState *thr) {
- ProcWire(proc, thr);
-}
-
-void __tsan_proc_unwire(Processor *proc, ThreadState *thr) {
- ProcUnwire(proc, thr);
-}
-
void __tsan_acquire(ThreadState *thr, void *addr) {
Acquire(thr, 0, (uptr)addr);
}
OpenPOWER on IntegriCloud