[*] Minor optimizations: AuThreading::Waitable::Futex*

This commit is contained in:
Reece Wilson 2023-08-20 17:11:50 +01:00
parent b8d4e02ab5
commit 58302586a9
3 changed files with 61 additions and 25 deletions

View File

@ -169,22 +169,38 @@ namespace Aurora::Threading::Waitables
volatile AuUInt32 uAtomicSleeping {};
private:
auline bool TryLock3()
{
auto old = this->uAtomicState;
return ((old != 0 && AuAtomicCompareExchange(&this->uAtomicState, old - 1, old) == old));
}
auline bool TryLock2()
{
for (AU_ITERATE_N(i, AuUInt(GetTotalSpinCountTimeout())))
if (TryLock3())
{
#if defined(AURORA_ARCH_X86) || defined(AURORA_ARCH_X64)
_mm_pause();
#else
Threading::ContextYield();
#endif
return true;
}
auto old = this->uAtomicState;
if ((old != 0 && AuAtomicCompareExchange(&this->uAtomicState, old - 1, old) == old))
#if defined(AURORA_ARCH_X86) || defined(AURORA_ARCH_X64)
AuUInt uCount(GetTotalSpinCountTimeout());
for (AU_ITERATE_N(i, uCount))
{
_mm_pause();
if (TryLock3())
{
return true;
}
}
#else
static const AuUInt32 kRef { 0 };
if (TryWaitOnAddress(&this->uAtomicState, &kRef, sizeof(kRef)))
{
return TryLock3();
}
#endif
return false;
}

View File

@ -19,23 +19,26 @@ namespace Aurora::Threading::Waitables
AU_NO_COPY_NO_MOVE(FutexSemaphoreWaitable);
auline bool TryLockNoSpin()
{
auto uState = this->uAtomicState;
return (uState != 0 && AuAtomicCompareExchange(&this->uAtomicState, uState - 1, uState) == uState);
}
inline bool TryLock() override
{
if (TryLockNoSpin())
{
auto uState = this->uAtomicState;
if (uState != 0 && AuAtomicCompareExchange(&this->uAtomicState, uState - 1, uState) == uState)
{
return true;
}
return true;
}
#if defined(AURORA_ARCH_X86) || defined(AURORA_ARCH_X64)
for (AU_ITERATE_N(i, AuUInt(GetTotalSpinCountTimeout())))
AuUInt uCount(GetTotalSpinCountTimeout());
for (AU_ITERATE_N(i, uCount))
{
_mm_pause();
auto uState = this->uAtomicState;
if (uState != 0 && AuAtomicCompareExchange(&this->uAtomicState, uState - 1, uState) == uState)
if (TryLockNoSpin())
{
return true;
}
@ -44,11 +47,7 @@ namespace Aurora::Threading::Waitables
static const AuUInt32 kRef { 0 };
if (TryWaitOnAddress(&this->uAtomicState, &kRef, sizeof(kRef)))
{
auto uState = this->uAtomicState;
if (uState != 0 && AuAtomicCompareExchange(&this->uAtomicState, uState - 1, uState) == uState)
{
return true;
}
return TryLockNoSpin();
}
#endif
@ -89,7 +88,12 @@ namespace Aurora::Threading::Waitables
{
static const AuUInt32 kRef { 0 };
while (!TryLock())
if (TryLock())
{
return;
}
while (!TryLockNoSpin())
{
AuAtomicAdd(&this->uAtomicSleeping, 1u);
WaitOnAddress((void *)&this->uAtomicState, &kRef, sizeof(kRef), 0);
@ -111,9 +115,19 @@ namespace Aurora::Threading::Waitables
{
static const AuUInt32 kRef { 0 };
if (TryLockNoSpin())
{
return true;
}
auto qwEndTime = Time::SteadyClockNS() + qwTimeout;
while (!TryLock())
if (TryLock())
{
return true;
}
while (!TryLockNoSpin())
{
bool bStatus {};

View File

@ -32,7 +32,8 @@ namespace Aurora::Threading::Waitables
}
#if defined(AURORA_ARCH_X86) || defined(AURORA_ARCH_X64)
for (AU_ITERATE_N(i, AuUInt(GetTotalSpinCountTimeout())))
AuUInt uCount(GetTotalSpinCountTimeout());
for (AU_ITERATE_N(i, uCount))
{
_mm_pause();
@ -110,13 +111,18 @@ namespace Aurora::Threading::Waitables
{
static const AuUInt32 kRef { 1 };
if (TryLock())
if (TryLockNoSpin())
{
return true;
}
auto qwEndTime = Time::SteadyClockNS() + qwTimeout;
if (TryLock())
{
return true;
}
while (!TryLockNoSpin())
{
bool bStatus {};