76 uintptr_t debugAddress = 0,
77 StackDiscardCleanup onStackDiscard =
nullptr,
78 void* stackDiscardContext =
nullptr);
87 size_t debugState = 0, uintptr_t debugAddress = 0);
95 size_t debugState = 0, uintptr_t debugAddress = 0,
96 StackDiscardCleanup onStackDiscard =
nullptr,
97 void* stackDiscardContext =
nullptr);
107 size_t debugState = 0,
108 uintptr_t debugAddress = 0);
110 bool wakeOne(WakeReason reason = WakeReason::Signalled,
const Channel& channel =
Channel());
111 size_t wakeAll(WakeReason reason = WakeReason::Signalled,
const Channel& channel =
Channel());
114 size_t wakeAndRequeue(
const Channel& source,
size_t wakeCount,
const Channel& destination,
115 size_t requeueCount);
122 NOT_COPYABLE_OR_ASSIGNABLE(
Guard);
126 uintptr_t debugAddress);
143 bool wakeOne(WakeReason reason = WakeReason::Signalled,
const Channel& channel = Channel());
144 size_t wakeAll(WakeReason reason = WakeReason::Signalled,
const Channel& channel = Channel());
173 return __atomic_load_n(&queue, __ATOMIC_ACQUIRE);
177 __atomic_store_n(&queue, value, __ATOMIC_RELEASE);
180 WakeReason loadReason()
const {
181 return static_cast<WakeReason
>(__atomic_load_n(&reason, __ATOMIC_ACQUIRE));
184 void storeReason(WakeReason value) {
185 __atomic_store_n(&reason,
static_cast<size_t>(value), __ATOMIC_RELEASE);
188 bool isQueued()
const {
189 return __atomic_load_n(&queued, __ATOMIC_ACQUIRE);
192 void setQueued(
bool value) {
193 __atomic_store_n(&queued, value, __ATOMIC_RELEASE);
200 size_t channelGeneration = 0;
202 void storeChannel(
const Channel& value) {
203 __atomic_add_fetch(&channelGeneration,
static_cast<size_t>(1), __ATOMIC_ACQ_REL);
204 __atomic_store_n(&channel.owner, value.owner, __ATOMIC_RELAXED);
205 __atomic_store_n(&channel.value, value.value, __ATOMIC_RELAXED);
206 __atomic_add_fetch(&channelGeneration,
static_cast<size_t>(1), __ATOMIC_RELEASE);
209 bool snapshotChannel(
Channel& value)
const {
210 const size_t generation = __atomic_load_n(&channelGeneration, __ATOMIC_ACQUIRE);
211 if (generation & 1) {
214 value.owner = __atomic_load_n(&channel.owner, __ATOMIC_RELAXED);
215 value.value = __atomic_load_n(&channel.value, __ATOMIC_RELAXED);
216 __atomic_thread_fence(__ATOMIC_ACQUIRE);
217 return __atomic_load_n(&channelGeneration, __ATOMIC_RELAXED) == generation;
219 size_t stateLevel = 0;
220 size_t reason =
static_cast<size_t>(WakeReason::Waiting);
224 StackDiscardCleanup legacyOnAbandon =
nullptr;
225 void* legacyAbandonContext =
nullptr;
226 Waiter* previous =
nullptr;
228 Waiter* notificationNext =
nullptr;