diff --git a/Include/Aurora/Threading/Primitives/ConditionEx.hpp b/Include/Aurora/Threading/Primitives/ConditionEx.hpp index 4ca4027e..edd6317e 100644 --- a/Include/Aurora/Threading/Primitives/ConditionEx.hpp +++ b/Include/Aurora/Threading/Primitives/ConditionEx.hpp @@ -10,21 +10,26 @@ namespace Aurora::Threading::Primitives { /** - A comprehensive CV that does not strictly abide by typical assumptions.
- This object depends on the synchronization of primitives within our abstraction layer rather than the OS's implementation of condition variables.
+ A more comprehensive CV that does not strictly abide by the alternative stricter assumptions. + This object depends on the synchronization of primitives within our abstraction layer rather than + the OS's implementation of condition variables. + In some instances, the cond mutex/var implementations are directly backed by an OS primitive, + sometimes they're reimplemented. In this primitive any locking interface can be used, and an + AuThreadPrimitive is used for the sleep operation. Note: Missing 'pWaitable's cannnot serve as an `atomic wait for while is [not] value` operation. There are no legal use cases for this feature. It's just there. */ struct ConditionEx { virtual void WaitForSignal() = 0; - virtual void WaitForSignal(IWaitable *pWaitable) = 0; virtual void WaitForSignal(const AuSPtr &pWaitable) = 0; virtual bool WaitForSignalNS(AuUInt64 uRelativeNanoseconds) = 0; - virtual bool WaitForSignalNS(IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds) = 0; virtual bool WaitForSignalNS(const AuSPtr &pWaitable, AuUInt64 uRelativeNanoseconds) = 0; + virtual bool WaitForSignalAbsNS(AuUInt64 uAbsNanoseconds) = 0; + virtual bool WaitForSignalAbsNS(const AuSPtr &pWaitable, AuUInt64 uAbsNanoseconds) = 0; + virtual void Broadcast() = 0; virtual void Signal() = 0; }; diff --git a/Source/Threading/Primitives/AuConditionEx.cpp b/Source/Threading/Primitives/AuConditionEx.cpp index 50824b1b..f689d29b 100644 --- a/Source/Threading/Primitives/AuConditionEx.cpp +++ b/Source/Threading/Primitives/AuConditionEx.cpp @@ -15,14 +15,15 @@ namespace Aurora::Threading::Primitives { SemaphoreConditionVariableImpl(); - void WaitForSignal(IWaitable *pWaitable) override; void WaitForSignal(const AuSPtr &pWaitable) override; void WaitForSignal() override; bool WaitForSignalNS(AuUInt64 uRelativeNanoseconds) override; - bool WaitForSignalNS(IWaitable *waitable, AuUInt64 uRelativeNanoseconds) override; bool WaitForSignalNS(const AuSPtr &waitable, AuUInt64 uRelativeNanoseconds) override; + bool WaitForSignalAbsNS(AuUInt64 uAbsNanoseconds) override; + bool WaitForSignalAbsNS(const AuSPtr &pWaitable, AuUInt64 uAbsNanoseconds) override; + void Signal() override; void Broadcast() override; @@ -43,14 +44,8 @@ namespace Aurora::Threading::Primitives return WaitForSignalNS(nullptr, uRelativeNanoseconds); } - bool SemaphoreConditionVariableImpl::WaitForSignalNS(IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds) - { - return WaitForSignalNS(pWaitable ? AuUnsafeRaiiToShared(pWaitable) : AuSPtr {}, - uRelativeNanoseconds); - } - - bool SemaphoreConditionVariableImpl::WaitForSignalNS(const AuSPtr &pWaitable, - AuUInt64 uRelativeNanoseconds) + bool SemaphoreConditionVariableImpl::WaitForSignalAbsNS(const AuSPtr &pWaitable, + AuUInt64 uRelativeNanoseconds) { AuAtomicAdd(&this->uWaiters_, 1u); @@ -59,7 +54,7 @@ namespace Aurora::Threading::Primitives pWaitable->Unlock(); } - auto bSuccess = this->s_.LockNS(uRelativeNanoseconds); + auto bSuccess = this->s_.LockAbsNS(uRelativeNanoseconds); if (!bSuccess) { auto uWaiters = this->uWaiters_; @@ -85,9 +80,11 @@ namespace Aurora::Threading::Primitives return bSuccess; } - void SemaphoreConditionVariableImpl::WaitForSignal(IWaitable *pWaitable) + bool SemaphoreConditionVariableImpl::WaitForSignalNS(const AuSPtr &pWaitable, + AuUInt64 uAbsNanoseconds) { - return WaitForSignal(AuUnsafeRaiiToShared(pWaitable)); + return this->WaitForSignalAbsNS(pWaitable, + uAbsNanoseconds ? AuTime::SteadyClockNS() + uAbsNanoseconds : 0); } void SemaphoreConditionVariableImpl::WaitForSignal(const AuSPtr &pWaitable) @@ -112,6 +109,11 @@ namespace Aurora::Threading::Primitives WaitForSignal(nullptr); } + bool SemaphoreConditionVariableImpl::WaitForSignalAbsNS(AuUInt64 uAbsNanoseconds) + { + return this->WaitForSignalAbsNS({}, uAbsNanoseconds); + } + void SemaphoreConditionVariableImpl::Signal() { AuUInt32 uWaitCount {};