Skip to content

Commit b4f647f

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#23397: Avoid excessive lock contention in CCheckQueue::Add
459e208 Exit early for an empty vChecks in CCheckQueue::Add (Hennadii Stepanov) c43aa62 Avoid excessive lock contention in CCheckQueue::Add (Hennadii Stepanov) Pull request description: This PR significantly reduces lock contention in the `CCheckQueue` class by releasing a mutex before calling `std::condition_variable::notify_one` and `std::condition_variable::notify_all`. From C++ [docs](https://en.cppreference.com/w/cpp/thread/condition_variable/notify_one): > The notifying thread does not need to hold the lock on the same mutex as the one held by the waiting thread(s); in fact doing so is a pessimization, since the notified thread would immediately block again, waiting for the notifying thread to release the lock. Related to: - #23167 - #23223 ACKs for top commit: martinus: ACK 459e208, codereview and tested. I first thought this introduced a segfault in `psbt_wallet_tests/psbt_updater_test` because that test failed for me, but thats a different issue fixed in #23403. vasild: ACK 459e208 theStack: Code-review ACK 459e208 Tree-SHA512: c197858656392ba3ebcd638d713cf93c9fb48b7b3bad193209490d2828f9c7e3ae4dee6f84674f2f34dceed894139562e29579ee7299e06756c8c990caddc5ed
2 parents e521c55 + 459e208 commit b4f647f

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/checkqueue.h

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,24 @@ class CCheckQueue
167167
//! Add a batch of checks to the queue
168168
void Add(std::vector<T>& vChecks)
169169
{
170-
LOCK(m_mutex);
171-
for (T& check : vChecks) {
172-
queue.push_back(T());
173-
check.swap(queue.back());
170+
if (vChecks.empty()) {
171+
return;
174172
}
175-
nTodo += vChecks.size();
176-
if (vChecks.size() == 1)
173+
174+
{
175+
LOCK(m_mutex);
176+
for (T& check : vChecks) {
177+
queue.emplace_back();
178+
check.swap(queue.back());
179+
}
180+
nTodo += vChecks.size();
181+
}
182+
183+
if (vChecks.size() == 1) {
177184
m_worker_cv.notify_one();
178-
else if (vChecks.size() > 1)
185+
} else {
179186
m_worker_cv.notify_all();
187+
}
180188
}
181189

182190
//! Stop all of the worker threads.

0 commit comments

Comments
 (0)