Commit 43e27ca3 authored by Anton Likhtarov's avatar Anton Likhtarov Committed by Facebook Github Bot

Remove spinning for fibers::Baton when waiting from a thread

Summary: This is not a good default. We can build a dedicated SpinningBaton if needed

Reviewed By: andriigrynenko

Differential Revision: D15387138

fbshipit-source-id: 433ce2b1af7c661edd2c0e264dc618cc9c680aa3
parent 598b2103
......@@ -59,11 +59,6 @@ void Baton::wait(TimeoutHandler& timeoutHandler) {
}
void Baton::waitThread() {
if (spinWaitForEarlyPost()) {
assert(waiter_.load(std::memory_order_acquire) == POSTED);
return;
}
auto waiter = waiter_.load();
if (LIKELY(
......@@ -90,31 +85,7 @@ void Baton::waitThread() {
throw std::logic_error("Other waiter is already waiting on this baton");
}
bool Baton::spinWaitForEarlyPost() {
static_assert(
PreBlockAttempts > 0,
"isn't this assert clearer than an uninitialized variable warning?");
for (int i = 0; i < PreBlockAttempts; ++i) {
if (try_wait()) {
// hooray!
return true;
}
// The pause instruction is the polite way to spin, but it doesn't
// actually affect correctness to omit it if we don't have it.
// Pausing donates the full capabilities of the current core to
// its other hyperthreads for a dozen cycles or so
asm_volatile_pause();
}
return false;
}
bool Baton::timedWaitThread(std::chrono::milliseconds timeout) {
if (spinWaitForEarlyPost()) {
assert(waiter_.load(std::memory_order_acquire) == POSTED);
return true;
}
auto waiter = waiter_.load();
if (LIKELY(
......
......@@ -236,25 +236,6 @@ class Baton {
private:
class FiberWaiter;
enum {
/**
* Must be positive. If multiple threads are actively using a
* higher-level data structure that uses batons internally, it is
* likely that the post() and wait() calls happen almost at the same
* time. In this state, we lose big 50% of the time if the wait goes
* to sleep immediately. On circa-2013 devbox hardware it costs about
* 7 usec to FUTEX_WAIT and then be awoken (half the t/iter as the
* posix_sem_pingpong test in BatonTests). We can improve our chances
* of early post by spinning for a bit, although we have to balance
* this against the loss if we end up sleeping any way. Spins on this
* hw take about 7 nanos (all but 0.5 nanos is the pause instruction).
* We give ourself 300 spins, which is about 2 usec of waiting. As a
* partial consolation, since we are using the pause instruction we
* are giving a speed boost to the colocated hyperthread.
*/
PreBlockAttempts = 300,
};
explicit Baton(intptr_t state) : waiter_(state) {}
void postHelper(intptr_t new_value);
......@@ -263,13 +244,6 @@ class Baton {
template <typename F>
inline void waitFiber(FiberManager& fm, F&& mainContextFunc);
/**
* Spin for "some time" (see discussion on PreBlockAttempts) waiting
* for a post.
* @return true if we received a post the spin wait, false otherwise. If the
* function returns true then Baton state is guaranteed to be POSTED
*/
bool spinWaitForEarlyPost();
bool timedWaitThread(std::chrono::milliseconds timeout);
......
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