summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_thread_registry.cc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-03-19 12:25:48 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-03-19 12:25:48 +0000
commitce85e03620f64ce7e4cd0598f2e93090f52a9e99 (patch)
tree16b43363033c32c949b7b187e5d6cbe23219e1b0 /lib/sanitizer_common/sanitizer_thread_registry.cc
parent8e1c769ed84f4d5cf23904dee1abeec6f125f1ac (diff)
tsan: flush dead thread info earlier (when another thread is finished rather than new thread is created)
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@177394 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_thread_registry.cc')
-rw-r--r--lib/sanitizer_common/sanitizer_thread_registry.cc51
1 files changed, 32 insertions, 19 deletions
diff --git a/lib/sanitizer_common/sanitizer_thread_registry.cc b/lib/sanitizer_common/sanitizer_thread_registry.cc
index 3d246feee..5b3dacc56 100644
--- a/lib/sanitizer_common/sanitizer_thread_registry.cc
+++ b/lib/sanitizer_common/sanitizer_thread_registry.cc
@@ -77,11 +77,11 @@ void ThreadContextBase::SetCreated(uptr _user_id, u64 _unique_id,
OnCreated(arg);
}
-void ThreadContextBase::Reset(void *arg) {
+void ThreadContextBase::Reset() {
status = ThreadStatusInvalid;
reuse_count++;
SetName(0);
- OnReset(arg);
+ OnReset();
}
// ThreadRegistry implementation.
@@ -102,6 +102,7 @@ ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
threads_ = (ThreadContextBase **)MmapOrDie(max_threads_ * sizeof(threads_[0]),
"ThreadRegistry");
dead_threads_.clear();
+ invalid_threads_.clear();
}
void ThreadRegistry::GetNumberOfThreads(uptr *total, uptr *running,
@@ -121,25 +122,18 @@ u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
void *arg) {
BlockingMutexLock l(&mtx_);
u32 tid = kUnknownTid;
- ThreadContextBase *tctx = 0;
- if (dead_threads_.size() > thread_quarantine_size_ ||
- n_contexts_ >= max_threads_) {
- // Reusing old thread descriptor and tid.
- if (dead_threads_.size() == 0) {
- Report("%s: Thread limit (%u threads) exceeded. Dying.\n",
- SanitizerToolName, max_threads_);
- Die();
- }
- tctx = dead_threads_.front();
- dead_threads_.pop_front();
- CHECK_EQ(ThreadStatusDead, tctx->status);
- tctx->Reset(arg);
+ ThreadContextBase *tctx = QuarantinePop();
+ if (tctx) {
tid = tctx->tid;
- } else {
+ } else if (n_contexts_ < max_threads_) {
// Allocate new thread context and tid.
tid = n_contexts_++;
tctx = context_factory_(tid);
threads_[tid] = tctx;
+ } else {
+ Report("%s: Thread limit (%u threads) exceeded. Dying.\n",
+ SanitizerToolName, max_threads_);
+ Die();
}
CHECK_NE(tctx, 0);
CHECK_NE(tid, kUnknownTid);
@@ -207,7 +201,7 @@ void ThreadRegistry::DetachThread(u32 tid) {
}
if (tctx->status == ThreadStatusFinished) {
tctx->SetDead();
- dead_threads_.push_back(tctx);
+ QuarantinePush(tctx);
} else {
tctx->detached = true;
}
@@ -223,7 +217,7 @@ void ThreadRegistry::JoinThread(u32 tid, void *arg) {
return;
}
tctx->SetJoined(arg);
- dead_threads_.push_back(tctx);
+ QuarantinePush(tctx);
}
void ThreadRegistry::FinishThread(u32 tid) {
@@ -239,7 +233,7 @@ void ThreadRegistry::FinishThread(u32 tid) {
tctx->SetFinished();
if (tctx->detached) {
tctx->SetDead();
- dead_threads_.push_back(tctx);
+ QuarantinePush(tctx);
}
}
@@ -253,4 +247,23 @@ void ThreadRegistry::StartThread(u32 tid, uptr os_id, void *arg) {
tctx->SetStarted(os_id, arg);
}
+void ThreadRegistry::QuarantinePush(ThreadContextBase *tctx) {
+ dead_threads_.push_back(tctx);
+ if (dead_threads_.size() <= thread_quarantine_size_)
+ return;
+ tctx = dead_threads_.front();
+ dead_threads_.pop_front();
+ CHECK_EQ(tctx->status, ThreadStatusDead);
+ tctx->Reset();
+ invalid_threads_.push_back(tctx);
+}
+
+ThreadContextBase *ThreadRegistry::QuarantinePop() {
+ if (invalid_threads_.size() == 0)
+ return 0;
+ ThreadContextBase *tctx = invalid_threads_.front();
+ invalid_threads_.pop_front();
+ return tctx;
+}
+
} // namespace __sanitizer