diff --git a/Source/Threading/AuWakeOnAddress.hpp b/Source/Threading/AuWakeOnAddress.hpp index 442df5e9..8e93897b 100644 --- a/Source/Threading/AuWakeOnAddress.hpp +++ b/Source/Threading/AuWakeOnAddress.hpp @@ -7,7 +7,10 @@ ***/ #pragma once +#include "Primitives/AuWoASemaphore.hpp" + #include "Primitives/AuConditionMutex.Generic.hpp" +#include "Primitives/AuSemaphore.Generic.hpp" #include "Primitives/AuConditionVariable.Generic.hpp" namespace Aurora::Threading @@ -48,17 +51,28 @@ namespace Aurora::Threading // synch #if defined(WOA_SEMAPHORE_MODE) - #if defined(WOA_SEMAPHORE_SEMAPHORE) - // PORT: MacOS (?) - WOA_SEMAPHORE_SEMAPHORE semaphore; - #else - // Testing: - Primitives::Semaphore semaphore; - #endif + + #if !defined(WOA_SEMAPHORE_SEMAPHORE) + Primitives::Semaphore semaphore; + #else + // Recommended for XNU targets: + WOA_SEMAPHORE_SEMAPHORE semaphore; + #endif + #else // Recommended (we can better filter spurious wakes for the cost of a barrier on signal): - Primitives::ConditionMutexInternal mutex; // mutex ctor must come before var - Primitives::ConditionVariableInternal variable; // ...and something all 2007+ micro and monolithic kernels should have to yield for an event + // !!! we also prefer to block the containers mutex while we signal each thread individually !!! + // !!! for the sake of optimizing for windows xp - 7, its far nicer to optimize the entire signaling and wait operations under a container lock, than it is to buffer shared pointers or externally managed memory out of the lock scope !!! + // !!! also note: container spinlocks =/= WaitEntry::mutex !! + + #if !defined(WOA_CONDVAR_MUTEX) + Primitives::ConditionMutexInternal mutex; // mutex ctor must come before var + Primitives::ConditionVariableInternal variable; // ...and something all 2007+ micro and monolithic kernels should have; an event or semaphore primitive on which we can form a crude condvar + #else + WOA_CONDVAR_MUTEX mutex; + WOA_CONDVAR_VARIABLE variable; + #endif + #endif // state @@ -66,9 +80,8 @@ namespace Aurora::Threading AuUInt8 uSize {}; // bookkeeping (parent container) - bool bOverflow {}; - volatile bool bAlive {}; - + volatile bool bAlive {}; // wait entry validity. must be rechecked for each spurious or expected wake, if the comparison doesn't break the yield loop. + // if false, and we're still yielding under pCompare == pAddress, we must reschedule with inverse order (as to steal the next signal, as opposed to waiting last) void Release(); bool SleepOn(WaitState &state); diff --git a/Source/Threading/Primitives/AuWoASemaphore.hpp b/Source/Threading/Primitives/AuWoASemaphore.hpp new file mode 100644 index 00000000..9657ff72 --- /dev/null +++ b/Source/Threading/Primitives/AuWoASemaphore.hpp @@ -0,0 +1,42 @@ +/*** + Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuWoASemaphore.hpp + Date: 2024-1-22 + Author: Reece +***/ +#pragma once + +#if defined(AURORA_IS_LINUX_DERIVED) + + // Should use + #define WOA_SEMAPHORE_MODE + +#elif defined(AURORA_IS_XNU_DERIVED) + + // Must use libdispatch semaphores + #define WOA_SEMAPHORE_MODE + + #define WOA_SEMAPHORE_SEMAPHORE Aurora::Threading::Primitives::WoASemaphoreImpl + + #include "AuWoASemaphore.Unix.hpp" + +#elif defined(AURORA_IS_POSIX_DERIVED) + + // Probably not worth it? + #define WOA_SEMAPHORE_MODE + + #define WOA_SEMAPHORE_SEMAPHORE Aurora::Threading::Primitives::WoASemaphoreImpl + #define WOA_CONDVAR_MUTEX Aurora::Threading::Primitives::WoAConditionMutex + #define WOA_CONDVAR_VARIABLE Aurora::Threading::Primitives::WoAConditionVariable + + #include "AuWoASemaphore.Unix.hpp" + +#endif + +// Win32: N/A (simply use the win32 primitives built on top of the native kernelbase waitonaddress or keyed events) +// Linux: N/A (simply use the linux primitives built on top of Aurora::futex_[...] wrappers, in semaphore mode) +// Xbox Original/360 homebrew: Port using WOA_SEMAPHORE_SEMAPHORE behind CreateSemphore +// Win 2000 and Win9x: Port using WOA_SEMAPHORE_SEMAPHORE behind CreateSemphore +// Other microkernels: Port using WOA_SEMAPHORE_SEMAPHORE +// POSIX: experiment with WOA_SEMAPHORE_MODE turned on or off \ No newline at end of file