proxygen
folly::fibers::Baton Class Reference

#include <Baton.h>

Classes

class  FiberWaiter
 
class  TimeoutHandler
 
class  Waiter
 

Public Member Functions

 Baton () noexcept
 
 ~Baton () noexcept=default
 
bool ready () const
 
void setWaiter (Waiter &waiter)
 
void wait ()
 
void wait (TimeoutHandler &timeoutHandler)
 
template<typename F >
void wait (F &&mainContextFunc)
 
bool try_wait ()
 
template<typename Rep , typename Period >
bool try_wait_for (const std::chrono::duration< Rep, Period > &timeout)
 
template<typename Rep , typename Period , typename F >
bool try_wait_for (const std::chrono::duration< Rep, Period > &timeout, F &&mainContextFunc)
 
template<typename Clock , typename Duration >
bool try_wait_until (const std::chrono::time_point< Clock, Duration > &deadline)
 
template<typename Clock , typename Duration , typename F >
bool try_wait_until (const std::chrono::time_point< Clock, Duration > &deadline, F &&mainContextFunc)
 
template<typename Clock , typename Duration , typename F >
bool try_wait_for (const std::chrono::time_point< Clock, Duration > &deadline, F &&mainContextFunc)
 
template<typename Rep , typename Period >
bool timed_wait (const std::chrono::duration< Rep, Period > &timeout)
 Alias to try_wait_for. Deprecated. More...
 
template<typename Rep , typename Period , typename F >
bool timed_wait (const std::chrono::duration< Rep, Period > &timeout, F &&mainContextFunc)
 Alias to try_wait_for. Deprecated. More...
 
template<typename Clock , typename Duration >
bool timed_wait (const std::chrono::time_point< Clock, Duration > &deadline)
 Alias to try_wait_until. Deprecated. More...
 
template<typename Clock , typename Duration , typename F >
bool timed_wait (const std::chrono::time_point< Clock, Duration > &deadline, F &&mainContextFunc)
 Alias to try_wait_until. Deprecated. More...
 
void post ()
 
void reset ()
 

Private Types

enum  { PreBlockAttempts = 300 }
 

Private Member Functions

 Baton (intptr_t state)
 
void postHelper (intptr_t new_value)
 
void postThread ()
 
void waitThread ()
 
template<typename F >
void waitFiber (FiberManager &fm, F &&mainContextFunc)
 
bool spinWaitForEarlyPost ()
 
bool timedWaitThread (TimeoutController::Duration timeout)
 

Private Attributes

union {
   std::atomic< intptr_t >   waiter_
 
   struct {
      folly::detail::Futex   futex {}
 
      int32_t   _unused_packing
 
   }   futex_
 
}; 
 

Static Private Attributes

static constexpr intptr_t NO_WAITER = 0
 
static constexpr intptr_t POSTED = -1
 
static constexpr intptr_t TIMEOUT = -2
 
static constexpr intptr_t THREAD_WAITING = -3
 

Detailed Description

Primitive which allows one to put current Fiber to sleep and wake it from another Fiber/thread.

Definition at line 40 of file Baton.h.

Member Enumeration Documentation

anonymous enum
private
Enumerator
PreBlockAttempts 

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.

Definition at line 236 of file Baton.h.

236  {
252  PreBlockAttempts = 300,
253  };

Constructor & Destructor Documentation

folly::fibers::Baton::Baton ( )
inlinenoexcept

Definition at line 37 of file Baton-inl.h.

References futex_, POSTED, THREAD_WAITING, TIMEOUT, and waiter_.

Referenced by folly::fibers::Baton::Waiter::~Waiter().

37  : Baton(NO_WAITER) {
38  assert(Baton(NO_WAITER).futex_.futex == static_cast<uint32_t>(NO_WAITER));
39  assert(Baton(POSTED).futex_.futex == static_cast<uint32_t>(POSTED));
40  assert(Baton(TIMEOUT).futex_.futex == static_cast<uint32_t>(TIMEOUT));
41  assert(
42  Baton(THREAD_WAITING).futex_.futex ==
43  static_cast<uint32_t>(THREAD_WAITING));
44 
45  assert(futex_.futex.is_lock_free());
46  assert(waiter_.is_lock_free());
47 }
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
Baton() noexcept
Definition: Baton-inl.h:37
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
struct folly::fibers::Baton::@51::@53 futex_
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
static constexpr intptr_t THREAD_WAITING
Definition: Baton.h:276
folly::fibers::Baton::~Baton ( )
defaultnoexcept
folly::fibers::Baton::Baton ( intptr_t  state)
inlineexplicitprivate

