tsan: introduce Tid and StackID typedefs

Currently we inconsistently use u32 and int for thread ids,
there are also "unique tid" and "os tid" and just lots of other
things identified by integers.
Additionally new tsan runtime will introduce yet another
thread identifier that is very different from current tids.
Similarly for stack IDs, it's easy to confuse u32 with other
integer identifiers. And when a function accepts u32 or a struct
contains u32 field, it's not always clear what it is.

Add Tid and StackID typedefs to make it clear what is what.

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D107152
This commit is contained in:
Dmitry Vyukov 2021-07-30 13:50:15 +02:00
parent 3ea3b6b2d4
commit 103d075b05
16 changed files with 82 additions and 83 deletions

View File

@ -409,8 +409,14 @@ inline void Trap() {
(void)enable_fp; \ (void)enable_fp; \
} while (0) } while (0)
constexpr u32 kInvalidTid = -1; // Internal thread identifier allocated by ThreadRegistry.
constexpr u32 kMainTid = 0; typedef u32 Tid;
constexpr Tid kInvalidTid = -1;
constexpr Tid kMainTid = 0;
// Stack depot stack identifier.
typedef u32 StackID;
const StackID kInvalidStackID = 0;
} // namespace __sanitizer } // namespace __sanitizer

View File

@ -220,7 +220,7 @@ void __tsan_free(uptr p, uptr sz) {
void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) { void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) {
ThreadState *thr = AllocGoroutine(); ThreadState *thr = AllocGoroutine();
*pthr = thr; *pthr = thr;
int goid = ThreadCreate(parent, (uptr)pc, 0, true); Tid goid = ThreadCreate(parent, (uptr)pc, 0, true);
ThreadStart(thr, goid, 0, ThreadType::Regular); ThreadStart(thr, goid, 0, ThreadType::Regular);
} }

View File

@ -26,8 +26,8 @@ struct FdSync {
struct FdDesc { struct FdDesc {
FdSync *sync; FdSync *sync;
int creation_tid; Tid creation_tid;
u32 creation_stack; StackID creation_stack;
}; };
struct FdContext { struct FdContext {
@ -140,7 +140,7 @@ void FdOnFork(ThreadState *thr, uptr pc) {
} }
} }
bool FdLocation(uptr addr, int *fd, int *tid, u32 *stack) { bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack) {
for (int l1 = 0; l1 < kTableSizeL1; l1++) { for (int l1 = 0; l1 < kTableSizeL1; l1++) {
FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed); FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed);
if (tab == 0) if (tab == 0)
@ -211,8 +211,8 @@ void FdClose(ThreadState *thr, uptr pc, int fd, bool write) {
MemoryResetRange(thr, pc, (uptr)d, 8); MemoryResetRange(thr, pc, (uptr)d, 8);
unref(thr, pc, d->sync); unref(thr, pc, d->sync);
d->sync = 0; d->sync = 0;
d->creation_tid = 0; d->creation_tid = kInvalidTid;
d->creation_stack = 0; d->creation_stack = kInvalidStackID;
} }
void FdFileCreate(ThreadState *thr, uptr pc, int fd) { void FdFileCreate(ThreadState *thr, uptr pc, int fd) {

View File

@ -53,7 +53,7 @@ void FdSocketCreate(ThreadState *thr, uptr pc, int fd);
void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd); void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd);
void FdSocketConnecting(ThreadState *thr, uptr pc, int fd); void FdSocketConnecting(ThreadState *thr, uptr pc, int fd);
void FdSocketConnect(ThreadState *thr, uptr pc, int fd); void FdSocketConnect(ThreadState *thr, uptr pc, int fd);
bool FdLocation(uptr addr, int *fd, int *tid, u32 *stack); bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack);
void FdOnFork(ThreadState *thr, uptr pc); void FdOnFork(ThreadState *thr, uptr pc);
uptr File2addr(const char *path); uptr File2addr(const char *path);

View File

