[*] Update: WakeOnAddress.hpp comments

This commit is contained in:
Reece Wilson 2024-06-30 05:13:55 +01:00
parent fa900d0f78
commit 0555e8cc32

View File

@ -49,11 +49,25 @@
wait on address interface to develop the internal wrapper. Fortunately, only more esoteric UNIX machines
require these. Further platform support can be added with this; only a semaphore or conditionvar/mutex
pair is required to bootstrap this path.
Memory note: Weakly ordered memory is an alien concept. AuAtomicXXX operations ensure all previous stores are
visible across all cores (useful for semaphore increment and mutex-unlock operations), and that loads
are evaluated in order. For all intents and purposes, you should treat the au ecosystem like any
other strongly ordered processor and program pair. For memeworthy lockless algorithms, you can use
spec-of-the-year atomic word containers and related methods; we dont care about optimizing some midwits
weakly-ordered cas spinning and ABA-hell container, thats genuinely believed to be the best thing ever.
Sincerely, you are doing something wrong if you're write-locking a container for any notable length of
time, and more often than not, lock-free algorithms are bloated to all hell, just to end up losing in
most real world use cases.
tldr: Dont worry about memory ordering or ABA. Use the locks, atomic utilities, and primitives as expected.
(you'll be fine)
***/
#pragma once
namespace Aurora::Threading
{
// Break sleep when volatile pTargetAddress [...] constant pCompareAddress
AUE_DEFINE(EWaitMethod, (
eNotEqual, eEqual, eLessThanCompare, eGreaterThanCompare, eLessThanOrEqualsCompare, eGreaterThanOrEqualsCompare
))
@ -67,9 +81,9 @@ namespace Aurora::Threading
AuUInt8 uNMaximumThreads);
// On systems with processors of shared execution pipelines, these try-series of operations will spin (eg: mm_pause) for a configurable
// amount of time, so long as the the process-wide state isn't overly contested. This means you can use these arbitrarily without
// worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should report you already
// spun via optAlreadySpun. If the application is configured to spin later on, this hint may be used to prevent a double spin.
// amount of time, or enter a low power mode, so long as the the process-wide state isn't overly contested. This means you can use these
// arbitrarily without worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should
// report you already spun via optAlreadySpun. If the application is configured to spin later on, this hint may be used to prevent a double spin.
AUKN_SYM bool TryWaitOnAddress(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize);
@ -80,9 +94,9 @@ namespace Aurora::Threading
AuUInt8 uWordSize);
// On systems with processors of shared execution pipelines, these try-series of operations will spin (eg: mm_pause) for a configurable
// amount of time, so long as the the process-wide state isn't overly contested. This means you can use these arbitrarily without
// worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should report you already
// spun via optAlreadySpun. If the application is configured to spin later on, this hint may be used to prevent a double spin.
// amount of time, or enter a low power mode, so long as the the process-wide state isn't overly contested. This means you can use these
// arbitrarily without worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should
// report you already spun via optAlreadySpun. If the application is configured to spin later on, this hint may be used to prevent a double spin.
// In the case of a pTargetAddress != pCompareAddress condition, the optional check parameter is used to verify the wake condition.
// Otherwise, spinning will continue.
AUKN_SYM bool TryWaitOnAddressEx(const void *pTargetAddress,
@ -90,13 +104,16 @@ namespace Aurora::Threading
AuUInt8 uWordSize,
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
// See: TryWaitOnAddressEx
AUKN_SYM bool TryWaitOnAddressSpecialEx(EWaitMethod eMethod,
const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize,
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
// Relative timeout variant of nanosecond resolution WoA. 0 = indefinite
// Relative timeout variant of nanosecond resolution eNotEqual WoA. 0 = indefinite.
// In Wrapper Mode, it is possible to bypass the WoA implementation, and bail straight into the kernel.
// For improved order and EWaitMethod, do not use Wrapper Mode.
AUKN_SYM bool WaitOnAddress(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize,
@ -104,6 +121,7 @@ namespace Aurora::Threading
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
// Relative timeout variant of nanosecond resolution WoA. 0 = indefinite
// Emulation Mode over Wrapper Mode is recommended for applications that heavily depend on these wait functions.
AUKN_SYM bool WaitOnAddressSpecial(EWaitMethod eMethod,
const void *pTargetAddress,
const void *pCompareAddress,
@ -111,7 +129,9 @@ namespace Aurora::Threading
AuUInt64 qwNanoseconds,
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
// Absolute timeout variant of nanosecond resolution WoA. Nanoseconds are in steady clock time. 0 = indefinite
// Absolute timeout variant of nanosecond resolution eNotEqual WoA. Nanoseconds are in steady clock time. 0 = indefinite
// In Wrapper Mode, it is possible to bypass the WoA implementation, and bail straight into the kernel.
// For improved order and EWaitMethod, do not use Wrapper Mode.
AUKN_SYM bool WaitOnAddressSteady(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize,
@ -119,6 +139,7 @@ namespace Aurora::Threading
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
// Absolute timeout variant of nanosecond resolution WoA. Nanoseconds are in steady clock time. 0 = indefinite
// Emulation Mode over Wrapper Mode is recommended for applications that heavily depend on these wait functions.
AUKN_SYM bool WaitOnAddressSpecialSteady(EWaitMethod eMethod,
const void *pTargetAddress,
const void *pCompareAddress,