Definition at line 255 of file Baton.h.

References postHelper(), postThread(), spinWaitForEarlyPost(), timedWaitThread(), waitFiber(), and waitThread().

255 : waiter_(state) {}
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
state
Definition: http_parser.c:272

Member Function Documentation

void folly::fibers::Baton::post ( )

Wakes up Fiber which was waiting on this Baton (or if no Fiber is waiting, next wait() call will return immediately).

Definition at line 150 of file Baton.cpp.

References POSTED, and postHelper().

Referenced by folly::coro::detail::BlockingWaitPromiseBase::FinalAwaiter::await_suspend(), postHelper(), TEST(), and folly::fibers::TimedMutex::unlock().

150  {
152 }
static constexpr intptr_t POSTED
Definition: Baton.h:274
void postHelper(intptr_t new_value)
Definition: Baton.cpp:154
void folly::fibers::Baton::postHelper ( intptr_t  new_value)
private

Definition at line 154 of file Baton.cpp.

References NO_WAITER, post(), POSTED, postThread(), THREAD_WAITING, TIMEOUT, and waiter_.

Referenced by Baton(), post(), and wait().

154  {
155  auto waiter = waiter_.load();
156 
157  do {
158  if (waiter == THREAD_WAITING) {
159  assert(new_value == POSTED);
160 
161  return postThread();
162  }
163 
164  if (waiter == POSTED || waiter == TIMEOUT) {
165  return;
166  }
167  } while (!waiter_.compare_exchange_weak(waiter, new_value));
168 
169  if (waiter != NO_WAITER) {
170  reinterpret_cast<Waiter*>(waiter)->post();
171  }
172 }
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
static constexpr intptr_t THREAD_WAITING
Definition: Baton.h:276
void folly::fibers::Baton::postThread ( )
private

Definition at line 178 of file Baton.cpp.

References futex, futex_, folly::detail::futexWake(), POSTED, THREAD_WAITING, and waiter_.

Referenced by Baton(), and postHelper().

178  {
179  auto expected = THREAD_WAITING;
180 
181  auto* futex = &futex_.futex;
182  if (!waiter_.compare_exchange_strong(expected, POSTED)) {
183  return;
184  }
185  futexWake(futex, 1);
186 }
static constexpr intptr_t POSTED
Definition: Baton.h:274
struct folly::fibers::Baton::@51::@53 futex_
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
static constexpr intptr_t THREAD_WAITING
Definition: Baton.h:276
folly::detail::Futex futex
Definition: Baton.h:281
int futexWake(const Futex *futex, int count, uint32_t wakeMask)
Definition: Futex-inl.h:107
bool folly::fibers::Baton::ready ( ) const
inline

Definition at line 55 of file Baton.h.

References POSTED, setWaiter(), try_wait(), wait(), and waiter_.

Referenced by try_wait().

55  {
56  auto state = waiter_.load();
57  return state == POSTED;
58  }
static constexpr intptr_t POSTED
Definition: Baton.h:274
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
state
Definition: http_parser.c:272
void folly::fibers::Baton::reset ( )

Reset's the baton (equivalent to destroying the object and constructing another one in place). Caller is responsible for making sure no one is waiting on/posting the baton when reset() is called.

Definition at line 188 of file Baton.cpp.

References NO_WAITER, and waiter_.

Referenced by timed_wait().

188  {
189  waiter_.store(NO_WAITER, std::memory_order_relaxed);
190 }
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
void folly::fibers::Baton::setWaiter ( Waiter waiter)

Registers a waiter for the baton. The waiter will be notified when the baton is posted.

Definition at line 30 of file Baton.cpp.

References LIKELY, NO_WAITER, folly::fibers::Baton::Waiter::post(), POSTED, TIMEOUT, and waiter_.

Referenced by ready(), and waitFiber().

