Anton3
Anton3

Reputation: 586

What are the optimal std::memory_orders for this scenario of a coroutine waiting on an event?

I'm working on a coroutine multiple-producers, single-consumer Event (here it is, for context). Simplified:

class WaitList {
 public:
  void Append() { coro_.store(GetCurrentCoro()); }
  void Remove() { coro_.store({}); }

  void WakeUp() {
    auto p = coro_.exchange({});
    if (p) p->WakeUpIfSleeping();
  }

 private:
  std::atomic<Coro*> coro_{nullptr};
};

class Event {
 public:
  void Wait() {
    waiters_.Append();
    if (IsReady()) waiters_.WakeUp();
    // fall asleep
    // ...
    // woken up
    waiters_.Remove();
  }

  void Send() {
    SetReady();
    waiters_.WakeUp();
  }

 private:
  bool IsReady() { return signal_.load(); }
  void SetReady() { return signal_.store(true); }

  WaitList waiters_;
  std::atomic<bool> signal_{false};
};

Please help me set the minimum required std::memory_orders for:

  1. Append
  2. IsReady
  3. SetReady
  4. WakeUp (talking about the exchange)
  5. Remove

The primary platform is x86_64, but being optimal for other platforms is welcome. If there are multiple local minima, you can list them all (there is a finite number of theoretically possible combinations: sizeof(std::memory_order) ^ 5).

It seems to me that 1-4 require std::memory_order_seq_cst, because:

  1. If Append and IsReady are reordered from the POV of Send thread, then after the sequence IsReady-SetReady-WakeUp-Append the coroutine will fall asleep forever (right?)
  2. If SetReady and WakeUp are reordered from the POV of Wait thread, then after the sequence WakeUp-Append-IsReady-SetReady the coroutine will fall asleep forever (right?)

Given that we are dealing with two atomics (coro_ and signal_), I'd expect acquire-release not to be enough.

I know it is possible to squash coro_ and signal_ into a single std::uintptr_t or something, but let's leave them as they are for the purpose of this exercise. It's not as simple in reality: there are multiple synchronization primitives all based around the same ideas, and the current layout generalizes to them well.

Upvotes: 5

Views: 167

Answers (0)

Related Questions