diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2013-01-31 07:48:43 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2013-01-31 07:48:43 +0000 |
commit | 6faa20f2441cd845d98cb390ae2bacca908537ee (patch) | |
tree | 6cffadd0cf8c22460366a038b9ed5e80a8f705f9 /lib/tsan/go | |
parent | 6bd82d398b0c1e66f957a8553a912c5aa54b9639 (diff) | |
download | compiler-rt-6faa20f2441cd845d98cb390ae2bacca908537ee.tar.gz compiler-rt-6faa20f2441cd845d98cb390ae2bacca908537ee.tar.bz2 compiler-rt-6faa20f2441cd845d98cb390ae2bacca908537ee.tar.xz |
tsan: switch to explicit thread contexts in Go (instead of monotonic goroutine ids)
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@174047 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/go')
-rw-r--r-- | lib/tsan/go/test.c | 46 | ||||
-rw-r--r-- | lib/tsan/go/tsan_go.cc | 74 |
2 files changed, 51 insertions, 69 deletions
diff --git a/lib/tsan/go/test.c b/lib/tsan/go/test.c index 2414a1e9..902dfc91 100644 --- a/lib/tsan/go/test.c +++ b/lib/tsan/go/test.c @@ -13,20 +13,20 @@ #include <stdio.h> -void __tsan_init(); +void __tsan_init(void **thr); void __tsan_fini(); void __tsan_map_shadow(void *addr, unsigned long size); -void __tsan_go_start(int pgoid, int chgoid, void *pc); -void __tsan_go_end(int goid); -void __tsan_read(int goid, void *addr, void *pc); -void __tsan_write(int goid, void *addr, void *pc); -void __tsan_func_enter(int goid, void *pc); -void __tsan_func_exit(int goid); -void __tsan_malloc(int goid, void *p, unsigned long sz, void *pc); +void __tsan_go_start(void *thr, void **chthr, void *pc); +void __tsan_go_end(void *thr); +void __tsan_read(void *thr, void *addr, void *pc); +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 *p, unsigned long sz, void *pc); void __tsan_free(void *p); -void __tsan_acquire(int goid, void *addr); -void __tsan_release(int goid, void *addr); -void __tsan_release_merge(int goid, void *addr); +void __tsan_acquire(void *thr, void *addr); +void __tsan_release(void *thr, void *addr); +void __tsan_release_merge(void *thr, void *addr); int __tsan_symbolize(void *pc, char **img, char **rtn, char **file, int *l) { return 0; @@ -35,19 +35,21 @@ int __tsan_symbolize(void *pc, char **img, char **rtn, char **file, int *l) { char buf[10]; int main(void) { - __tsan_init(); + void *thr0 = 0; + __tsan_init(&thr0); __tsan_map_shadow(buf, sizeof(buf) + 4096); - __tsan_func_enter(0, &main); - __tsan_malloc(0, buf, 10, 0); - __tsan_release(0, buf); - __tsan_release_merge(0, buf); - __tsan_go_start(0, 1, 0); - __tsan_write(1, buf, 0); - __tsan_acquire(1, buf); - __tsan_go_end(1); - __tsan_read(0, buf, 0); + __tsan_func_enter(thr0, &main); + __tsan_malloc(thr0, buf, 10, 0); + __tsan_release(thr0, buf); + __tsan_release_merge(thr0, buf); + void *thr1 = 0; + __tsan_go_start(thr0, &thr1, 0); + __tsan_write(thr1, buf, 0); + __tsan_acquire(thr1, buf); + __tsan_go_end(thr1); + __tsan_read(thr0, buf, 0); __tsan_free(buf); - __tsan_func_exit(0); + __tsan_func_exit(thr0); __tsan_fini(); return 0; } diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cc index 360608a0..77f600b8 100644 --- a/lib/tsan/go/tsan_go.cc +++ b/lib/tsan/go/tsan_go.cc @@ -18,10 +18,6 @@ namespace __tsan { -const int kMaxGoroutinesEver = 128*1024; - -static ThreadState *goroutines[kMaxGoroutinesEver]; - void InitializeInterceptors() { } @@ -80,20 +76,18 @@ ReportStack *SymbolizeCode(uptr addr) { extern "C" { -static void AllocGoroutine(int tid) { - if (tid >= kMaxGoroutinesEver) { - Printf("FATAL: Reached goroutine limit\n"); - Die(); - } +static ThreadState *main_thr; + +static ThreadState *AllocGoroutine() { ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex, sizeof(ThreadState)); internal_memset(thr, 0, sizeof(*thr)); - goroutines[tid] = thr; + return thr; } -void __tsan_init() { - AllocGoroutine(0); - ThreadState *thr = goroutines[0]; +void __tsan_init(ThreadState **thrp) { + ThreadState *thr = AllocGoroutine(); + main_thr = *thrp = thr; thr->in_rtl++; Initialize(thr); thr->in_rtl--; @@ -101,7 +95,7 @@ void __tsan_init() { void __tsan_fini() { // FIXME: Not necessary thread 0. - ThreadState *thr = goroutines[0]; + ThreadState *thr = main_thr; thr->in_rtl++; int res = Finalize(thr); thr->in_rtl--; @@ -112,40 +106,35 @@ void __tsan_map_shadow(uptr addr, uptr size) { MapShadow(addr, size); } -void __tsan_read(int goid, void *addr, void *pc) { - ThreadState *thr = goroutines[goid]; +void __tsan_read(ThreadState *thr, void *addr, void *pc) { MemoryAccess(thr, (uptr)pc, (uptr)addr, 0, false); } -void __tsan_write(int goid, void *addr, void *pc) { - ThreadState *thr = goroutines[goid]; +void __tsan_write(ThreadState *thr, void *addr, void *pc) { MemoryAccess(thr, (uptr)pc, (uptr)addr, 0, true); } -void __tsan_read_range(int goid, void *addr, uptr size, uptr step, void *pc) { - ThreadState *thr = goroutines[goid]; +void __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr step, + void *pc) { for (uptr i = 0; i < size; i += step) MemoryAccess(thr, (uptr)pc, (uptr)addr + i, 0, false); } -void __tsan_write_range(int goid, void *addr, uptr size, uptr step, void *pc) { - ThreadState *thr = goroutines[goid]; +void __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr step, + void *pc) { for (uptr i = 0; i < size; i += step) MemoryAccess(thr, (uptr)pc, (uptr)addr + i, 0, true); } -void __tsan_func_enter(int goid, void *pc) { - ThreadState *thr = goroutines[goid]; +void __tsan_func_enter(ThreadState *thr, void *pc) { FuncEntry(thr, (uptr)pc); } -void __tsan_func_exit(int goid) { - ThreadState *thr = goroutines[goid]; +void __tsan_func_exit(ThreadState *thr) { FuncExit(thr); } -void __tsan_malloc(int goid, void *p, uptr sz, void *pc) { - ThreadState *thr = goroutines[goid]; +void __tsan_malloc(ThreadState *thr, void *p, uptr sz, void *pc) { if (thr == 0) // probably before __tsan_init() return; thr->in_rtl++; @@ -157,52 +146,43 @@ void __tsan_free(void *p) { (void)p; } -void __tsan_go_start(int pgoid, int chgoid, void *pc) { - if (chgoid == 0) - return; - AllocGoroutine(chgoid); - ThreadState *thr = goroutines[chgoid]; - ThreadState *parent = goroutines[pgoid]; +void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) { + ThreadState *thr = AllocGoroutine(); + *pthr = thr; thr->in_rtl++; parent->in_rtl++; - int goid2 = ThreadCreate(parent, (uptr)pc, 0, true); - ThreadStart(thr, goid2, 0); + int goid = ThreadCreate(parent, (uptr)pc, 0, true); + ThreadStart(thr, goid, 0); parent->in_rtl--; thr->in_rtl--; } -void __tsan_go_end(int goid) { - ThreadState *thr = goroutines[goid]; +void __tsan_go_end(ThreadState *thr) { thr->in_rtl++; ThreadFinish(thr); thr->in_rtl--; internal_free(thr); - goroutines[goid] = 0; } -void __tsan_acquire(int goid, void *addr) { - ThreadState *thr = goroutines[goid]; +void __tsan_acquire(ThreadState *thr, void *addr) { thr->in_rtl++; Acquire(thr, 0, (uptr)addr); thr->in_rtl--; } -void __tsan_release(int goid, void *addr) { - ThreadState *thr = goroutines[goid]; +void __tsan_release(ThreadState *thr, void *addr) { thr->in_rtl++; ReleaseStore(thr, 0, (uptr)addr); thr->in_rtl--; } -void __tsan_release_merge(int goid, void *addr) { - ThreadState *thr = goroutines[goid]; +void __tsan_release_merge(ThreadState *thr, void *addr) { thr->in_rtl++; Release(thr, 0, (uptr)addr); thr->in_rtl--; } -void __tsan_finalizer_goroutine(int goid) { - ThreadState *thr = goroutines[goid]; +void __tsan_finalizer_goroutine(ThreadState *thr) { AcquireGlobal(thr, 0); } |