[*] NT: backport unix optimization - no spin during spurious wake up
This commit is contained in:
parent
536522743a
commit
a977f0d1b5
@ -48,17 +48,32 @@ namespace Aurora::Threading::Primitives
|
||||
#else
|
||||
return DoTryIf([=]()
|
||||
{
|
||||
return !AuAtomicTestAndSet(&this->lock_.uWaitCount, 0);
|
||||
return this->TryLockNoSpin();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Win32ConditionMutex::TryLockNoSpin()
|
||||
{
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
return ::TryAcquireSRWLockExclusive(&this->lock_);
|
||||
#else
|
||||
return AuAtomicTestAndSet(&this->lock_.uWaitCount, 0) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Win32ConditionMutex::Lock()
|
||||
{
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
::AcquireSRWLockExclusive(&this->lock_);
|
||||
#else
|
||||
while (!TryLock())
|
||||
|
||||
if (this->TryLock())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (!this->TryLockNoSpin())
|
||||
{
|
||||
auto &uValueRef = this->lock_.uWaitCount;
|
||||
auto uValue = uValueRef | 1;
|
||||
|
@ -24,6 +24,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
inline HANDLE gKeyedEventHandle { INVALID_HANDLE_VALUE };
|
||||
|
||||
// Actually NT5.x
|
||||
struct NT4Mutex
|
||||
{
|
||||
volatile AuUInt32 uWaitCount {}; // yields while bits are high, dec to release one from the semaphore yield
|
||||
@ -39,6 +40,8 @@ namespace Aurora::Threading::Primitives
|
||||
auline void Unlock() override;
|
||||
AuUInt GetOSHandle() override;
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
|
||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||
NT4Mutex lock_;
|
||||
#else
|
||||
|
@ -48,10 +48,15 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
{
|
||||
return AuAtomicTestAndSet(&this->state_, 0) == 0;
|
||||
return this->TryLockNoSpin();
|
||||
});
|
||||
}
|
||||
|
||||
bool MutexImpl::TryLockNoSpin()
|
||||
{
|
||||
return AuAtomicTestAndSet(&this->state_, 0) == 0;
|
||||
}
|
||||
|
||||
bool MutexImpl::HasLockImplementation()
|
||||
{
|
||||
return true;
|
||||
@ -77,7 +82,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
if (TryLock())
|
||||
if (this->TryLock())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -87,7 +92,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
if (gUseNativeWaitMutex)
|
||||
{
|
||||
while (!TryLock())
|
||||
while (!this->TryLockNoSpin())
|
||||
{
|
||||
auto &uValueRef = this->state_;
|
||||
auto uValue = uValueRef | 1;
|
||||
@ -110,13 +115,13 @@ namespace Aurora::Threading::Primitives
|
||||
::AcquireSRWLockShared(&this->atomicHolder_);
|
||||
|
||||
BOOL status = false;
|
||||
while (!this->TryLock())
|
||||
while (!this->TryLockNoSpin())
|
||||
{
|
||||
AuUInt32 uTimeoutMS = INFINITE;
|
||||
|
||||
if (uTimeout != 0)
|
||||
{
|
||||
uStartTime = Time::SteadyClockNS();
|
||||
auto uStartTime = Time::SteadyClockNS();
|
||||
if (uStartTime >= uEndTime)
|
||||
{
|
||||
goto exitWin32;
|
||||
@ -146,7 +151,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
if (!uTimeout)
|
||||
{
|
||||
while (!TryLock())
|
||||
while (!this->TryLockNoSpin())
|
||||
{
|
||||
auto &uValueRef = this->state_;
|
||||
auto uValue = uValueRef | 1;
|
||||
@ -169,14 +174,14 @@ namespace Aurora::Threading::Primitives
|
||||
auto uEndTimeWall = AuTime::CurrentClockNS() + uTimeout;
|
||||
bool bFailed {};
|
||||
|
||||
while (bFailed || (!TryLock()))
|
||||
while (bFailed || (!this->TryLockNoSpin()))
|
||||
{
|
||||
auto uValue = uValueRef | 1;
|
||||
|
||||
if (!bFailed &&
|
||||
AuTime::SteadyClockNS() >= uEndTimeSteady)
|
||||
{
|
||||
returnValue = TryLock();
|
||||
returnValue = this->TryLock();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ namespace Aurora::Threading::Primitives
|
||||
bool LockNS(AuUInt64 timeout) override;
|
||||
void Unlock() override;
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
|
||||
private:
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
SRWLOCK atomicHolder_;
|
||||
|
Loading…
Reference in New Issue
Block a user