2023-03-12 15:27:28 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
|
|
|
File: WakeOnAddress.hpp
|
|
|
|
Date: 2023-3-11
|
|
|
|
Author: Reece
|
2023-10-30 14:50:28 +00:00
|
|
|
Note: In emulation mode (*):
|
|
|
|
1: Wakes occur in FIFO order
|
|
|
|
2: uWordSize can be any length not exceeding 32 bytes
|
|
|
|
otherwise
|
|
|
|
1: Wakes are orderless
|
|
|
|
2: uWordSize must be less than or equal to 8 bytes
|
|
|
|
3: only the least significant 32bits are guaranteed to be used as wake signals
|
|
|
|
|
|
|
|
* By default: UNIXes and targets below/inc Windows 7 will be in userland emulation mode for performance reasons.
|
|
|
|
* Linux and other targets can directly interface with their futex interface under a smaller wrapper;
|
|
|
|
* however, these applications are limited to internal synchronization primitives. The added bloat
|
|
|
|
* of the WaitOnAddress/FUTEX/atomic wait emulation layer improves performance in real world dumb
|
|
|
|
* code with spurious wakes, odd word sizes, and pointer alignments. Not to mention some targets
|
|
|
|
* are stuck with semaphores or condition variables to start off with, and therefore need this
|
|
|
|
* for the sake of porting modern applications. The aforementioned synchronization primitives
|
|
|
|
* are written with OS specific optimizations in mind, and therefore consider emulation bloat.
|
|
|
|
* bPreferEmulatedWakeOnAddress disables the emulation layer, if theres a reasonable native
|
|
|
|
* interfaces available.
|
|
|
|
* Defer to ThreadingConfig::bPreferEmulatedWakeOnAddress = !AuBuild::kIsNtDerived
|
2023-03-12 15:27:28 +00:00
|
|
|
***/
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
namespace Aurora::Threading
|
|
|
|
{
|
2023-08-19 19:37:24 +00:00
|
|
|
AUKN_SYM void WakeAllOnAddress(const void *pTargetAddress);
|
2023-03-12 15:27:28 +00:00
|
|
|
|
2023-08-19 19:37:24 +00:00
|
|
|
AUKN_SYM void WakeOnAddress(const void *pTargetAddress);
|
2023-03-12 15:27:28 +00:00
|
|
|
|
2023-08-19 19:37:24 +00:00
|
|
|
AUKN_SYM void WakeNOnAddress(const void *pTargetAddress,
|
2023-03-12 15:27:28 +00:00
|
|
|
AuUInt8 uNMaximumThreads);
|
|
|
|
|
2023-08-22 10:08:56 +00:00
|
|
|
AUKN_SYM bool TryWaitOnAddress(const void *pTargetAddress,
|
2023-08-19 18:48:24 +00:00
|
|
|
const void *pCompareAddress,
|
2023-03-12 15:27:28 +00:00
|
|
|
AuUInt8 uWordSize);
|
|
|
|
|
2023-11-14 14:44:56 +00:00
|
|
|
AUKN_SYM bool TryWaitOnAddressEx(const void *pTargetAddress,
|
|
|
|
const void *pCompareAddress,
|
|
|
|
AuUInt8 uWordSize,
|
|
|
|
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
|
|
|
|
|
2023-10-30 14:50:28 +00:00
|
|
|
// Relative timeout variant of nanosecond resolution WoA. 0 = indefinite
|
2023-08-22 10:08:56 +00:00
|
|
|
AUKN_SYM bool WaitOnAddress(const void *pTargetAddress,
|
2023-08-19 18:48:24 +00:00
|
|
|
const void *pCompareAddress,
|
2023-03-12 15:27:28 +00:00
|
|
|
AuUInt8 uWordSize,
|
2023-10-30 14:50:28 +00:00
|
|
|
AuUInt64 qwNanoseconds,
|
|
|
|
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
|
2023-06-15 19:44:27 +00:00
|
|
|
|
|
|
|
// Absolute timeout variant of nanosecond resolution WoA. Nanoseconds are in steady clock time. 0 = indefinite
|
2023-08-22 10:08:56 +00:00
|
|
|
AUKN_SYM bool WaitOnAddressSteady(const void *pTargetAddress,
|
2023-08-19 18:48:24 +00:00
|
|
|
const void *pCompareAddress,
|
2023-06-15 19:44:27 +00:00
|
|
|
AuUInt8 uWordSize,
|
2023-10-30 14:50:28 +00:00
|
|
|
AuUInt64 qwNanoseconds,
|
|
|
|
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
|
2023-03-12 15:27:28 +00:00
|
|
|
}
|