12#include <dispatch/dispatch.h>
58 using Clock = std::chrono::steady_clock;
62 : semaphore_(dispatch_semaphore_create(0))
72 if (semaphore_ !=
nullptr)
73 dispatch_release(semaphore_);
82 std::atomic_thread_fence(std::memory_order_seq_cst);
83 if (parked_.load(std::memory_order_relaxed)) {
84 posts_.fetch_add(1, std::memory_order_relaxed);
92 template <
typename Ready>
bool wait_until(Ready&& ready, Clock::time_point deadline) {
96 parked_.store(
true, std::memory_order_relaxed);
97 std::atomic_thread_fence(std::memory_order_seq_cst);
99 parked_.store(
false, std::memory_order_relaxed);
102 const auto now = Clock::now();
103 if (now >= deadline) {
104 parked_.store(
false, std::memory_order_relaxed);
107 park(deadline - now);
108 parked_.store(
false, std::memory_order_relaxed);
109 wakes_.fetch_add(1, std::memory_order_relaxed);
114 template <
typename Ready>
bool wait_for(Ready&& ready, Clock::duration timeout) {
115 return wait_until(
static_cast<Ready&&
>(ready), Clock::now() + timeout);
120 std::uint64_t
posts() const noexcept {
121 return posts_.load(std::memory_order_relaxed);
123 std::uint64_t
wakes() const noexcept {
124 return wakes_.load(std::memory_order_relaxed);
128 return parked_.load(std::memory_order_relaxed);
132 void post() noexcept {
133#if defined(__APPLE__)
134 (void)dispatch_semaphore_signal(semaphore_);
136 semaphore_.release();
140 void park(Clock::duration timeout) {
141#if defined(__APPLE__)
142 const auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
143 (void)dispatch_semaphore_wait(semaphore_, dispatch_time(DISPATCH_TIME_NOW, ns));
145 (void)semaphore_.try_acquire_for(timeout);
149 std::atomic<bool> parked_{
false};
150 std::atomic<std::uint64_t> posts_{0};
151 std::atomic<std::uint64_t> wakes_{0};
152#if defined(__APPLE__)
153 dispatch_semaphore_t semaphore_ =
nullptr;
155 std::counting_semaphore<> semaphore_{0};
WakeSignal() noexcept
Definition wake_signal.hpp:60
std::uint64_t posts() const noexcept
Diagnostics: kernel posts the producers made, and times the consumer woke from a park (a post or a ti...
Definition wake_signal.hpp:120
void notify() noexcept
Producer side, realtime safe. Call after the work is published.
Definition wake_signal.hpp:81
WakeSignal(const WakeSignal &)=delete
~WakeSignal()
Definition wake_signal.hpp:67
std::uint64_t wakes() const noexcept
Definition wake_signal.hpp:123
bool wait_for(Ready &&ready, Clock::duration timeout)
wait_until() with a deadline timeout from now.
Definition wake_signal.hpp:114
std::chrono::steady_clock Clock
Definition wake_signal.hpp:58
bool wait_until(Ready &&ready, Clock::time_point deadline)
Consumer side.
Definition wake_signal.hpp:92
bool consumer_parked() const noexcept
Diagnostics: whether the consumer is currently parked (or about to be).
Definition wake_signal.hpp:127
WakeSignal & operator=(const WakeSignal &)=delete
Definition generated_event_source.hpp:33