[compiler-rt] 51aa61e - [hwasan] Fix lock contention on thread creation.
Evgenii Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 14 17:14:08 PDT 2021
Author: Evgenii Stepanov
Date: 2021-04-14T17:13:15-07:00
New Revision: 51aa61e74bdb394d89217350ddcb0fd04a21e32f
URL: https://github.com/llvm/llvm-project/commit/51aa61e74bdb394d89217350ddcb0fd04a21e32f
DIFF: https://github.com/llvm/llvm-project/commit/51aa61e74bdb394d89217350ddcb0fd04a21e32f.diff
LOG: [hwasan] Fix lock contention on thread creation.
Do not hold the free/live thread list lock longer than necessary.
This change speeds up the following benchmark 10x.
constexpr int kTopThreads = 50;
constexpr int kChildThreads = 20;
constexpr int kChildIterations = 8;
void Thread() {
for (int i = 0; i < kChildIterations; ++i) {
std::vector<std::thread> threads;
for (int i = 0; i < kChildThreads; ++i)
threads.emplace_back([](){});
for (auto& t : threads)
t.join();
}
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < kTopThreads; ++i)
threads.emplace_back(Thread);
for (auto& t : threads)
t.join();
}
Differential Revision: https://reviews.llvm.org/D100348
Added:
Modified:
compiler-rt/lib/hwasan/hwasan_thread_list.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/hwasan/hwasan_thread_list.h b/compiler-rt/lib/hwasan/hwasan_thread_list.h
index e596bde36662..3b89bad59cc3 100644
--- a/compiler-rt/lib/hwasan/hwasan_thread_list.h
+++ b/compiler-rt/lib/hwasan/hwasan_thread_list.h
@@ -86,17 +86,22 @@ class HwasanThreadList {
}
Thread *CreateCurrentThread() {
- Thread *t;
+ Thread *t = nullptr;
{
- SpinMutexLock l(&list_mutex_);
+ SpinMutexLock l(&free_list_mutex_);
if (!free_list_.empty()) {
t = free_list_.back();
free_list_.pop_back();
- uptr start = (uptr)t - ring_buffer_size_;
- internal_memset((void *)start, 0, ring_buffer_size_ + sizeof(Thread));
- } else {
- t = AllocThread();
}
+ }
+ if (t) {
+ uptr start = (uptr)t - ring_buffer_size_;
+ internal_memset((void *)start, 0, ring_buffer_size_ + sizeof(Thread));
+ } else {
+ t = AllocThread();
+ }
+ {
+ SpinMutexLock l(&live_list_mutex_);
live_list_.push_back(t);
}
t->Init((uptr)t - ring_buffer_size_, ring_buffer_size_);
@@ -110,6 +115,7 @@ class HwasanThreadList {
}
void RemoveThreadFromLiveList(Thread *t) {
+ SpinMutexLock l(&live_list_mutex_);
for (Thread *&t2 : live_list_)
if (t2 == t) {
// To remove t2, copy the last element of the list in t2's position, and
@@ -124,10 +130,10 @@ class HwasanThreadList {
void ReleaseThread(Thread *t) {
RemoveThreadStats(t);
t->Destroy();
- SpinMutexLock l(&list_mutex_);
+ DontNeedThread(t);
RemoveThreadFromLiveList(t);
+ SpinMutexLock l(&free_list_mutex_);
free_list_.push_back(t);
- DontNeedThread(t);
}
Thread *GetThreadByBufferAddress(uptr p) {
@@ -144,7 +150,7 @@ class HwasanThreadList {
template <class CB>
void VisitAllLiveThreads(CB cb) {
- SpinMutexLock l(&list_mutex_);
+ SpinMutexLock l(&live_list_mutex_);
for (Thread *t : live_list_) cb(t);
}
@@ -180,9 +186,10 @@ class HwasanThreadList {
uptr ring_buffer_size_;
uptr thread_alloc_size_;
+ SpinMutex free_list_mutex_;
InternalMmapVector<Thread *> free_list_;
+ SpinMutex live_list_mutex_;
InternalMmapVector<Thread *> live_list_;
- SpinMutex list_mutex_;
ThreadStats stats_;
SpinMutex stats_mutex_;
More information about the llvm-commits
mailing list