Commit d973a73e authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook GitHub Bot

Mitigate lock contention in BlockingWaitExecutor

Summary: `BlockingWaitExecutor::add` (and similarly `WaitExecutor`) posts the baton while holding the queue lock. If these happen in two different threads, the `drive()` thread wakes up while the lock is still held; the `add()` thread may be descheduled before the lock is released, causing the other thread to have to wait (and possibly sleep) for a while.

Reviewed By: andriigrynenko

Differential Revision: D25814620

fbshipit-source-id: 07d3e9afdc4647e68f996e3f0a1c007fd1596611
parent 1be254ba
......@@ -306,9 +306,12 @@ class BlockingWaitExecutor final : public folly::DrivableExecutor {
}
void add(Func func) override {
auto wQueue = queue_.wlock();
bool empty = wQueue->empty();
wQueue->push_back(std::move(func));
bool empty;
{
auto wQueue = queue_.wlock();
empty = wQueue->empty();
wQueue->push_back(std::move(func));
}
if (empty) {
baton_.post();
}
......
......@@ -478,12 +478,15 @@ FutureBase<T>::thenImplementation(
class WaitExecutor final : public folly::Executor {
public:
void add(Func func) override {
auto wQueue = queue_.wlock();
if (wQueue->detached) {
return;
bool empty;
{
auto wQueue = queue_.wlock();
if (wQueue->detached) {
return;
}
empty = wQueue->funcs.empty();
wQueue->funcs.push_back(std::move(func));
}
bool empty = wQueue->funcs.empty();
wQueue->funcs.push_back(std::move(func));
if (empty) {
baton_.post();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment