[*] Reoptimize semaphore wait paths
This commit is contained in:
parent
03a3532a20
commit
a4d317a48d
@ -68,7 +68,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
AuUInt64 uStart {};
|
AuUInt64 uStart {};
|
||||||
AuUInt64 uEnd {};
|
AuUInt64 uEnd {};
|
||||||
|
|
||||||
if (this->TryLockHeavy())
|
if (this->TryLockNoSpin())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -84,6 +84,11 @@ namespace Aurora::Threading::Primitives
|
|||||||
Time::monoabsns2ts(&tspec, uEnd);
|
Time::monoabsns2ts(&tspec, uEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->TryLockHeavy())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
|
|
||||||
auto old = this->dwState_;
|
auto old = this->dwState_;
|
||||||
@ -137,6 +142,89 @@ namespace Aurora::Threading::Primitives
|
|||||||
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SemaphoreImpl::LockAbsMS(AuUInt64 timeout)
|
||||||
|
{
|
||||||
|
return this->LockAbsNS(AuMSToNS<AuUInt64>(timeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SemaphoreImpl::LockAbsNS(AuUInt64 uTimeout)
|
||||||
|
{
|
||||||
|
AuUInt64 uEnd {};
|
||||||
|
|
||||||
|
if (this->TryLockNoSpin())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
struct timespec tspec;
|
||||||
|
if (uTimeout != 0)
|
||||||
|
{
|
||||||
|
uEnd = uTimeout;
|
||||||
|
|
||||||
|
Time::monoabsns2ts(&tspec, uEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->TryLockHeavy())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
|
|
||||||
|
auto old = this->dwState_;
|
||||||
|
//!tryLock (with old in a scope we can access)
|
||||||
|
while (!((old != 0) &&
|
||||||
|
(AuAtomicCompareExchange(&this->dwState_, old - 1, old) == old)))
|
||||||
|
{
|
||||||
|
if (uTimeout != 0)
|
||||||
|
{
|
||||||
|
if (Time::SteadyClockNS() >= uEnd)
|
||||||
|
{
|
||||||
|
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret {};
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = futex_wait(&this->dwState_, 0, &tspec);
|
||||||
|
}
|
||||||
|
while (ret == EINTR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ret {};
|
||||||
|
bool bStatus {};
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((ret = futex_wait(&this->dwState_, 0)) == 0)
|
||||||
|
{
|
||||||
|
bStatus = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == EAGAIN || errno == EAGAIN)
|
||||||
|
{
|
||||||
|
bStatus = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
while (ret == EINTR);
|
||||||
|
|
||||||
|
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "semaphore wait failed: {}", ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
old = this->dwState_;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void SemaphoreImpl::Lock()
|
void SemaphoreImpl::Lock()
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,8 @@ namespace Aurora::Threading::Primitives
|
|||||||
bool TryLock() override;
|
bool TryLock() override;
|
||||||
bool LockMS(AuUInt64 timeout) override;
|
bool LockMS(AuUInt64 timeout) override;
|
||||||
bool LockNS(AuUInt64 timeout) override;
|
bool LockNS(AuUInt64 timeout) override;
|
||||||
|
bool LockAbsMS(AuUInt64 timeout) override;
|
||||||
|
bool LockAbsNS(AuUInt64 timeout) override;
|
||||||
void Lock() override;
|
void Lock() override;
|
||||||
void Unlock(AuUInt16 count) override;
|
void Unlock(AuUInt16 count) override;
|
||||||
void Unlock() override;
|
void Unlock() override;
|
||||||
|
@ -67,7 +67,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool SemaphoreImpl::LockNS(AuUInt64 uTimeout)
|
bool SemaphoreImpl::LockNS(AuUInt64 uTimeout)
|
||||||
{
|
{
|
||||||
if (this->TryLockHeavy())
|
if (this->TryLockNoSpin())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -75,6 +75,11 @@ namespace Aurora::Threading::Primitives
|
|||||||
AuUInt64 uStart = AuTime::SteadyClockNS();
|
AuUInt64 uStart = AuTime::SteadyClockNS();
|
||||||
AuUInt64 uEnd = uTimeout ? uStart + uTimeout : 0;
|
AuUInt64 uEnd = uTimeout ? uStart + uTimeout : 0;
|
||||||
|
|
||||||
|
if (this->TryLockHeavy())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (gUseNativeWaitSemapahore)
|
if (gUseNativeWaitSemapahore)
|
||||||
{
|
{
|
||||||
AuUInt32 uYieldCounter {};
|
AuUInt32 uYieldCounter {};
|
||||||
|
Loading…
Reference in New Issue
Block a user