/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuWakeOnAddress.hpp Date: 2023-3-10 Author: Reece ***/ #pragma once #include "Primitives/AuConditionMutex.Generic.hpp" #include "Primitives/AuConditionVariable.Generic.hpp" namespace Aurora::Threading /*::Primitives for this file only!*/ { static const auto kDefaultWaitPerProcess = 32; struct WaitState; struct WaitBuffer { char buffer[8]; AuUInt8 uSize; static WaitBuffer From(const void *pBuf, AuUInt8 uSize); bool Compare(const void *pBuf); bool Compare(WaitState &state); }; struct WaitState { WaitBuffer compare; AuOptionalEx qwNanoseconds; AuOptionalEx uDownsizeMask; AuUInt32 uWordSize {}; }; struct WaitEntry { WaitEntry(); ~WaitEntry(); // synch AuUInt32 uAtomic {}; // fastpath Primitives::ConditionMutexImpl mutex; // mutex ctor must come before var Primitives::ConditionVariableImpl variable; // ...and something all 2007+ micro and monolithic kernels should have to yield for an event // state const void *pAddress {}; AuUInt8 uSize {}; // bookkeeping (parent container) bool bOverflow {}; bool TryAcquire(const void *pAddress, AuUInt8 uSize); void Release(); bool SleepOn(WaitState &state); bool TryWake(const void *pAddress); bool TryWakeNoLock(const void *pAddress); bool TryWakeNoLockNoReallyNoLock(const void *pAddress); }; struct ProcessWaitContainer { AuUInt32 uAtomic {}; WaitEntry entries[kDefaultWaitPerProcess]; AuList> overflow; AuSPtr WaitBufferFrom(void *pAddress, AuUInt8 uSize); template bool IterateAll(T callback); template bool IterateForceNoCreateDuringOp(T callback); void Lock(); void Unlock(); void Remove(WaitEntry *pParent); }; }