[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(&registry);
 }
 


        


More information about the llvm-commits mailing list