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 {};