[+] FlexibleConditionVariable::WaitForSignalRelativeNanoseconds(AuUInt64 uRelativeNanoseconds)
[+] FlexibleConditionVariable::WaitForSignalRelativeNanoseconds(Threading::IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds) [+] FlexibleConditionVariable::WaitForSignalRelativeNanoseconds(AuUInt64 uRelativeNanoseconds) [*] Refactor FlexibleConditionVariable
This commit is contained in:
parent
dab6e9caee
commit
66cfbb5351
@ -18,8 +18,13 @@ namespace Aurora::Threading::Primitives
|
||||
struct ConditionEx
|
||||
{
|
||||
virtual void WaitForSignal() = 0;
|
||||
virtual void WaitForSignal(Threading::IWaitable *waitable) = 0;
|
||||
virtual void WaitForSignal(const AuSPtr<Threading::IWaitable> &waitable) = 0;
|
||||
virtual void WaitForSignal(IWaitable *pWaitable) = 0;
|
||||
virtual void WaitForSignal(const AuSPtr<IWaitable> &pWaitable) = 0;
|
||||
|
||||
virtual void WaitForSignalRelativeNanoseconds(AuUInt64 uRelativeNanoseconds) = 0;
|
||||
virtual void WaitForSignalRelativeNanoseconds(IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds) = 0;
|
||||
virtual void WaitForSignalRelativeNanoseconds(const AuSPtr<IWaitable> &pWaitable, AuUInt64 uRelativeNanoseconds) = 0;
|
||||
|
||||
virtual void Broadcast() = 0;
|
||||
virtual void Signal() = 0;
|
||||
};
|
||||
|
@ -15,32 +15,81 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
SemaphoreConditionVariableImpl();
|
||||
|
||||
void WaitForSignal(Aurora::Threading::IWaitable *pWaitable) override;
|
||||
void WaitForSignal(const AuSPtr<Threading::IWaitable> &pWaitable) override;
|
||||
void WaitForSignal(IWaitable *pWaitable) override;
|
||||
void WaitForSignal(const AuSPtr<IWaitable> &pWaitable) override;
|
||||
void WaitForSignal() override;
|
||||
|
||||
void WaitForSignalRelativeNanoseconds(AuUInt64 uRelativeNanoseconds) override;
|
||||
void WaitForSignalRelativeNanoseconds(IWaitable *waitable, AuUInt64 uRelativeNanoseconds) override;
|
||||
void WaitForSignalRelativeNanoseconds(const AuSPtr<IWaitable> &waitable, AuUInt64 uRelativeNanoseconds) override;
|
||||
|
||||
void Signal() override;
|
||||
void Broadcast() override;
|
||||
|
||||
private:
|
||||
SemaphoreImpl s_;
|
||||
AuUInt32 waiters_;
|
||||
AuUInt32 uWaiters_;
|
||||
};
|
||||
|
||||
SemaphoreConditionVariableImpl::SemaphoreConditionVariableImpl() :
|
||||
s_(0),
|
||||
waiters_(0)
|
||||
uWaiters_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SemaphoreConditionVariableImpl::WaitForSignal(Aurora::Threading::IWaitable *pWaitable)
|
||||
void SemaphoreConditionVariableImpl::WaitForSignalRelativeNanoseconds(AuUInt64 uRelativeNanoseconds)
|
||||
{
|
||||
WaitForSignalRelativeNanoseconds(nullptr, uRelativeNanoseconds);
|
||||
}
|
||||
|
||||
void SemaphoreConditionVariableImpl::WaitForSignalRelativeNanoseconds(IWaitable *pWaitable, AuUInt64 uRelativeNanoseconds)
|
||||
{
|
||||
return WaitForSignalRelativeNanoseconds(pWaitable ? AuUnsafeRaiiToShared(pWaitable) : AuSPtr<IWaitable> {},
|
||||
uRelativeNanoseconds);
|
||||
}
|
||||
|
||||
void SemaphoreConditionVariableImpl::WaitForSignalRelativeNanoseconds(const AuSPtr<IWaitable> &pWaitable,
|
||||
AuUInt64 uRelativeNanoseconds)
|
||||
{
|
||||
AuAtomicAdd(&this->uWaiters_, 1u);
|
||||
|
||||
if (pWaitable)
|
||||
{
|
||||
pWaitable->Unlock();
|
||||
}
|
||||
|
||||
auto bSuccess = this->s_.LockNS(uRelativeNanoseconds);
|
||||
if (!bSuccess)
|
||||
{
|
||||
auto uWaiters = this->uWaiters_;
|
||||
auto uWaitCount = 1;
|
||||
|
||||
while (AuAtomicCompareExchange(&this->uWaiters_, uWaiters - uWaitCount, uWaiters) != uWaiters)
|
||||
{
|
||||
uWaiters = this->uWaiters_;
|
||||
|
||||
if (uWaiters == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pWaitable)
|
||||
{
|
||||
pWaitable->Lock();
|
||||
}
|
||||
}
|
||||
|
||||
void SemaphoreConditionVariableImpl::WaitForSignal(IWaitable *pWaitable)
|
||||
{
|
||||
return WaitForSignal(AuUnsafeRaiiToShared(pWaitable));
|
||||
}
|
||||
|
||||
void SemaphoreConditionVariableImpl::WaitForSignal(const AuSPtr<Threading::IWaitable> &pWaitable)
|
||||
void SemaphoreConditionVariableImpl::WaitForSignal(const AuSPtr<IWaitable> &pWaitable)
|
||||
{
|
||||
AuAtomicAdd(&this->waiters_, 1u);
|
||||
AuAtomicAdd(&this->uWaiters_, 1u);
|
||||
|
||||
if (pWaitable)
|
||||
{
|
||||
@ -65,16 +114,16 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt32 uWaitCount {};
|
||||
AuUInt32 uWaiters {};
|
||||
|
||||
uWaiters = this->waiters_;
|
||||
uWaiters = this->uWaiters_;
|
||||
if (uWaiters > 0)
|
||||
{
|
||||
this->s_.Unlock();
|
||||
uWaitCount = 1;
|
||||
}
|
||||
|
||||
while (AuAtomicCompareExchange(&this->waiters_, uWaiters - uWaitCount, uWaiters) != uWaiters)
|
||||
while (AuAtomicCompareExchange(&this->uWaiters_, uWaiters - uWaitCount, uWaiters) != uWaiters)
|
||||
{
|
||||
uWaiters = this->waiters_;
|
||||
uWaiters = this->uWaiters_;
|
||||
|
||||
if (uWaiters == 0)
|
||||
{
|
||||
@ -88,16 +137,16 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt32 uWaitCount {};
|
||||
AuUInt32 uWaiters {};
|
||||
|
||||
uWaiters = this->waiters_;
|
||||
uWaiters = this->uWaiters_;
|
||||
if (uWaiters > 0)
|
||||
{
|
||||
this->s_.Unlock(uWaiters);
|
||||
uWaitCount = uWaiters;
|
||||
}
|
||||
|
||||
while (AuAtomicCompareExchange(&this->waiters_, uWaiters - uWaitCount, uWaiters) != uWaiters)
|
||||
while (AuAtomicCompareExchange(&this->uWaiters_, uWaiters - uWaitCount, uWaiters) != uWaiters)
|
||||
{
|
||||
uWaiters = this->waiters_;
|
||||
uWaiters = this->uWaiters_;
|
||||
|
||||
if (uWaiters <= uWaitCount)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user