Remove multi-poster support from Baton
[folly.git] / folly / synchronization / Baton.h
index ef87125..379f902 100644 (file)
 
 namespace folly {
 
-/// A Baton allows a thread to block once and be awoken. The single
-/// poster version (with SinglePoster == true) captures a single
-/// handoff, and during its lifecycle (from construction/reset to
-/// destruction/reset) a baton must either be post()ed and wait()ed
+/// A Baton allows a thread to block once and be awoken. Captures a
+/// single handoff, and during its lifecycle (from construction/reset
+/// to destruction/reset) a baton must either be post()ed and wait()ed
 /// exactly once each, or not at all.
 ///
-/// The multi-poster version (SinglePoster == false) allows multiple
-/// concurrent handoff attempts, the first of which completes the
-/// handoff and the rest if any are idempotent.
-///
 /// Baton includes no internal padding, and is only 4 bytes in size.
 /// Any alignment or padding to avoid false sharing is up to the user.
 ///
-/// This is basically a stripped-down semaphore that supports (only a
-/// single call to sem_post, when SinglePoster == true) and a single
-/// call to sem_wait.
+/// This is basically a stripped-down semaphore that supports only a
+/// single call to sem_post and a single call to sem_wait.
 ///
 /// The non-blocking version (Blocking == false) provides more speed
 /// by using only load acquire and store release operations in the
@@ -58,7 +52,6 @@ namespace folly {
 /// catch race conditions ahead of time.
 template <
     template <typename> class Atom = std::atomic,
-    bool SinglePoster = true, //  single vs multiple posters
     bool Blocking = true> // blocking vs spinning
 struct Baton {
   constexpr Baton() : state_(INIT) {}
@@ -130,65 +123,24 @@ struct Baton {
 
     /// Blocking versions
     ///
-    if (SinglePoster) {
-      /// Single poster version
-      ///
-      uint32_t before = state_.load(std::memory_order_acquire);
+    uint32_t before = state_.load(std::memory_order_acquire);
 
-      assert(before == INIT || before == WAITING || before == TIMED_OUT);
+    assert(before == INIT || before == WAITING || before == TIMED_OUT);
 
-      if (before == INIT &&
-          state_.compare_exchange_strong(before, EARLY_DELIVERY)) {
-        return;
-      }
-
-      assert(before == WAITING || before == TIMED_OUT);
+    if (before == INIT &&
+        state_.compare_exchange_strong(before, EARLY_DELIVERY)) {
+      return;
+    }
 
-      if (before == TIMED_OUT) {
-        return;
-      }
+    assert(before == WAITING || before == TIMED_OUT);
 
-      assert(before == WAITING);
-      state_.store(LATE_DELIVERY, std::memory_order_release);
-      state_.futexWake(1);
-    } else {
-      /// Multi-poster version
-      ///
-      while (true) {
-        uint32_t before = state_.load(std::memory_order_acquire);
-
-        if (before == INIT &&
-            state_.compare_exchange_strong(before, EARLY_DELIVERY)) {
-          return;
-        }
-
-        if (before == TIMED_OUT) {
-          return;
-        }
-
-        if (before == EARLY_DELIVERY || before == LATE_DELIVERY) {
-          // The reason for not simply returning (without the following
-          // atomic operation) is to avoid the following case:
-          //
-          //  T1:             T2:             T3:
-          //  local1.post();  local2.post();  global.wait();
-          //  global.post();  global.post();  local1.try_wait() == true;
-          //                                  local2.try_wait() == false;
-          //
-          if (state_.fetch_add(0) != before) {
-            continue;
-          }
-          return;
-        }
-
-        assert(before == WAITING);
-        if (!state_.compare_exchange_weak(before, LATE_DELIVERY)) {
-          continue;
-        }
-        state_.futexWake(1);
-        return;
-      }
+    if (before == TIMED_OUT) {
+      return;
     }
+
+    assert(before == WAITING);
+    state_.store(LATE_DELIVERY, std::memory_order_release);
+    state_.futexWake(1);
   }
 
   /// Waits until post() has been called in the current Baton lifetime.