Event count¶
A standalone adaptation of folly::EventCount utilizing C++20’s atomic wait facilities. 
This file has been adapted from: 
- 
class event_count : private lf::impl::immovable<event_count>¶
- A condition variable for lock free algorithms. - See http://www.1024cores.net/home/lock-free-algorithms/eventcounts for details. - Event counts allow you to convert a non-blocking lock-free / wait-free algorithm into a blocking one, by isolating the blocking logic. You call prepare_wait() before checking your condition and then either cancel_wait() or wait() depending on whether the condition was true. When another thread makes the condition true, it must call notify() / notify_all() just like a regular condition variable. - If “<” denotes the happens-before relationship, consider 2 threads (T1 and T2) and 3 events: - E1: T1 returns from prepare_wait. 
- E2: T1 calls wait (obviously E1 < E2, intra-thread). 
- E3: T2 calls - notify_all().
 - If E1 < E3, then E2’s wait will complete (and T1 will either wake up, or not block at all) - This means that you can use an event_count in the following manner: - Waiter: - if (!condition()) { // handle fast path first for (;;) { auto key = eventCount.prepare_wait(); if (condition()) { eventCount.cancel_wait(); break; } else { eventCount.wait(key); } } } - (This pattern is encapsulated in the - await()method.)- Poster: - make_condition_true(); eventCount.notify_all(); - Note - Just like with regular condition variables, the waiter needs to be tolerant of spurious wakeups and needs to recheck the condition after being woken up. Also, as there is no mutual exclusion implied, “checking” the condition likely means attempting an operation on an underlying data structure (push into a lock-free queue, etc) and returning true on success and false on failure. - Public Functions - 
template<typename Pred>
 void await(Pred const &condition) noexcept(std::is_nothrow_invocable_r_v<bool, Pred const&>)¶
- Wait for - condition()to become true.- Cleans up appropriately if - condition()throws, and then rethrow.
 - 
inline auto cancel_wait() noexcept -> void¶
- Cancel a wait that was prepared with - prepare_wait().
 - 
inline auto notify_all() noexcept -> void¶
- Wake up all waiters. 
 - 
inline auto notify_one() noexcept -> void¶
- Wake up one waiter. 
 - 
inline auto prepare_wait() noexcept -> key¶
- Prepare to wait. - Once this has been called, you must either call - wait()with the key or- cancel_wait().
 - 
class key¶
- The return type of - prepare_wait().