diff options
Diffstat (limited to 'lib/tsan/go/tsan_go.cc')
-rw-r--r-- | lib/tsan/go/tsan_go.cc | 81 |
1 files changed, 70 insertions, 11 deletions
diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cc index 4b3076c46ce7..360608a0cf1b 100644 --- a/lib/tsan/go/tsan_go.cc +++ b/lib/tsan/go/tsan_go.cc @@ -18,7 +18,9 @@ namespace __tsan { -static ThreadState *goroutines[kMaxTid]; +const int kMaxGoroutinesEver = 128*1024; + +static ThreadState *goroutines[kMaxGoroutinesEver]; void InitializeInterceptors() { } @@ -33,7 +35,7 @@ bool IsExpectedReport(uptr addr, uptr size) { void internal_start_thread(void(*func)(void*), void *arg) { } -ReportStack *SymbolizeData(uptr addr) { +ReportLocation *SymbolizeData(uptr addr) { return 0; } @@ -79,9 +81,14 @@ ReportStack *SymbolizeCode(uptr addr) { extern "C" { static void AllocGoroutine(int tid) { - goroutines[tid] = (ThreadState*)internal_alloc(MBlockThreadContex, + if (tid >= kMaxGoroutinesEver) { + Printf("FATAL: Reached goroutine limit\n"); + Die(); + } + ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex, sizeof(ThreadState)); - internal_memset(goroutines[tid], 0, sizeof(ThreadState)); + internal_memset(thr, 0, sizeof(*thr)); + goroutines[tid] = thr; } void __tsan_init() { @@ -98,7 +105,11 @@ void __tsan_fini() { thr->in_rtl++; int res = Finalize(thr); thr->in_rtl--; - exit(res); + exit(res); +} + +void __tsan_map_shadow(uptr addr, uptr size) { + MapShadow(addr, size); } void __tsan_read(int goid, void *addr, void *pc) { @@ -111,6 +122,18 @@ void __tsan_write(int goid, 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]; + 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]; + 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]; FuncEntry(thr, (uptr)pc); @@ -123,9 +146,10 @@ void __tsan_func_exit(int goid) { void __tsan_malloc(int goid, void *p, uptr sz, void *pc) { ThreadState *thr = goroutines[goid]; + if (thr == 0) // probably before __tsan_init() + return; thr->in_rtl++; - MemoryResetRange(thr, (uptr)pc, (uptr)p, sz); - MemoryAccessRange(thr, (uptr)pc, (uptr)p, sz, true); + MemoryRangeImitateWrite(thr, (uptr)pc, (uptr)p, sz); thr->in_rtl--; } @@ -142,7 +166,7 @@ void __tsan_go_start(int pgoid, int chgoid, void *pc) { thr->in_rtl++; parent->in_rtl++; int goid2 = ThreadCreate(parent, (uptr)pc, 0, true); - ThreadStart(thr, goid2); + ThreadStart(thr, goid2, 0); parent->in_rtl--; thr->in_rtl--; } @@ -152,6 +176,8 @@ void __tsan_go_end(int goid) { thr->in_rtl++; ThreadFinish(thr); thr->in_rtl--; + internal_free(thr); + goroutines[goid] = 0; } void __tsan_acquire(int goid, void *addr) { @@ -159,7 +185,6 @@ void __tsan_acquire(int goid, void *addr) { thr->in_rtl++; Acquire(thr, 0, (uptr)addr); thr->in_rtl--; - //internal_free(thr); } void __tsan_release(int goid, void *addr) { @@ -178,8 +203,42 @@ void __tsan_release_merge(int goid, void *addr) { void __tsan_finalizer_goroutine(int goid) { ThreadState *thr = goroutines[goid]; - ThreadFinalizerGoroutine(thr); -} + AcquireGlobal(thr, 0); +} + +#ifdef _WIN32 +// MinGW gcc emits calls to the function. +void ___chkstk_ms(void) { +// The implementation must be along the lines of: +// .code64 +// PUBLIC ___chkstk_ms +// //cfi_startproc() +// ___chkstk_ms: +// push rcx +// //cfi_push(%rcx) +// push rax +// //cfi_push(%rax) +// cmp rax, PAGE_SIZE +// lea rcx, [rsp + 24] +// jb l_LessThanAPage +// .l_MoreThanAPage: +// sub rcx, PAGE_SIZE +// or rcx, 0 +// sub rax, PAGE_SIZE +// cmp rax, PAGE_SIZE +// ja l_MoreThanAPage +// .l_LessThanAPage: +// sub rcx, rax +// or [rcx], 0 +// pop rax +// //cfi_pop(%rax) +// pop rcx +// //cfi_pop(%rcx) +// ret +// //cfi_endproc() +// END +} +#endif } // extern "C" } // namespace __tsan |