diff options
Diffstat (limited to 'libsanitizer/tsan/tsan_rtl_thread.cc')
-rw-r--r-- | libsanitizer/tsan/tsan_rtl_thread.cc | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/libsanitizer/tsan/tsan_rtl_thread.cc b/libsanitizer/tsan/tsan_rtl_thread.cc index bb7f35c24ed..462d12c7dee 100644 --- a/libsanitizer/tsan/tsan_rtl_thread.cc +++ b/libsanitizer/tsan/tsan_rtl_thread.cc @@ -96,6 +96,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) { ThreadContext *tctx = 0; if (ctx->dead_list_size > kThreadQuarantineSize || ctx->thread_seq >= kMaxTid) { + // Reusing old thread descriptor and tid. if (ctx->dead_list_size == 0) { Printf("ThreadSanitizer: %d thread limit exceeded. Dying.\n", kMaxTid); @@ -115,12 +116,18 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) { tctx->sync.Reset(); tid = tctx->tid; DestroyAndFree(tctx->dead_info); + if (tctx->name) { + internal_free(tctx->name); + tctx->name = 0; + } } else { + // Allocating new thread descriptor and tid. StatInc(thr, StatThreadMaxTid); tid = ctx->thread_seq++; void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadContext)); tctx = new(mem) ThreadContext(tid); ctx->threads[tid] = tctx; + MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event)); } CHECK_NE(tctx, 0); CHECK_GE(tid, 0); @@ -141,12 +148,11 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) { if (tid) { thr->fast_state.IncrementEpoch(); // Can't increment epoch w/o writing to the trace as well. - TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeMop, 0); + TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0); thr->clock.set(thr->tid, thr->fast_state.epoch()); thr->fast_synch_epoch = thr->fast_state.epoch(); thr->clock.release(&tctx->sync); StatInc(thr, StatSyncRelease); - tctx->creation_stack.ObtainCurrent(thr, pc); } return tid; @@ -185,7 +191,9 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) { CHECK_EQ(tctx->status, ThreadStatusCreated); tctx->status = ThreadStatusRunning; tctx->os_id = os_id; - tctx->epoch0 = tctx->epoch1 + 1; + // RoundUp so that one trace part does not contain events + // from different threads. + tctx->epoch0 = RoundUp(tctx->epoch1 + 1, kTracePartSize); tctx->epoch1 = (u64)-1; new(thr) ThreadState(CTX(), tid, tctx->unique_id, tctx->epoch0, stk_addr, stk_size, @@ -202,6 +210,9 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) { thr->fast_synch_epoch = tctx->epoch0; thr->clock.set(tid, tctx->epoch0); thr->clock.acquire(&tctx->sync); + thr->fast_state.SetHistorySize(flags()->history_size); + const uptr trace = (tctx->epoch0 / kTracePartSize) % TraceParts(); + thr->trace.headers[trace].epoch0 = tctx->epoch0; StatInc(thr, StatSyncAcquire); DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx " "tls_addr=%zx tls_size=%zx\n", @@ -236,7 +247,7 @@ void ThreadFinish(ThreadState *thr) { } else { thr->fast_state.IncrementEpoch(); // Can't increment epoch w/o writing to the trace as well. - TraceAddEvent(thr, thr->fast_state.epoch(), EventTypeMop, 0); + TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0); thr->clock.set(thr->tid, thr->fast_state.epoch()); thr->fast_synch_epoch = thr->fast_state.epoch(); thr->clock.release(&tctx->sync); @@ -247,9 +258,8 @@ void ThreadFinish(ThreadState *thr) { // Save from info about the thread. tctx->dead_info = new(internal_alloc(MBlockDeadInfo, sizeof(ThreadDeadInfo))) ThreadDeadInfo(); - internal_memcpy(&tctx->dead_info->trace.events[0], - &thr->trace.events[0], sizeof(thr->trace.events)); - for (int i = 0; i < kTraceParts; i++) { + for (uptr i = 0; i < TraceParts(); i++) { + tctx->dead_info->trace.headers[i].epoch0 = thr->trace.headers[i].epoch0; tctx->dead_info->trace.headers[i].stack0.CopyFrom( thr->trace.headers[i].stack0); } @@ -318,6 +328,20 @@ void ThreadDetach(ThreadState *thr, uptr pc, int tid) { } } +void ThreadSetName(ThreadState *thr, const char *name) { + Context *ctx = CTX(); + Lock l(&ctx->thread_mtx); + ThreadContext *tctx = ctx->threads[thr->tid]; + CHECK_NE(tctx, 0); + CHECK_EQ(tctx->status, ThreadStatusRunning); + if (tctx->name) { + internal_free(tctx->name); + tctx->name = 0; + } + if (name) + tctx->name = internal_strdup(name); +} + void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr, uptr size, bool is_write) { if (size == 0) @@ -356,7 +380,7 @@ void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr, fast_state.IncrementEpoch(); thr->fast_state = fast_state; - TraceAddEvent(thr, fast_state.epoch(), EventTypeMop, pc); + TraceAddEvent(thr, fast_state, EventTypeMop, pc); bool unaligned = (addr % kShadowCell) != 0; |