@ -19,7 +19,7 @@ IgnoreSet::IgnoreSet()
: size_() { : size_() {
} }
void IgnoreSet::Add(u32 stack_id) { void IgnoreSet::Add(StackID stack_id) {
if (size_ == kMaxSize) if (size_ == kMaxSize)
return; return;
for (uptr i = 0; i < size_; i++) { for (uptr i = 0; i < size_; i++) {
@ -37,7 +37,7 @@ uptr IgnoreSet::Size() const {
return size_; return size_;
} }
u32 IgnoreSet::At(uptr i) const { StackID IgnoreSet::At(uptr i) const {
CHECK_LT(i, size_); CHECK_LT(i, size_);
CHECK_LE(size_, kMaxSize); CHECK_LE(size_, kMaxSize);
return stacks_[i]; return stacks_[i];

View File

@ -22,14 +22,14 @@ class IgnoreSet {
static const uptr kMaxSize = 16; static const uptr kMaxSize = 16;
IgnoreSet(); IgnoreSet();
void Add(u32 stack_id); void Add(StackID stack_id);
void Reset(); void Reset();
uptr Size() const; uptr Size() const;
u32 At(uptr i) const; StackID At(uptr i) const;
private: private:
uptr size_; uptr size_;
u32 stacks_[kMaxSize]; StackID stacks_[kMaxSize];
}; };
} // namespace __tsan } // namespace __tsan

View File

@ -1010,8 +1010,8 @@ TSAN_INTERCEPTOR(int, pthread_create,
ThreadIgnoreEnd(thr); ThreadIgnoreEnd(thr);
} }
if (res == 0) { if (res == 0) {
int tid = ThreadCreate(thr, pc, *(uptr*)th, IsStateDetached(detached)); Tid tid = ThreadCreate(thr, pc, *(uptr *)th, IsStateDetached(detached));
CHECK_NE(tid, 0); CHECK_NE(tid, kMainTid);
// Synchronization on p.tid serves two purposes: // Synchronization on p.tid serves two purposes:
// 1. ThreadCreate must finish before the new thread starts. // 1. ThreadCreate must finish before the new thread starts.
// Otherwise the new thread can call pthread_detach, but the pthread_t // Otherwise the new thread can call pthread_detach, but the pthread_t
@ -1030,7 +1030,7 @@ TSAN_INTERCEPTOR(int, pthread_create,
TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret); SCOPED_INTERCEPTOR_RAW(pthread_join, th, ret);
int tid = ThreadConsumeTid(thr, pc, (uptr)th); Tid tid = ThreadConsumeTid(thr, pc, (uptr)th);
ThreadIgnoreBegin(thr, pc); ThreadIgnoreBegin(thr, pc);
int res = BLOCK_REAL(pthread_join)(th, ret); int res = BLOCK_REAL(pthread_join)(th, ret);
ThreadIgnoreEnd(thr); ThreadIgnoreEnd(thr);
@ -1044,7 +1044,7 @@ DEFINE_REAL_PTHREAD_FUNCTIONS
TSAN_INTERCEPTOR(int, pthread_detach, void *th) { TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
SCOPED_INTERCEPTOR_RAW(pthread_detach, th); SCOPED_INTERCEPTOR_RAW(pthread_detach, th);
int tid = ThreadConsumeTid(thr, pc, (uptr)th); Tid tid = ThreadConsumeTid(thr, pc, (uptr)th);
int res = REAL(pthread_detach)(th); int res = REAL(pthread_detach)(th);
if (res == 0) { if (res == 0) {
ThreadDetach(thr, pc, tid); ThreadDetach(thr, pc, tid);
@ -1065,7 +1065,7 @@ TSAN_INTERCEPTOR(void, pthread_exit, void *retval) {
#if SANITIZER_LINUX #if SANITIZER_LINUX
TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) { TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
SCOPED_INTERCEPTOR_RAW(pthread_tryjoin_np, th, ret); SCOPED_INTERCEPTOR_RAW(pthread_tryjoin_np, th, ret);
int tid = ThreadConsumeTid(thr, pc, (uptr)th); Tid tid = ThreadConsumeTid(thr, pc, (uptr)th);
ThreadIgnoreBegin(thr, pc); ThreadIgnoreBegin(thr, pc);
int res = REAL(pthread_tryjoin_np)(th, ret); int res = REAL(pthread_tryjoin_np)(th, ret);
ThreadIgnoreEnd(thr); ThreadIgnoreEnd(thr);
@ -1079,7 +1079,7 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret, TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret,
const struct timespec *abstime) { const struct timespec *abstime) {
SCOPED_INTERCEPTOR_RAW(pthread_timedjoin_np, th, ret, abstime); SCOPED_INTERCEPTOR_RAW(pthread_timedjoin_np, th, ret, abstime);
int tid = ThreadConsumeTid(thr, pc, (uptr)th); Tid tid = ThreadConsumeTid(thr, pc, (uptr)th);
ThreadIgnoreBegin(thr, pc); ThreadIgnoreBegin(thr, pc);
int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime); int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime);
ThreadIgnoreEnd(thr); ThreadIgnoreEnd(thr);

View File

@ -215,8 +215,8 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread,
Processor *proc = ProcCreate(); Processor *proc = ProcCreate();
ProcWire(proc, thr); ProcWire(proc, thr);
ThreadState *parent_thread_state = nullptr; // No parent. ThreadState *parent_thread_state = nullptr; // No parent.
int tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true); Tid tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true);
CHECK_NE(tid, 0); CHECK_NE(tid, kMainTid);
ThreadStart(thr, tid, GetTid(), ThreadType::Worker); ThreadStart(thr, tid, GetTid(), ThreadType::Worker);
} }
} else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) { } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) {

View File

@ -52,7 +52,7 @@ ReportDesc::~ReportDesc() {
#if !SANITIZER_GO #if !SANITIZER_GO
const int kThreadBufSize = 32; const int kThreadBufSize = 32;
const char *thread_name(char *buf, int tid) { const char *thread_name(char *buf, Tid tid) {
if (tid == kMainTid) if (tid == kMainTid)
return "main thread"; return "main thread";
internal_snprintf(buf, kThreadBufSize, "thread T%d", tid); internal_snprintf(buf, kThreadBufSize, "thread T%d", tid);
@ -378,7 +378,7 @@ void PrintReport(const ReportDesc *rep) {
#else // #if !SANITIZER_GO #else // #if !SANITIZER_GO
const u32 kMainGoroutineId = 1; const Tid kMainGoroutineId = 1;
void PrintStack(const ReportStack *ent) { void PrintStack(const ReportStack *ent) {
if (ent == 0 || ent->frames == 0) { if (ent == 0 || ent->frames == 0) {

View File

@ -74,19 +74,19 @@ struct ReportLocation {
uptr heap_chunk_start = 0; uptr heap_chunk_start = 0;
uptr heap_chunk_size = 0; uptr heap_chunk_size = 0;
uptr external_tag = 0; uptr external_tag = 0;
int tid = kInvalidTid; Tid tid = kInvalidTid;
int fd = 0; int fd = 0;
bool suppressable = false; bool suppressable = false;
ReportStack *stack = nullptr; ReportStack *stack = nullptr;
}; };
struct ReportThread { struct ReportThread {
int id; Tid id;
tid_t os_id; tid_t os_id;
bool running; bool running;
ThreadType thread_type; ThreadType thread_type;
char *name; char *name;
u32 parent_tid; Tid parent_tid;
ReportStack *stack; ReportStack *stack;
}; };
@ -106,7 +106,7 @@ class ReportDesc {
Vector<ReportLocation*> locs; Vector<ReportLocation*> locs;
Vector<ReportMutex*> mutexes; Vector<ReportMutex*> mutexes;
Vector<ReportThread*> threads; Vector<ReportThread*> threads;
Vector<int> unique_tids; Vector<Tid> unique_tids;
ReportStack *sleep; ReportStack *sleep;
int count; int count;

View File

@ -77,7 +77,7 @@ void OnInitialize() {
} }
#endif #endif
static ThreadContextBase *CreateThreadContext(u32 tid) { static ThreadContextBase *CreateThreadContext(Tid tid) {
// Map thread trace when context is created. // Map thread trace when context is created.
char name[50]; char name[50];
internal_snprintf(name, sizeof(name), "trace %u", tid); internal_snprintf(name, sizeof(name), "trace %u", tid);
@ -126,7 +126,7 @@ Context::Context()
} }
// The objects are allocated in TLS, so one may rely on zero-initialization. // The objects are allocated in TLS, so one may rely on zero-initialization.
ThreadState::ThreadState(Context *ctx, u32 tid, int unique_id, u64 epoch, ThreadState::ThreadState(Context *ctx, Tid tid, int unique_id, u64 epoch,
unsigned reuse_count, uptr stk_addr, uptr stk_size, unsigned reuse_count, uptr stk_addr, uptr stk_size,
uptr tls_addr, uptr tls_size) uptr tls_addr, uptr tls_size)
: fast_state(tid, epoch) : fast_state(tid, epoch)
@ -438,8 +438,8 @@ void Initialize(ThreadState *thr) {
(int)internal_getpid()); (int)internal_getpid());
// Initialize thread 0. // Initialize thread 0.
int tid = ThreadCreate(thr, 0, 0, true); Tid tid = ThreadCreate(thr, 0, 0, true);
CHECK_EQ(tid, 0); CHECK_EQ(tid, kMainTid);
ThreadStart(thr, tid, GetTid(), ThreadType::Regular); ThreadStart(thr, tid, GetTid(), ThreadType::Regular);
#if TSAN_CONTAINS_UBSAN #if TSAN_CONTAINS_UBSAN
__ubsan::InitAsPlugin(); __ubsan::InitAsPlugin();
@ -581,9 +581,9 @@ void GrowShadowStack(ThreadState *thr) {
} }
#endif #endif
u32 CurrentStackId(ThreadState *thr, uptr pc) { StackID CurrentStackId(ThreadState *thr, uptr pc) {
if (!thr->is_inited) // May happen during bootstrap. if (!thr->is_inited) // May happen during bootstrap.
return 0; return kInvalidStackID;
if (pc != 0) { if (pc != 0) {
#if !SANITIZER_GO #if !SANITIZER_GO
DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end); DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);
@ -594,7 +594,7 @@ u32 CurrentStackId(ThreadState *thr, uptr pc) {
thr->shadow_stack_pos[0] = pc; thr->shadow_stack_pos[0] = pc;
thr->shadow_stack_pos++; thr->shadow_stack_pos++;
} }
u32 id = StackDepotPut( StackID id = StackDepotPut(
StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack)); StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack));
if (pc != 0) if (pc != 0)
thr->shadow_stack_pos--; thr->shadow_stack_pos--;
@ -617,9 +617,7 @@ void TraceSwitch(ThreadState *thr) {
thr->nomalloc--; thr->nomalloc--;
} }
Trace *ThreadTrace(int tid) { Trace *ThreadTrace(Tid tid) { return (Trace *)GetThreadTraceHeader(tid); }
return (Trace*)GetThreadTraceHeader(tid);
}
uptr TraceTopPC(ThreadState *thr) { uptr TraceTopPC(ThreadState *thr) {
Event *events = (Event*)GetThreadTrace(thr->tid); Event *events = (Event*)GetThreadTrace(thr->tid);

View File

@ -400,7 +400,7 @@ struct ThreadState {
Vector<JmpBuf> jmp_bufs; Vector<JmpBuf> jmp_bufs;
int ignore_interceptors; int ignore_interceptors;
#endif #endif
const u32 tid; const Tid tid;
const int unique_id; const int unique_id;
bool in_symbolizer; bool in_symbolizer;
bool in_ignored_lib; bool in_ignored_lib;
@ -428,7 +428,7 @@ struct ThreadState {
ThreadSignalContext *signal_ctx; ThreadSignalContext *signal_ctx;
#if !SANITIZER_GO #if !SANITIZER_GO
u32 last_sleep_stack_id; StackID last_sleep_stack_id;
ThreadClock last_sleep_clock; ThreadClock last_sleep_clock;
#endif #endif
@ -438,7 +438,7 @@ struct ThreadState {
const ReportDesc *current_report; const ReportDesc *current_report;
explicit ThreadState(Context *ctx, u32 tid, int unique_id, u64 epoch, explicit ThreadState(Context *ctx, Tid tid, int unique_id, u64 epoch,
unsigned reuse_count, uptr stk_addr, uptr stk_size, unsigned reuse_count, uptr stk_addr, uptr stk_size,
uptr tls_addr, uptr tls_size); uptr tls_addr, uptr tls_size);
}; };
@ -469,10 +469,10 @@ inline void cur_thread_finalize() { }
class ThreadContext final : public ThreadContextBase { class ThreadContext final : public ThreadContextBase {
public: public:
explicit ThreadContext(int tid); explicit ThreadContext(Tid tid);
~ThreadContext(); ~ThreadContext();
ThreadState *thr; ThreadState *thr;
u32 creation_stack_id; StackID creation_stack_id;
SyncClock sync; SyncClock sync;
// Epoch at which the thread had started. // Epoch at which the thread had started.
// If we see an event from the thread stamped by an older epoch, // If we see an event from the thread stamped by an older epoch,
@ -575,12 +575,12 @@ class ScopedReportBase {
const MutexSet *mset); const MutexSet *mset);
void AddStack(StackTrace stack, bool suppressable = false); void AddStack(StackTrace stack, bool suppressable = false);
void AddThread(const ThreadContext *tctx, bool suppressable = false); void AddThread(const ThreadContext *tctx, bool suppressable = false);
void AddThread(int unique_tid, bool suppressable = false); void AddThread(Tid unique_tid, bool suppressable = false);
void AddUniqueTid(int unique_tid); void AddUniqueTid(Tid unique_tid);
void AddMutex(const SyncVar *s); void AddMutex(const SyncVar *s);
u64 AddMutex(u64 id); u64 AddMutex(u64 id);
void AddLocation(uptr addr, uptr size); void AddLocation(uptr addr, uptr size);
void AddSleep(u32 stack_id); void AddSleep(StackID stack_id);
void SetCount(int count); void SetCount(int count);
const ReportDesc *GetReport() const; const ReportDesc *GetReport() const;
@ -612,7 +612,7 @@ class ScopedReport : public ScopedReportBase {
bool ShouldReport(ThreadState *thr, ReportType typ); bool ShouldReport(ThreadState *thr, ReportType typ);
ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack); ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack);
void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk, void RestoreStack(Tid tid, const u64 epoch, VarSizeStackTrace *stk,
MutexSet *mset, uptr *tag = nullptr); MutexSet *mset, uptr *tag = nullptr);
// The stack could look like: // The stack could look like:
@ -678,8 +678,8 @@ bool IsExpectedReport(uptr addr, uptr size);
# define DPrintf2(...) # define DPrintf2(...)
#endif #endif
u32 CurrentStackId(ThreadState *thr, uptr pc); StackID CurrentStackId(ThreadState *thr, uptr pc);
ReportStack *SymbolizeStackId(u32 stack_id); ReportStack *SymbolizeStackId(StackID stack_id);
void PrintCurrentStack(ThreadState *thr, uptr pc); void PrintCurrentStack(ThreadState *thr, uptr pc);
void PrintCurrentStackSlow(uptr pc); // uses libunwind void PrintCurrentStackSlow(uptr pc); // uses libunwind
MBlock *JavaHeapBlock(uptr addr, uptr *start); MBlock *JavaHeapBlock(uptr addr, uptr *start);
@ -742,18 +742,18 @@ void ThreadIgnoreSyncEnd(ThreadState *thr);
void FuncEntry(ThreadState *thr, uptr pc); void FuncEntry(ThreadState *thr, uptr pc);
void FuncExit(ThreadState *thr); void FuncExit(ThreadState *thr);
int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached); Tid ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
void ThreadStart(ThreadState *thr, int tid, tid_t os_id, void ThreadStart(ThreadState *thr, Tid tid, tid_t os_id,
ThreadType thread_type); ThreadType thread_type);
void ThreadFinish(ThreadState *thr); void ThreadFinish(ThreadState *thr);
int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid); Tid ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid);
void ThreadJoin(ThreadState *thr, uptr pc, int tid); void ThreadJoin(ThreadState *thr, uptr pc, Tid tid);
void ThreadDetach(ThreadState *thr, uptr pc, int tid); void ThreadDetach(ThreadState *thr, uptr pc, Tid tid);
void ThreadFinalize(ThreadState *thr); void ThreadFinalize(ThreadState *thr);
void ThreadSetName(ThreadState *thr, const char *name); void ThreadSetName(ThreadState *thr, const char *name);
int ThreadCount(ThreadState *thr); int ThreadCount(ThreadState *thr);
void ProcessPendingSignals(ThreadState *thr); void ProcessPendingSignals(ThreadState *thr);
void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid); void ThreadNotJoined(ThreadState *thr, uptr pc, Tid tid, uptr uid);
Processor *ProcCreate(); Processor *ProcCreate();
void ProcDestroy(Processor *proc); void ProcDestroy(Processor *proc);
@ -818,7 +818,7 @@ void TraceSwitch(ThreadState *thr);
uptr TraceTopPC(ThreadState *thr); uptr TraceTopPC(ThreadState *thr);
uptr TraceSize(); uptr TraceSize();
uptr TraceParts(); uptr TraceParts();
Trace *ThreadTrace(int tid); Trace *ThreadTrace(Tid tid);
extern "C" void __tsan_trace_switch(); extern "C" void __tsan_trace_switch();
void ALWAYS_INLINE TraceAddEvent(ThreadState *thr, FastState fs, void ALWAYS_INLINE TraceAddEvent(ThreadState *thr, FastState fs,

View File

@ -35,7 +35,7 @@ struct Callback final : public DDCallback {
DDCallback::lt = thr->dd_lt; DDCallback::lt = thr->dd_lt;
} }
u32 Unwind() override { return CurrentStackId(thr, pc); } StackID Unwind() override { return CurrentStackId(thr, pc); }
int UniqueTid() override { return thr->unique_id; } int UniqueTid() override { return thr->unique_id; }
}; };

View File

@ -195,7 +195,7 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s,
} }
} }
void ScopedReportBase::AddUniqueTid(int unique_tid) { void ScopedReportBase::AddUniqueTid(Tid unique_tid) {
rep_->unique_tids.PushBack(unique_tid); rep_->unique_tids.PushBack(unique_tid);
} }
@ -224,14 +224,14 @@ static bool FindThreadByUidLockedCallback(ThreadContextBase *tctx, void *arg) {
return tctx->unique_id == (u32)unique_id; return tctx->unique_id == (u32)unique_id;
} }
static ThreadContext *FindThreadByUidLocked(int unique_id) { static ThreadContext *FindThreadByUidLocked(Tid unique_id) {
ctx->thread_registry.CheckLocked(); ctx->thread_registry.CheckLocked();
return static_cast<ThreadContext *>( return static_cast<ThreadContext *>(
ctx->thread_registry.FindThreadContextLocked( ctx->thread_registry.FindThreadContextLocked(
FindThreadByUidLockedCallback, &unique_id)); FindThreadByUidLockedCallback, &unique_id));
} }
static ThreadContext *FindThreadByTidLocked(int tid) { static ThreadContext *FindThreadByTidLocked(Tid tid) {
ctx->thread_registry.CheckLocked(); ctx->thread_registry.CheckLocked();
return static_cast<ThreadContext *>( return static_cast<ThreadContext *>(
ctx->thread_registry.GetThreadLocked(tid)); ctx->thread_registry.GetThreadLocked(tid));
@ -262,7 +262,7 @@ ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack) {
} }
#endif #endif
void ScopedReportBase::AddThread(int unique_tid, bool suppressable) { void ScopedReportBase::AddThread(Tid unique_tid, bool suppressable) {
#if !SANITIZER_GO #if !SANITIZER_GO
if (const ThreadContext *tctx = FindThreadByUidLocked(unique_tid)) if (const ThreadContext *tctx = FindThreadByUidLocked(unique_tid))
AddThread(tctx, suppressable); AddThread(tctx, suppressable);
@ -319,8 +319,8 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
return; return;
#if !SANITIZER_GO #if !SANITIZER_GO
int fd = -1; int fd = -1;
int creat_tid = kInvalidTid; Tid creat_tid = kInvalidTid;
u32 creat_stack = 0; StackID creat_stack = 0;
if (FdLocation(addr, &fd, &creat_tid, &creat_stack)) { if (FdLocation(addr, &fd, &creat_tid, &creat_stack)) {
auto *loc = New<ReportLocation>(); auto *loc = New<ReportLocation>();
loc->type = ReportLocationFD; loc->type = ReportLocationFD;
@ -374,7 +374,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
} }
#if !SANITIZER_GO #if !SANITIZER_GO
void ScopedReportBase::AddSleep(u32 stack_id) { void ScopedReportBase::AddSleep(StackID stack_id) {
rep_->sleep = SymbolizeStackId(stack_id); rep_->sleep = SymbolizeStackId(stack_id);
} }
#endif #endif
@ -388,7 +388,7 @@ ScopedReport::ScopedReport(ReportType typ, uptr tag)
ScopedReport::~ScopedReport() {} ScopedReport::~ScopedReport() {}
void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk, void RestoreStack(Tid tid, const u64 epoch, VarSizeStackTrace *stk,
MutexSet *mset, uptr *tag) { MutexSet *mset, uptr *tag) {
// This function restores stack trace and mutex set for the thread/epoch. // This function restores stack trace and mutex set for the thread/epoch.
// It does so by getting stack trace and mutex set at the beginning of // It does so by getting stack trace and mutex set at the beginning of

View File

@ -21,13 +21,8 @@ namespace __tsan {
// ThreadContext implementation. // ThreadContext implementation.
ThreadContext::ThreadContext(int tid) ThreadContext::ThreadContext(Tid tid)
: ThreadContextBase(tid) : ThreadContextBase(tid), thr(), sync(), epoch0(), epoch1() {}
, thr()
, sync()
, epoch0()
, epoch1() {
}
#if !SANITIZER_GO #if !SANITIZER_GO
ThreadContext::~ThreadContext() { ThreadContext::~ThreadContext() {
@ -223,15 +218,15 @@ int ThreadCount(ThreadState *thr) {
return (int)result; return (int)result;
} }
int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) { Tid ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
OnCreatedArgs args = { thr, pc }; OnCreatedArgs args = { thr, pc };
u32 parent_tid = thr ? thr->tid : kInvalidTid; // No parent for GCD workers. u32 parent_tid = thr ? thr->tid : kInvalidTid; // No parent for GCD workers.
int tid = ctx->thread_registry.CreateThread(uid, detached, parent_tid, &args); Tid tid = ctx->thread_registry.CreateThread(uid, detached, parent_tid, &args);
DPrintf("#%d: ThreadCreate tid=%d uid=%zu\n", parent_tid, tid, uid); DPrintf("#%d: ThreadCreate tid=%d uid=%zu\n", parent_tid, tid, uid);
return tid; return tid;
} }
void ThreadStart(ThreadState *thr, int tid, tid_t os_id, void ThreadStart(ThreadState *thr, Tid tid, tid_t os_id,
ThreadType thread_type) { ThreadType thread_type) {
uptr stk_addr = 0; uptr stk_addr = 0;
uptr stk_size = 0; uptr stk_size = 0;
@ -299,28 +294,28 @@ static bool ConsumeThreadByUid(ThreadContextBase *tctx, void *arg) {
return false; return false;
} }
int ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) { Tid ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid) {
ConsumeThreadContext findCtx = {uid, nullptr}; ConsumeThreadContext findCtx = {uid, nullptr};
ctx->thread_registry.FindThread(ConsumeThreadByUid, &findCtx); ctx->thread_registry.FindThread(ConsumeThreadByUid, &findCtx);
int tid = findCtx.tctx ? findCtx.tctx->tid : kInvalidTid; Tid tid = findCtx.tctx ? findCtx.tctx->tid : kInvalidTid;
DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid); DPrintf("#%d: ThreadTid uid=%zu tid=%d\n", thr->tid, uid, tid);
return tid; return tid;
} }
void ThreadJoin(ThreadState *thr, uptr pc, int tid) { void ThreadJoin(ThreadState *thr, uptr pc, Tid tid) {
CHECK_GT(tid, 0); CHECK_GT(tid, 0);
CHECK_LT(tid, kMaxTid); CHECK_LT(tid, kMaxTid);
DPrintf("#%d: ThreadJoin tid=%d\n", thr->tid, tid); DPrintf("#%d: ThreadJoin tid=%d\n", thr->tid, tid);
ctx->thread_registry.JoinThread(tid, thr); ctx->thread_registry.JoinThread(tid, thr);
} }
void ThreadDetach(ThreadState *thr, uptr pc, int tid) { void ThreadDetach(ThreadState *thr, uptr pc, Tid tid) {
CHECK_GT(tid, 0); CHECK_GT(tid, 0);
CHECK_LT(tid, kMaxTid); CHECK_LT(tid, kMaxTid);
ctx->thread_registry.DetachThread(tid, thr); ctx->thread_registry.DetachThread(tid, thr);
} }
void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid) { void ThreadNotJoined(ThreadState *thr, uptr pc, Tid tid, uptr uid) {
CHECK_GT(tid, 0); CHECK_GT(tid, 0);
CHECK_LT(tid, kMaxTid); CHECK_LT(tid, kMaxTid);
ctx->thread_registry.SetThreadUserId(tid, uid); ctx->thread_registry.SetThreadUserId(tid, uid);
@ -421,7 +416,7 @@ ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags) {
void *mem = Alloc(sizeof(ThreadState)); void *mem = Alloc(sizeof(ThreadState));
ThreadState *fiber = static_cast<ThreadState *>(mem); ThreadState *fiber = static_cast<ThreadState *>(mem);
internal_memset(fiber, 0, sizeof(*fiber)); internal_memset(fiber, 0, sizeof(*fiber));
int tid = ThreadCreate(thr, pc, 0, true); Tid tid = ThreadCreate(thr, pc, 0, true);
FiberSwitchImpl(thr, fiber); FiberSwitchImpl(thr, fiber);
ThreadStart(fiber, tid, 0, ThreadType::Fiber); ThreadStart(fiber, tid, 0, ThreadType::Fiber);
FiberSwitchImpl(fiber, thr); FiberSwitchImpl(fiber, thr);

View File

@ -52,8 +52,8 @@ struct SyncVar {
uptr addr; // overwritten by DenseSlabAlloc freelist uptr addr; // overwritten by DenseSlabAlloc freelist
Mutex mtx; Mutex mtx;
u64 uid; // Globally unique id. u64 uid; // Globally unique id.
u32 creation_stack_id; StackID creation_stack_id;
u32 owner_tid; // Set only by exclusive owners. Tid owner_tid; // Set only by exclusive owners.
u64 last_lock; u64 last_lock;
int recursion; int recursion;
atomic_uint32_t flags; atomic_uint32_t flags;