[+] ConditionEx::WaitForSignalAbsNS

This commit is contained in:
Reece Wilson 2023-11-29 06:08:09 +00:00
parent f06248f687
commit 22f2e73954
2 changed files with 24 additions and 17 deletions

View File

@ -10,21 +10,26 @@
namespace Aurora::Threading::Primitives namespace Aurora::Threading::Primitives
{ {
/** /**
A comprehensive CV that does not strictly abide by typical assumptions. <br> 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. <br> 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. 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. There are no legal use cases for this feature. It's just there.
*/ */
struct ConditionEx struct ConditionEx
{ {
virtual void WaitForSignal() = 0; virtual void WaitForSignal() = 0;
virtual void WaitForSignal(IWaitable *pWaitable) = 0;
virtual void WaitForSignal(const AuSPtr<IWaitable> &pWaitable) = 0; virtual void WaitForSignal(const AuSPtr<IWaitable> &pWaitable) = 0;
virtual bool WaitForSignalNS(AuUInt64 uRelativeNanoseconds) = 0; virtual bool WaitForSignalNS(AuUInt64 uRelativeNanoseconds) = 0;
virtual bool WaitForSignalNS(IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds) = 0;
virtual bool WaitForSignalNS(const AuSPtr<IWaitable> &pWaitable, AuUInt64 uRelativeNanoseconds) = 0; virtual bool WaitForSignalNS(const AuSPtr<IWaitable> &pWaitable, AuUInt64 uRelativeNanoseconds) = 0;
virtual bool WaitForSignalAbsNS(AuUInt64 uAbsNanoseconds) = 0;
virtual bool WaitForSignalAbsNS(const AuSPtr<IWaitable> &pWaitable, AuUInt64 uAbsNanoseconds) = 0;
virtual void Broadcast() = 0; virtual void Broadcast() = 0;
virtual void Signal() = 0; virtual void Signal() = 0;
}; };

View File

@ -15,14 +15,15 @@ namespace Aurora::Threading::Primitives
{ {
SemaphoreConditionVariableImpl(); SemaphoreConditionVariableImpl();
void WaitForSignal(IWaitable *pWaitable) override;
void WaitForSignal(const AuSPtr<IWaitable> &pWaitable) override; void WaitForSignal(const AuSPtr<IWaitable> &pWaitable) override;
void WaitForSignal() override; void WaitForSignal() override;
bool WaitForSignalNS(AuUInt64 uRelativeNanoseconds) override; bool WaitForSignalNS(AuUInt64 uRelativeNanoseconds) override;
bool WaitForSignalNS(IWaitable *waitable, AuUInt64 uRelativeNanoseconds) override;
bool WaitForSignalNS(const AuSPtr<IWaitable> &waitable, AuUInt64 uRelativeNanoseconds) override; bool WaitForSignalNS(const AuSPtr<IWaitable> &waitable, AuUInt64 uRelativeNanoseconds) override;
bool WaitForSignalAbsNS(AuUInt64 uAbsNanoseconds) override;
bool WaitForSignalAbsNS(const AuSPtr<IWaitable> &pWaitable, AuUInt64 uAbsNanoseconds) override;
void Signal() override; void Signal() override;
void Broadcast() override; void Broadcast() override;
@ -43,13 +44,7 @@ namespace Aurora::Threading::Primitives
return WaitForSignalNS(nullptr, uRelativeNanoseconds); return WaitForSignalNS(nullptr, uRelativeNanoseconds);
} }
bool SemaphoreConditionVariableImpl::WaitForSignalNS(IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds) bool SemaphoreConditionVariableImpl::WaitForSignalAbsNS(const AuSPtr<IWaitable> &pWaitable,
{
return WaitForSignalNS(pWaitable ? AuUnsafeRaiiToShared(pWaitable) : AuSPtr<IWaitable> {},
uRelativeNanoseconds);
}
bool SemaphoreConditionVariableImpl::WaitForSignalNS(const AuSPtr<IWaitable> &pWaitable,
AuUInt64 uRelativeNanoseconds) AuUInt64 uRelativeNanoseconds)
{ {
AuAtomicAdd(&this->uWaiters_, 1u); AuAtomicAdd(&this->uWaiters_, 1u);
@ -59,7 +54,7 @@ namespace Aurora::Threading::Primitives
pWaitable->Unlock(); pWaitable->Unlock();
} }
auto bSuccess = this->s_.LockNS(uRelativeNanoseconds); auto bSuccess = this->s_.LockAbsNS(uRelativeNanoseconds);
if (!bSuccess) if (!bSuccess)
{ {
auto uWaiters = this->uWaiters_; auto uWaiters = this->uWaiters_;
@ -85,9 +80,11 @@ namespace Aurora::Threading::Primitives
return bSuccess; return bSuccess;
} }
void SemaphoreConditionVariableImpl::WaitForSignal(IWaitable *pWaitable) bool SemaphoreConditionVariableImpl::WaitForSignalNS(const AuSPtr<IWaitable> &pWaitable,
AuUInt64 uAbsNanoseconds)
{ {
return WaitForSignal(AuUnsafeRaiiToShared(pWaitable)); return this->WaitForSignalAbsNS(pWaitable,
uAbsNanoseconds ? AuTime::SteadyClockNS() + uAbsNanoseconds : 0);
} }
void SemaphoreConditionVariableImpl::WaitForSignal(const AuSPtr<IWaitable> &pWaitable) void SemaphoreConditionVariableImpl::WaitForSignal(const AuSPtr<IWaitable> &pWaitable)
@ -112,6 +109,11 @@ namespace Aurora::Threading::Primitives
WaitForSignal(nullptr); WaitForSignal(nullptr);
} }
bool SemaphoreConditionVariableImpl::WaitForSignalAbsNS(AuUInt64 uAbsNanoseconds)
{
return this->WaitForSignalAbsNS({}, uAbsNanoseconds);
}
void SemaphoreConditionVariableImpl::Signal() void SemaphoreConditionVariableImpl::Signal()
{ {
AuUInt32 uWaitCount {}; AuUInt32 uWaitCount {};