{
ScopedInRtl in_rtl;
DestroyAndFree(atexit_ctx);
- REAL(usleep)(flags()->atexit_sleep_ms * 1000);
}
int status = Finalize(cur_thread());
if (status)
Context *ctx = __tsan::ctx;
bool failed = false;
+ if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
+ SleepForMillis(flags()->atexit_sleep_ms);
+
// Wait for pending reports.
ctx->report_mtx.Lock();
ctx->report_mtx.Unlock();
void ThreadJoin(ThreadState *thr, uptr pc, int tid);
void ThreadDetach(ThreadState *thr, uptr pc, int tid);
void ThreadFinalize(ThreadState *thr);
+int ThreadCount(ThreadState *thr);
void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
bool rw, bool recursive, bool linker_init);
}
}
+int ThreadCount(ThreadState *thr) {
+ CHECK_GT(thr->in_rtl, 0);
+ Context *ctx = CTX();
+ Lock l(&ctx->thread_mtx);
+ int cnt = 0;
+ for (unsigned i = 0; i < kMaxTid; i++) {
+ ThreadContext *tctx = ctx->threads[i];
+ if (tctx == 0)
+ continue;
+ if (tctx->status != ThreadStatusCreated
+ && tctx->status != ThreadStatusRunning)
+ continue;
+ cnt++;
+ }
+ return cnt;
+}
+
static void ThreadDead(ThreadState *thr, ThreadContext *tctx) {
Context *ctx = CTX();
CHECK_GT(thr->in_rtl, 0);