summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc')
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc38
1 files changed, 28 insertions, 10 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
index e93a7a34ee4..35e97873a3b 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -143,26 +143,44 @@ void ThreadContext::OnFinished() {
thr = 0;
}
-static void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *unused) {
+#ifndef TSAN_GO
+struct ThreadLeak {
+ ThreadContext *tctx;
+ int count;
+};
+
+static void MaybeReportThreadLeak(ThreadContextBase *tctx_base, void *arg) {
+ Vector<ThreadLeak> &leaks = *(Vector<ThreadLeak>*)arg;
ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);
- if (tctx->detached)
+ if (tctx->detached || tctx->status != ThreadStatusFinished)
return;
- if (tctx->status != ThreadStatusCreated
- && tctx->status != ThreadStatusRunning
- && tctx->status != ThreadStatusFinished)
- return;
- ScopedReport rep(ReportTypeThreadLeak);
- rep.AddThread(tctx);
- OutputReport(CTX(), rep);
+ for (uptr i = 0; i < leaks.Size(); i++) {
+ if (leaks[i].tctx->creation_stack_id == tctx->creation_stack_id) {
+ leaks[i].count++;
+ return;
+ }
+ }
+ ThreadLeak leak = {tctx, 1};
+ leaks.PushBack(leak);
}
+#endif
void ThreadFinalize(ThreadState *thr) {
CHECK_GT(thr->in_rtl, 0);
+#ifndef TSAN_GO
if (!flags()->report_thread_leaks)
return;
ThreadRegistryLock l(CTX()->thread_registry);
+ Vector<ThreadLeak> leaks(MBlockScopedBuf);
CTX()->thread_registry->RunCallbackForEachThreadLocked(
- MaybeReportThreadLeak, 0);
+ MaybeReportThreadLeak, &leaks);
+ for (uptr i = 0; i < leaks.Size(); i++) {
+ ScopedReport rep(ReportTypeThreadLeak);
+ rep.AddThread(leaks[i].tctx);
+ rep.SetCount(leaks[i].count);
+ OutputReport(CTX(), rep);
+ }
+#endif
}
int ThreadCount(ThreadState *thr) {
OpenPOWER on IntegriCloud