[*] Update: WakeOnAddress.hpp comments
This commit is contained in:
parent
fa900d0f78
commit
0555e8cc32
@ -49,11 +49,25 @@
|
|||||||
wait on address interface to develop the internal wrapper. Fortunately, only more esoteric UNIX machines
|
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
|
require these. Further platform support can be added with this; only a semaphore or conditionvar/mutex
|
||||||
pair is required to bootstrap this path.
|
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
|
#pragma once
|
||||||
|
|
||||||
namespace Aurora::Threading
|
namespace Aurora::Threading
|
||||||
{
|
{
|
||||||
|
// Break sleep when volatile pTargetAddress [...] constant pCompareAddress
|
||||||
AUE_DEFINE(EWaitMethod, (
|
AUE_DEFINE(EWaitMethod, (
|
||||||
eNotEqual, eEqual, eLessThanCompare, eGreaterThanCompare, eLessThanOrEqualsCompare, eGreaterThanOrEqualsCompare
|
eNotEqual, eEqual, eLessThanCompare, eGreaterThanCompare, eLessThanOrEqualsCompare, eGreaterThanOrEqualsCompare
|
||||||
))
|
))
|
||||||
@ -67,9 +81,9 @@ namespace Aurora::Threading
|
|||||||
AuUInt8 uNMaximumThreads);
|
AuUInt8 uNMaximumThreads);
|
||||||
|
|
||||||
// On systems with processors of shared execution pipelines, these try-series of operations will spin (eg: mm_pause) for a configurable
|
// 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
|
// 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
|
||||||
// worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should report you already
|
// arbitrarily without worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should
|
||||||
// spun via optAlreadySpun. If the application is configured to spin later on, this hint may be used to prevent a double spin.
|
// 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,
|
AUKN_SYM bool TryWaitOnAddress(const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
AuUInt8 uWordSize);
|
AuUInt8 uWordSize);
|
||||||
@ -80,9 +94,9 @@ namespace Aurora::Threading
|
|||||||
AuUInt8 uWordSize);
|
AuUInt8 uWordSize);
|
||||||
|
|
||||||
// On systems with processors of shared execution pipelines, these try-series of operations will spin (eg: mm_pause) for a configurable
|
// 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
|
// 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
|
||||||
// worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should report you already
|
// arbitrarily without worrying about an accidental thundering mm_pause herd. If you wish to call WaitOnAddress[...] afterwards, you should
|
||||||
// spun via optAlreadySpun. If the application is configured to spin later on, this hint may be used to prevent a double spin.
|
// 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.
|
// In the case of a pTargetAddress != pCompareAddress condition, the optional check parameter is used to verify the wake condition.
|
||||||
// Otherwise, spinning will continue.
|
// Otherwise, spinning will continue.
|
||||||
AUKN_SYM bool TryWaitOnAddressEx(const void *pTargetAddress,
|
AUKN_SYM bool TryWaitOnAddressEx(const void *pTargetAddress,
|
||||||
@ -90,13 +104,16 @@ namespace Aurora::Threading
|
|||||||
AuUInt8 uWordSize,
|
AuUInt8 uWordSize,
|
||||||
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
|
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
|
||||||
|
|
||||||
|
// See: TryWaitOnAddressEx
|
||||||
AUKN_SYM bool TryWaitOnAddressSpecialEx(EWaitMethod eMethod,
|
AUKN_SYM bool TryWaitOnAddressSpecialEx(EWaitMethod eMethod,
|
||||||
const void *pTargetAddress,
|
const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
AuUInt8 uWordSize,
|
AuUInt8 uWordSize,
|
||||||
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
|
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,
|
AUKN_SYM bool WaitOnAddress(const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
AuUInt8 uWordSize,
|
AuUInt8 uWordSize,
|
||||||
@ -104,6 +121,7 @@ namespace Aurora::Threading
|
|||||||
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
|
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
|
||||||
|
|
||||||
// Relative timeout variant of nanosecond resolution WoA. 0 = indefinite
|
// 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,
|
AUKN_SYM bool WaitOnAddressSpecial(EWaitMethod eMethod,
|
||||||
const void *pTargetAddress,
|
const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
@ -111,7 +129,9 @@ namespace Aurora::Threading
|
|||||||
AuUInt64 qwNanoseconds,
|
AuUInt64 qwNanoseconds,
|
||||||
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
|
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,
|
AUKN_SYM bool WaitOnAddressSteady(const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
AuUInt8 uWordSize,
|
AuUInt8 uWordSize,
|
||||||
@ -119,6 +139,7 @@ namespace Aurora::Threading
|
|||||||
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
|
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 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,
|
AUKN_SYM bool WaitOnAddressSpecialSteady(EWaitMethod eMethod,
|
||||||
const void *pTargetAddress,
|
const void *pTargetAddress,
|
||||||
const void *pCompareAddress,
|
const void *pCompareAddress,
|
||||||
|
Loading…
Reference in New Issue
Block a user