AuroraRuntime/Include/Aurora/Threading/WakeOnAddress.hpp
Jamie Reece Wilson 62e8625a11 [+] Aurora::Threading::TryWaitOnAddressEx
[*] Spin on top of Linuxs kernel spin, if in non-emu mode
2023-11-14 14:49:40 +00:00

60 lines
3.4 KiB
C++

/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: WakeOnAddress.hpp
Date: 2023-3-11
Author: Reece
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
***/
#pragma once
namespace Aurora::Threading
{
AUKN_SYM void WakeAllOnAddress(const void *pTargetAddress);
AUKN_SYM void WakeOnAddress(const void *pTargetAddress);
AUKN_SYM void WakeNOnAddress(const void *pTargetAddress,
AuUInt8 uNMaximumThreads);
AUKN_SYM bool TryWaitOnAddress(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize);
AUKN_SYM bool TryWaitOnAddressEx(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
AUKN_SYM bool WaitOnAddress(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize,
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
AUKN_SYM bool WaitOnAddressSteady(const void *pTargetAddress,
const void *pCompareAddress,
AuUInt8 uWordSize,
AuUInt64 qwNanoseconds,
AuOptional<bool> optAlreadySpun = {} /*hint: do not spin before switching. subject to global config.*/);
}