30  {
31  auto curr_waiter = waiter_.load();
32  do {
33  if (LIKELY(curr_waiter == NO_WAITER)) {
34  continue;
35  } else if (curr_waiter == POSTED || curr_waiter == TIMEOUT) {
36  waiter.post();
37  break;
38  } else {
39  throw std::logic_error("Some waiter is already waiting on this Baton.");
40  }
41  } while (!waiter_.compare_exchange_weak(
42  curr_waiter, reinterpret_cast<intptr_t>(&waiter)));
43 }
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
#define LIKELY(x)
Definition: Likely.h:47
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
bool folly::fibers::Baton::spinWaitForEarlyPost ( )
private

Spin for "some time" (see discussion on PreBlockAttempts) waiting for a post.

Returns
true if we received a post the spin wait, false otherwise. If the function returns true then Baton state is guaranteed to be POSTED

Definition at line 94 of file Baton.cpp.

References folly::asm_volatile_pause(), i, PreBlockAttempts, and try_wait().

Referenced by Baton(), timedWaitThread(), and waitThread().

94  {
95  static_assert(
96  PreBlockAttempts > 0,
97  "isn't this assert clearer than an uninitialized variable warning?");
98  for (int i = 0; i < PreBlockAttempts; ++i) {
99  if (try_wait()) {
100  // hooray!
101  return true;
102  }
103  // The pause instruction is the polite way to spin, but it doesn't
104  // actually affect correctness to omit it if we don't have it.
105  // Pausing donates the full capabilities of the current core to
106  // its other hyperthreads for a dozen cycles or so
108  }
109 
110  return false;
111 }
void asm_volatile_pause()
Definition: Asm.h:37
template<typename Rep , typename Period >
bool folly::fibers::Baton::timed_wait ( const std::chrono::duration< Rep, Period > &  timeout)
inline

Alias to try_wait_for. Deprecated.

Definition at line 170 of file Baton.h.

References try_wait_for().

170  {
171  return try_wait_for(timeout);
172  }
bool try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: Baton.h:105
template<typename Rep , typename Period , typename F >
bool folly::fibers::Baton::timed_wait ( const std::chrono::duration< Rep, Period > &  timeout,
F &&  mainContextFunc 
)
inline

Alias to try_wait_for. Deprecated.

Definition at line 176 of file Baton.h.

References try_wait_for().

178  {
179  return try_wait_for(timeout, static_cast<F&&>(mainContextFunc));
180  }
bool try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: Baton.h:105
template<typename Clock , typename Duration >
bool folly::fibers::Baton::timed_wait ( const std::chrono::time_point< Clock, Duration > &  deadline)
inline

Alias to try_wait_until. Deprecated.

Definition at line 184 of file Baton.h.

References try_wait_until().

184  {
185  return try_wait_until(deadline);
186  }
bool try_wait_until(const std::chrono::time_point< Clock, Duration > &deadline)
Definition: Baton.h:133
template<typename Clock , typename Duration , typename F >
bool folly::fibers::Baton::timed_wait ( const std::chrono::time_point< Clock, Duration > &  deadline,
F &&  mainContextFunc 
)
inline

Alias to try_wait_until. Deprecated.

Definition at line 190 of file Baton.h.

References folly::fibers::Baton::Waiter::post(), reset(), and try_wait_until().

192  {
193  return try_wait_until(deadline, static_cast<F&&>(mainContextFunc));
194  }
bool try_wait_until(const std::chrono::time_point< Clock, Duration > &deadline)
Definition: Baton.h:133
bool folly::fibers::Baton::timedWaitThread ( TimeoutController::Duration  timeout)
private

Definition at line 113 of file Baton.cpp.

References futex, futex_, futexWaitUntil(), LIKELY, NO_WAITER, now(), POSTED, spinWaitForEarlyPost(), THREAD_WAITING, folly::detail::TIMEDOUT, TIMEOUT, uint32_t, and waiter_.

Referenced by Baton(), and try_wait_for().

