[compiler-rt] b4a6fa1 - Revert "sanitizer_common: add simpler ThreadRegistry ctor"
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 12 12:04:23 PDT 2021
Author: Vitaly Buka
Date: 2021-07-12T12:04:12-07:00
New Revision: b4a6fa12d1fdcc9a446432218d9990a6c6797c83
URL: https://github.com/llvm/llvm-project/commit/b4a6fa12d1fdcc9a446432218d9990a6c6797c83
DIFF: https://github.com/llvm/llvm-project/commit/b4a6fa12d1fdcc9a446432218d9990a6c6797c83.diff
LOG: Revert "sanitizer_common: add simpler ThreadRegistry ctor"
Breaks https://lab.llvm.org/buildbot/#/builders/sanitizer-x86_64-linux-android
This reverts commit 6062c672bc5e560a4c3dc73741f9e82b39d08527.
This reverts commit 8e489b4b96e31cfb004e03cfa1393c425c504013.
Added:
Modified:
compiler-rt/lib/asan/asan_thread.cpp
compiler-rt/lib/asan/asan_thread.h
compiler-rt/lib/lsan/lsan_thread.cpp
compiler-rt/lib/memprof/memprof_thread.cpp
compiler-rt/lib/memprof/memprof_thread.h
compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h
compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp
index 35d4467e7b53a..7099850254875 100644
--- a/compiler-rt/lib/asan/asan_thread.cpp
+++ b/compiler-rt/lib/asan/asan_thread.cpp
@@ -60,8 +60,8 @@ ThreadRegistry &asanThreadRegistry() {
// in TSD and can't reliably tell when no more TSD destructors will
// be called. It would be wrong to reuse AsanThreadContext for another
// thread before all TSD destructors will be called for it.
- asan_thread_registry =
- new (thread_registry_placeholder) ThreadRegistry(GetAsanThreadContext);
+ asan_thread_registry = new(thread_registry_placeholder) ThreadRegistry(
+ GetAsanThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads);
initialized = true;
}
return *asan_thread_registry;
diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h
index 801a3960ec6cb..faa25d6964838 100644
--- a/compiler-rt/lib/asan/asan_thread.h
+++ b/compiler-rt/lib/asan/asan_thread.h
@@ -28,6 +28,8 @@ struct DTLS;
namespace __asan {
+const u32 kMaxNumberOfThreads = (1 << 22); // 4M
+
class AsanThread;
// These objects are created for every thread and are never deleted,
diff --git a/compiler-rt/lib/lsan/lsan_thread.cpp b/compiler-rt/lib/lsan/lsan_thread.cpp
index 1d224ebca693b..9003620dd8fb1 100644
--- a/compiler-rt/lib/lsan/lsan_thread.cpp
+++ b/compiler-rt/lib/lsan/lsan_thread.cpp
@@ -30,10 +30,13 @@ static ThreadContextBase *CreateThreadContext(u32 tid) {
return new (mem) ThreadContext(tid);
}
+static const uptr kMaxThreads = 1 << 22; // 4M
+static const uptr kThreadQuarantineSize = 64;
+
void InitializeThreadRegistry() {
static ALIGNED(64) char thread_registry_placeholder[sizeof(ThreadRegistry)];
- thread_registry =
- new (thread_registry_placeholder) ThreadRegistry(CreateThreadContext);
+ thread_registry = new (thread_registry_placeholder)
+ ThreadRegistry(CreateThreadContext, kMaxThreads, kThreadQuarantineSize);
}
ThreadContextLsanBase::ThreadContextLsanBase(int tid)
diff --git a/compiler-rt/lib/memprof/memprof_thread.cpp b/compiler-rt/lib/memprof/memprof_thread.cpp
index 5ae7a2ee85b99..0da811901f708 100644
--- a/compiler-rt/lib/memprof/memprof_thread.cpp
+++ b/compiler-rt/lib/memprof/memprof_thread.cpp
@@ -57,8 +57,8 @@ ThreadRegistry &memprofThreadRegistry() {
// in TSD and can't reliably tell when no more TSD destructors will
// be called. It would be wrong to reuse MemprofThreadContext for another
// thread before all TSD destructors will be called for it.
- memprof_thread_registry = new (thread_registry_placeholder)
- ThreadRegistry(GetMemprofThreadContext);
+ memprof_thread_registry = new (thread_registry_placeholder) ThreadRegistry(
+ GetMemprofThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads);
initialized = true;
}
return *memprof_thread_registry;
diff --git a/compiler-rt/lib/memprof/memprof_thread.h b/compiler-rt/lib/memprof/memprof_thread.h
index 4c9313fcb369e..a191b96b5b82a 100644
--- a/compiler-rt/lib/memprof/memprof_thread.h
+++ b/compiler-rt/lib/memprof/memprof_thread.h
@@ -27,6 +27,8 @@ struct DTLS;
namespace __memprof {
+const u32 kMaxNumberOfThreads = (1 << 22); // 4M
+
class MemprofThread;
// These objects are created for every thread and are never deleted,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
index 745fbf76b01f6..3273da38bfd6c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
@@ -99,9 +99,6 @@ void ThreadContextBase::Reset() {
// ThreadRegistry implementation.
-ThreadRegistry::ThreadRegistry(ThreadContextFactory factory)
- : ThreadRegistry(factory, UINT32_MAX, UINT32_MAX, 0) {}
-
ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
u32 thread_quarantine_size, u32 max_reuse)
: context_factory_(factory),
@@ -109,10 +106,13 @@ ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
thread_quarantine_size_(thread_quarantine_size),
max_reuse_(max_reuse),
mtx_(),
+ n_contexts_(0),
total_threads_(0),
alive_threads_(0),
max_alive_threads_(0),
running_threads_(0) {
+ threads_ = (ThreadContextBase **)MmapOrDie(max_threads_ * sizeof(threads_[0]),
+ "ThreadRegistry");
dead_threads_.clear();
invalid_threads_.clear();
}
@@ -120,8 +120,7 @@ ThreadRegistry::ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
void ThreadRegistry::GetNumberOfThreads(uptr *total, uptr *running,
uptr *alive) {
BlockingMutexLock l(&mtx_);
- if (total)
- *total = threads_.size();
+ if (total) *total = n_contexts_;
if (running) *running = running_threads_;
if (alive) *alive = alive_threads_;
}
@@ -138,11 +137,11 @@ u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
ThreadContextBase *tctx = QuarantinePop();
if (tctx) {
tid = tctx->tid;
- } else if (threads_.size() < max_threads_) {
+ } else if (n_contexts_ < max_threads_) {
// Allocate new thread context and tid.
- tid = threads_.size();
+ tid = n_contexts_++;
tctx = context_factory_(tid);
- threads_.push_back(tctx);
+ threads_[tid] = tctx;
} else {
#if !SANITIZER_GO
Report("%s: Thread limit (%u threads) exceeded. Dying.\n",
@@ -170,7 +169,7 @@ u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
void ThreadRegistry::RunCallbackForEachThreadLocked(ThreadCallback cb,
void *arg) {
CheckLocked();
- for (u32 tid = 0; tid < threads_.size(); tid++) {
+ for (u32 tid = 0; tid < n_contexts_; tid++) {
ThreadContextBase *tctx = threads_[tid];
if (tctx == 0)
continue;
@@ -180,7 +179,7 @@ void ThreadRegistry::RunCallbackForEachThreadLocked(ThreadCallback cb,
u32 ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) {
BlockingMutexLock l(&mtx_);
- for (u32 tid = 0; tid < threads_.size(); tid++) {
+ for (u32 tid = 0; tid < n_contexts_; tid++) {
ThreadContextBase *tctx = threads_[tid];
if (tctx != 0 && cb(tctx, arg))
return tctx->tid;
@@ -191,7 +190,7 @@ u32 ThreadRegistry::FindThread(FindThreadCallback cb, void *arg) {
ThreadContextBase *
ThreadRegistry::FindThreadContextLocked(FindThreadCallback cb, void *arg) {
CheckLocked();
- for (u32 tid = 0; tid < threads_.size(); tid++) {
+ for (u32 tid = 0; tid < n_contexts_; tid++) {
ThreadContextBase *tctx = threads_[tid];
if (tctx != 0 && cb(tctx, arg))
return tctx;
@@ -212,6 +211,7 @@ ThreadContextBase *ThreadRegistry::FindThreadContextByOsIDLocked(tid_t os_id) {
void ThreadRegistry::SetThreadName(u32 tid, const char *name) {
BlockingMutexLock l(&mtx_);
+ CHECK_LT(tid, n_contexts_);
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
CHECK_EQ(SANITIZER_FUCHSIA ? ThreadStatusCreated : ThreadStatusRunning,
@@ -221,7 +221,7 @@ void ThreadRegistry::SetThreadName(u32 tid, const char *name) {
void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {
BlockingMutexLock l(&mtx_);
- for (u32 tid = 0; tid < threads_.size(); tid++) {
+ for (u32 tid = 0; tid < n_contexts_; tid++) {
ThreadContextBase *tctx = threads_[tid];
if (tctx != 0 && tctx->user_id == user_id &&
tctx->status != ThreadStatusInvalid) {
@@ -233,6 +233,7 @@ void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char *name) {
void ThreadRegistry::DetachThread(u32 tid, void *arg) {
BlockingMutexLock l(&mtx_);
+ CHECK_LT(tid, n_contexts_);
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
if (tctx->status == ThreadStatusInvalid) {
@@ -253,6 +254,7 @@ void ThreadRegistry::JoinThread(u32 tid, void *arg) {
do {
{
BlockingMutexLock l(&mtx_);
+ CHECK_LT(tid, n_contexts_);
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
if (tctx->status == ThreadStatusInvalid) {
@@ -278,6 +280,7 @@ ThreadStatus ThreadRegistry::FinishThread(u32 tid) {
BlockingMutexLock l(&mtx_);
CHECK_GT(alive_threads_, 0);
alive_threads_--;
+ CHECK_LT(tid, n_contexts_);
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
bool dead = tctx->detached;
@@ -303,6 +306,7 @@ void ThreadRegistry::StartThread(u32 tid, tid_t os_id, ThreadType thread_type,
void *arg) {
BlockingMutexLock l(&mtx_);
running_threads_++;
+ CHECK_LT(tid, n_contexts_);
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
CHECK_EQ(ThreadStatusCreated, tctx->status);
@@ -335,6 +339,7 @@ ThreadContextBase *ThreadRegistry::QuarantinePop() {
void ThreadRegistry::SetThreadUserId(u32 tid, uptr user_id) {
BlockingMutexLock l(&mtx_);
+ CHECK_LT(tid, n_contexts_);
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
CHECK_NE(tctx->status, ThreadStatusInvalid);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h
index ded9e3af14065..1bbafd160243d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h
@@ -87,9 +87,8 @@ typedef ThreadContextBase* (*ThreadContextFactory)(u32 tid);
class MUTEX ThreadRegistry {
public:
- ThreadRegistry(ThreadContextFactory factory);
ThreadRegistry(ThreadContextFactory factory, u32 max_threads,
- u32 thread_quarantine_size, u32 max_reuse);
+ u32 thread_quarantine_size, u32 max_reuse = 0);
void GetNumberOfThreads(uptr *total = nullptr, uptr *running = nullptr,
uptr *alive = nullptr);
uptr GetMaxAliveThreads();
@@ -100,6 +99,7 @@ class MUTEX ThreadRegistry {
// Should be guarded by ThreadRegistryLock.
ThreadContextBase *GetThreadLocked(u32 tid) {
+ DCHECK_LT(tid, n_contexts_);
return threads_[tid];
}
@@ -137,13 +137,15 @@ class MUTEX ThreadRegistry {
BlockingMutex mtx_;
+ u32 n_contexts_; // Number of created thread contexts,
+ // at most max_threads_.
u64 total_threads_; // Total number of created threads. May be greater than
// max_threads_ if contexts were reused.
uptr alive_threads_; // Created or running.
uptr max_alive_threads_;
uptr running_threads_;
- InternalMmapVector<ThreadContextBase *> threads_;
+ ThreadContextBase **threads_; // Array of thread contexts is leaked.
IntrusiveList<ThreadContextBase> dead_threads_;
IntrusiveList<ThreadContextBase> invalid_threads_;
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cpp
index c87258fbac748..68b421baae2c8 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cpp
@@ -136,13 +136,13 @@ static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
TEST(SanitizerCommon, ThreadRegistryTest) {
ThreadRegistry quarantine_registry(GetThreadContext<ThreadContextBase>,
- kMaxRegistryThreads, kRegistryQuarantine,
- 0);
+ kMaxRegistryThreads,
+ kRegistryQuarantine);
TestRegistry(&quarantine_registry, true);
ThreadRegistry no_quarantine_registry(GetThreadContext<ThreadContextBase>,
kMaxRegistryThreads,
- kMaxRegistryThreads, 0);
+ kMaxRegistryThreads);
TestRegistry(&no_quarantine_registry, false);
}
@@ -227,7 +227,7 @@ TEST(SanitizerCommon, ThreadRegistryThreadedTest) {
memset(&num_joined, 0, sizeof(num_created));
ThreadRegistry registry(GetThreadContext<TestThreadContext>,
- kThreadsPerShard * kNumShards + 1, 10, 0);
+ kThreadsPerShard * kNumShards + 1, 10);
ThreadedTestRegistry(®istry);
}
More information about the llvm-commits
mailing list