title: Using std::atomic with futex system call
body: <p>In C++20, we got the capability to sleep on atomic variables, waiting for their value to change.
  We do so by using the <a href="https://en.cppreference.com/w/cpp/atomic/atomic/wait" rel="noreferrer"><code>std::atomic::wait</code></a> method.</p>
  <p>Unfortunately, while <code>wait</code> has been standardized, <code>wait_for</code> and <code>wait_until</code> are not. Meaning that we cannot sleep on an atomic variable with a timeout.</p>
  <p>Sleeping on an atomic variable is anyway implemented behind the scenes with <a href="https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress" rel="noreferrer">WaitOnAddress</a> on Windows and the <a href="https://man7.org/linux/man-pages/man2/futex.2.html" rel="noreferrer">futex</a> system call on Linux.</p>
  <p>Working around the above problem (no way to sleep on an atomic variable with a timeout), I could pass the memory address of an <code>std::atomic</code> to <code>WaitOnAddress</code> on Windows and it will (kinda) work with no UB, as the function gets <code>void*</code> as a parameter, and it's valid to cast <code>std::atomic&lt;type&gt;</code> to <code>void*</code></p>
  <p>On Linux, it is unclear whether it's ok to mix <code>std::atomic</code> with <code>futex</code>.  <code>futex</code> gets either a <code>uint32_t*</code> or a <code>int32_t*</code> (depending which manual you read), and casting <code>std::atomic&lt;u/int&gt;</code> to <code>u/int*</code> is UB. On the other hand, the manual says</p>
  <blockquote>
  <p>The uaddr argument points to the futex word.  <em><strong>On all platforms,
  futexes are four-byte integers that must be aligned on a four-
  byte boundary</strong></em>.  The operation to perform on the futex is
  specified in the futex_op argument; val is a value whose meaning
  and purpose depends on futex_op.</p>
  </blockquote>
  <p>Hinting that <code>alignas(4) std::atomic&lt;int&gt;</code> should work, and it doesn't matter which integer type is it is as long as the type has the size of 4 bytes and the alignment of 4.</p>
  <p>Also, I have seen many places where this trick of combining atomics and futexes is implemented, including <a href="https://www.boost.org/doc/libs/1_68_0/boost/fiber/detail/futex.hpp" rel="noreferrer">boost</a> and <a href="https://github.com/wjakob/tbb/blob/141b0e310e1fb552bdca887542c9c1a8544d6503/src/tbb/semaphore.h#L205" rel="noreferrer">TBB</a>.</p>
  <p>So what is the best way to sleep on an atomic variable with a timeout in a non UB way?
  Do we have to implement our own atomic class with OS primitives to achieve it correctly?</p>
  <p>(Solutions like mixing atomics and condition variables exist, but sub-optimal)</p>