Search code examples
c++atomicc++20memory-barriers

std::memory_order for std::atomic<T>::wait


According to cppreference, in C++20 there are wait, notify_one, notify_all in std::atomic<T>. Looks like they make std::atomic<T> usable as a futex.

I'm asking why does wait accept std::memory_order as a parameter. As I always need to check if waking from wait is not spurious, I'll specify the memory order in corresponding load:

  std::atomic<bool> x;

  while (x.load(std::memory_order_acquire) == false)
  {
     x.wait(false, std::memory_order_acquire);
  }

Or should I specify std::memory_order_relaxed for wait? Are there scenarios with wait not followed by load?


Solution

  • I posted this issue to GitHub for this proposal, and got a response that std::atomic::wait is meant to be implemented on a futex with logic over it, specifically to mask spurious wakes.

    So, cppreference.com is wrong about this:

    These functions are allowed to unblock spuriously, i.e. return due to reasons other than value change or notification.

    And while loop is superfluous in my example, I should use just:

    std::atomic<bool> x;
    
    x.wait(false, std::memory_order_acquire);