113  {
114  if (spinWaitForEarlyPost()) {
115  assert(waiter_.load(std::memory_order_acquire) == POSTED);
116  return true;
117  }
118 
119  auto waiter = waiter_.load();
120 
121  if (LIKELY(
122  waiter == NO_WAITER &&
123  waiter_.compare_exchange_strong(waiter, THREAD_WAITING))) {
124  auto deadline = TimeoutController::Clock::now() + timeout;
125  do {
126  auto* futex = &futex_.futex;
127  const auto wait_rv =
129  if (wait_rv == folly::detail::FutexResult::TIMEDOUT) {
130  return false;
131  }
132  waiter = waiter_.load(std::memory_order_relaxed);
133  } while (waiter == THREAD_WAITING);
134  }
135 
136  if (LIKELY(waiter == POSTED)) {
137  return true;
138  }
139 
140  // Handle errors
141  if (waiter == TIMEOUT) {
142  throw std::logic_error("Thread baton can't have timeout status");
143  }
144  if (waiter == THREAD_WAITING) {
145  throw std::logic_error("Other thread is already waiting on this baton");
146  }
147  throw std::logic_error("Other waiter is already waiting on this baton");
148 }
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
FutexResult futexWaitUntil(const Futex< MockAtom > *futex, std::uint32_t expected, std::chrono::time_point< Clock, Duration > const &deadline, uint32_t waitMask)
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
struct folly::fibers::Baton::@51::@53 futex_
std::chrono::steady_clock::time_point now()
#define LIKELY(x)
Definition: Likely.h:47
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
static constexpr intptr_t THREAD_WAITING
Definition: Baton.h:276
folly::detail::Futex futex
Definition: Baton.h:281
bool spinWaitForEarlyPost()
Definition: Baton.cpp:94
bool folly::fibers::Baton::try_wait ( )

Checks if the baton has been posted without blocking.

Returns
true iff the baton has been posted.

Definition at line 174 of file Baton.cpp.

References ready().

Referenced by ready(), spinWaitForEarlyPost(), TEST(), and wait().

174  {
175  return ready();
176 }
bool ready() const
Definition: Baton.h:55
template<typename Rep , typename Period >
bool folly::fibers::Baton::try_wait_for ( const std::chrono::duration< Rep, Period > &  timeout)
inline

Puts active fiber to sleep. Returns when post is called or the timeout expires.

Parameters
timeoutBaton will be automatically awaken if timeout expires
Returns
true if was posted, false if timeout expired

Definition at line 105 of file Baton.h.

References folly::detail::timeout.

Referenced by TEST(), folly::fibers::TimedMutex::timed_lock(), timed_wait(), and try_wait_until().

105  {
106  return try_wait_for(timeout, [] {});
107  }
bool try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: Baton.h:105
template<typename Rep , typename Period , typename F >
bool folly::fibers::Baton::try_wait_for ( const std::chrono::duration< Rep, Period > &  timeout,
F &&  mainContextFunc 
)

Puts active fiber to sleep. Returns when post is called or the timeout expires.

Parameters
timeoutBaton will be automatically awaken if timeout expires
mainContextFuncthis function is immediately executed on the main context.
Returns
true if was posted, false if timeout expired

Definition at line 75 of file Baton-inl.h.

References folly::fibers::FiberManager::getFiberManagerUnsafe(), POSTED, timedWaitThread(), TIMEOUT, waiter_, and waitFiber().

77  {
79 
80  if (!fm || !fm->activeFiber_) {
81  mainContextFunc();
82  return timedWaitThread(timeout);
83  }
84 
85  auto& baton = *this;
86  bool canceled = false;
87  auto timeoutFunc = [&baton, &canceled]() mutable {
88  baton.postHelper(TIMEOUT);
89  canceled = true;
90  };
91 
92  auto id =
93  fm->timeoutManager_->registerTimeout(std::ref(timeoutFunc), timeout);
94 
95  waitFiber(*fm, static_cast<F&&>(mainContextFunc));
96 
97  auto posted = waiter_ == POSTED;
98 
99  if (!canceled) {
100  fm->timeoutManager_->cancel(id);
101  }
102 
103  return posted;
104 }
static constexpr intptr_t POSTED
Definition: Baton.h:274
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
bool timedWaitThread(TimeoutController::Duration timeout)
Definition: Baton.cpp:113
static FiberManager * getFiberManagerUnsafe()
void waitFiber(FiberManager &fm, F &&mainContextFunc)
Definition: Baton-inl.h:61
template<typename Clock , typename Duration , typename F >
bool folly::fibers::Baton::try_wait_for ( const std::chrono::time_point< Clock, Duration > &  deadline,
F &&  mainContextFunc 
)

Puts active fiber to sleep. Returns when post is called or the deadline expires.

Parameters
timeoutBaton will be automatically awaken if deadline expires
mainContextFuncthis function is immediately executed on the main context.
Returns
true if was posted, false if timeout expired
template<typename Clock , typename Duration >
bool folly::fibers::Baton::try_wait_until ( const std::chrono::time_point< Clock, Duration > &  deadline)
inline

