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