Puts active fiber to sleep. Returns when post is called or the deadline expires.

Parameters
timeoutBaton will be automatically awaken if deadline expires
Returns
true if was posted, false if timeout expired

Definition at line 133 of file Baton.h.

References try_wait_for().

Referenced by timed_wait().

134  {
135  return try_wait_until(deadline, [] {});
136  }
bool try_wait_until(const std::chrono::time_point< Clock, Duration > &deadline)
Definition: Baton.h:133
template<typename Clock , typename Duration , typename F >
bool folly::fibers::Baton::try_wait_until ( const std::chrono::time_point< Clock, Duration > &  deadline,
F &&  mainContextFunc 
)

Puts active fiber to sleep. Returns when post is called or the deadline expires.

Parameters
timeoutBaton will be automatically awaken if deadline expires
mainContextFuncthis function is immediately executed on the main context.
Returns
true if was posted, false if timeout expired

Definition at line 107 of file Baton-inl.h.

References LIKELY, now(), and try_wait_for().

109  {
110  auto now = Clock::now();
111 
112  if (LIKELY(now <= deadline)) {
113  return try_wait_for(deadline - now, static_cast<F&&>(mainContextFunc));
114  } else {
115  return try_wait_for(Duration{}, static_cast<F&&>(mainContextFunc));
116  }
117 }
std::chrono::steady_clock::time_point now()
#define LIKELY(x)
Definition: Likely.h:47
StatsClock::duration Duration
bool try_wait_for(const std::chrono::duration< Rep, Period > &timeout)
Definition: Baton.h:105
void folly::fibers::Baton::wait ( )

Puts active fiber to sleep. Returns when post is called.

Definition at line 45 of file Baton.cpp.

Referenced by folly::fibers::forEach(), folly::fibers::TimedMutex::lock(), ready(), TEST(), folly::coro::detail::BlockingWaitPromiseBase::wait(), wait(), and folly::fibers::Semaphore::waitSlow().

45  {
46  wait([]() {});
47 }
void folly::fibers::Baton::wait ( TimeoutHandler timeoutHandler)

Put active fiber to sleep indefinitely. However, timeoutHandler may be used elsewhere on the same thread in order to schedule a wakeup for the active fiber. Users of timeoutHandler must be on the same thread as the active fiber and may only schedule one timeout, which must occur after the active fiber calls wait.

Definition at line 49 of file Baton.cpp.

References folly::fibers::Baton::TimeoutHandler::cancelTimeout(), folly::fibers::Baton::TimeoutHandler::fiberManager_, folly::fibers::FiberManager::getFiberManagerUnsafe(), postHelper(), TIMEOUT, folly::fibers::Baton::TimeoutHandler::timeoutFunc_, folly::fibers::Baton::TimeoutHandler::timeoutPtr_, try_wait(), and wait().

49  {
50  auto timeoutFunc = [this, &timeoutHandler] {
51  if (!try_wait()) {
53  }
54  timeoutHandler.timeoutPtr_ = 0;
55  };
56  timeoutHandler.timeoutFunc_ = std::ref(timeoutFunc);
57  timeoutHandler.fiberManager_ = FiberManager::getFiberManagerUnsafe();
58  wait();
59  timeoutHandler.cancelTimeout();
60 }
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
static FiberManager * getFiberManagerUnsafe()
void postHelper(intptr_t new_value)
Definition: Baton.cpp:154
template<typename F >
void folly::fibers::Baton::wait ( F &&  mainContextFunc)

Puts active fiber to sleep. Returns when post is called.

Parameters
mainContextFuncthis function is immediately executed on the main context.

Definition at line 50 of file Baton-inl.h.

References folly::fibers::FiberManager::getFiberManagerUnsafe(), waitFiber(), and waitThread().

50  {
52  if (!fm || !fm->activeFiber_) {
53  mainContextFunc();
54  return waitThread();
55  }
56 
57  return waitFiber(*fm, std::forward<F>(mainContextFunc));
58 }
static FiberManager * getFiberManagerUnsafe()
void waitFiber(FiberManager &fm, F &&mainContextFunc)
Definition: Baton-inl.h:61
template<typename F >
void folly::fibers::Baton::waitFiber ( FiberManager fm,
F &&  mainContextFunc 
)
inlineprivate

Definition at line 61 of file Baton-inl.h.

References folly::fibers::FiberManager::activeFiber_, folly::fibers::FiberManager::awaitFunc_, folly::fibers::Fiber::AWAITING, f, folly::fibers::Fiber::preempt(), folly::fibers::Baton::FiberWaiter::setFiber(), and setWaiter().

Referenced by Baton(), try_wait_for(), and wait().

61  {
62  FiberWaiter waiter;
63  auto f = [this, &mainContextFunc, &waiter](Fiber& fiber) mutable {
64  waiter.setFiber(fiber);
65  setWaiter(waiter);
66 
67  mainContextFunc();
68  };
69 
70  fm.awaitFunc_ = std::ref(f);
71  fm.activeFiber_->preempt(Fiber::AWAITING);
72 }
auto f
void setWaiter(Waiter &waiter)
Definition: Baton.cpp:30
void folly::fibers::Baton::waitThread ( )
private

Definition at line 62 of file Baton.cpp.

References futex_, folly::detail::MemoryIdler::futexWait(), LIKELY, NO_WAITER, POSTED, spinWaitForEarlyPost(), THREAD_WAITING, TIMEOUT, uint32_t, and waiter_.

Referenced by Baton(), and wait().

62  {
63  if (spinWaitForEarlyPost()) {
64  assert(waiter_.load(std::memory_order_acquire) == POSTED);
65  return;
66  }
67 
68  auto waiter = waiter_.load();
69 
70  if (LIKELY(
71  waiter == NO_WAITER &&
72  waiter_.compare_exchange_strong(waiter, THREAD_WAITING))) {
73  do {
76  waiter = waiter_.load(std::memory_order_acquire);
77  } while (waiter == THREAD_WAITING);
78  }
79 
80  if (LIKELY(waiter == POSTED)) {
81  return;
82  }
83 
84  // Handle errors
85  if (waiter == TIMEOUT) {
86  throw std::logic_error("Thread baton can't have timeout status");
87  }
88  if (waiter == THREAD_WAITING) {
89  throw std::logic_error("Other thread is already waiting on this baton");
90  }
91  throw std::logic_error("Other waiter is already waiting on this baton");
92 }
static constexpr intptr_t NO_WAITER
Definition: Baton.h:273
static constexpr intptr_t POSTED
Definition: Baton.h:274
static FutexResult futexWait(Futex &fut, uint32_t expected, uint32_t waitMask=-1, IdleTime const &idleTimeout=defaultIdleTimeout.load(std::memory_order_acquire), size_t stackToRetain=kDefaultStackToRetain, float timeoutVariationFrac=0.5)
Definition: MemoryIdler.h:102
static constexpr intptr_t TIMEOUT
Definition: Baton.h:275
struct folly::fibers::Baton::@51::@53 futex_
#define LIKELY(x)
Definition: Likely.h:47
std::atomic< intptr_t > waiter_
Definition: Baton.h:279
static constexpr intptr_t THREAD_WAITING
Definition: Baton.h:276
bool spinWaitForEarlyPost()
Definition: Baton.cpp:94

Member Data Documentation

union { ... }
int32_t folly::fibers::Baton::_unused_packing

Definition at line 282 of file Baton.h.

folly::detail::Futex folly::fibers::Baton::futex {}

Definition at line 281 of file Baton.h.

Referenced by postThread(), and timedWaitThread().

struct { ... } folly::fibers::Baton::futex_
constexpr intptr_t folly::fibers::Baton::NO_WAITER = 0
staticprivate

Definition at line 273 of file Baton.h.

Referenced by postHelper(), reset(), setWaiter(), timedWaitThread(), and waitThread().

constexpr intptr_t folly::fibers::Baton::POSTED = -1
staticprivate
constexpr intptr_t folly::fibers::Baton::THREAD_WAITING = -3
staticprivate

Definition at line 276 of file Baton.h.

Referenced by Baton(), postHelper(), postThread(), timedWaitThread(), and waitThread().

constexpr intptr_t folly::fibers::Baton::TIMEOUT = -2
staticprivate

Definition at line 275 of file Baton.h.

Referenced by Baton(), postHelper(), setWaiter(), timedWaitThread(), try_wait_for(), wait(), and waitThread().

std::atomic<intptr_t> folly::fibers::Baton::waiter_

The documentation for this class was generated from the following files: