[*] Guess I should finalize this for linux. The verbosity of writing a cas in the wait loops is stupid if we arent doing anything special with the bits.
This commit is contained in:
parent
00260294b2
commit
4b0a7c651a
@ -75,9 +75,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
AuAtomicAdd(&this->uSleeping_, 1u);
|
AuAtomicAdd(&this->uSleeping_, 1u);
|
||||||
|
|
||||||
auto state = this->uState_;
|
while (!this->TryLockNoSpin())
|
||||||
while (!(state == 0 &&
|
|
||||||
AuAtomicCompareExchange<AuUInt32>(&this->uState_, 1, state) == state))
|
|
||||||
{
|
{
|
||||||
if (uTimeout != 0)
|
if (uTimeout != 0)
|
||||||
{
|
{
|
||||||
@ -90,7 +88,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
int ret {};
|
int ret {};
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = futex_wait(&this->uState_, state, &tspec);
|
ret = futex_wait(&this->uState_, 1, &tspec);
|
||||||
}
|
}
|
||||||
while (ret == -EINTR);
|
while (ret == -EINTR);
|
||||||
}
|
}
|
||||||
@ -101,7 +99,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((ret = futex_wait(&this->uState_, state)) == 0)
|
if ((ret = futex_wait(&this->uState_, 1)) == 0)
|
||||||
{
|
{
|
||||||
bStatus = true;
|
bStatus = true;
|
||||||
break;
|
break;
|
||||||
@ -118,8 +116,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
state = this->uState_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AuAtomicSub(&this->uSleeping_, 1u);
|
AuAtomicSub(&this->uSleeping_, 1u);
|
||||||
@ -170,9 +166,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
AuAtomicAdd(&this->uSleeping_, 1u);
|
AuAtomicAdd(&this->uSleeping_, 1u);
|
||||||
|
|
||||||
auto state = this->uState_;
|
while (!this->TryLockNoSpin())
|
||||||
while (!(state == 0 &&
|
|
||||||
AuAtomicCompareExchange<AuUInt32>(&this->uState_, 1, state) == state))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int ret {};
|
int ret {};
|
||||||
@ -180,7 +174,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((ret = futex_wait(&this->uState_, state)) == 0)
|
if ((ret = futex_wait(&this->uState_, 1)) == 0)
|
||||||
{
|
{
|
||||||
bStatus = true;
|
bStatus = true;
|
||||||
break;
|
break;
|
||||||
@ -196,8 +190,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
while (ret == -EINTR);
|
while (ret == -EINTR);
|
||||||
|
|
||||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
||||||
|
|
||||||
state = this->uState_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AuAtomicSub(&this->uSleeping_, 1u);
|
AuAtomicSub(&this->uSleeping_, 1u);
|
||||||
|
@ -101,9 +101,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
Time::monoabsns2ts(&tspec, uEnd);
|
Time::monoabsns2ts(&tspec, uEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto state = this->state_;
|
while (!this->TryLockNoSpin())
|
||||||
while (!(state == 0 &&
|
|
||||||
AuAtomicCompareExchange<AuUInt32>(&this->state_, 1, state) == state))
|
|
||||||
{
|
{
|
||||||
if (uTimeout != 0)
|
if (uTimeout != 0)
|
||||||
{
|
{
|
||||||
@ -116,7 +114,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
int ret {};
|
int ret {};
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ret = futex_wait(&this->state_, state, &tspec);
|
ret = futex_wait(&this->state_, 1, &tspec);
|
||||||
}
|
}
|
||||||
while (ret == -EINTR);
|
while (ret == -EINTR);
|
||||||
}
|
}
|
||||||
@ -127,7 +125,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((ret = futex_wait(&this->state_, state)) == 0)
|
if ((ret = futex_wait(&this->state_, 1)) == 0)
|
||||||
{
|
{
|
||||||
bStatus = true;
|
bStatus = true;
|
||||||
break;
|
break;
|
||||||
@ -144,8 +142,84 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state = this->state_;
|
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MutexImpl::LockAbsNS(AuUInt64 uTimeout)
|
||||||
|
{
|
||||||
|
struct timespec tspec;
|
||||||
|
|
||||||
|
if (this->TryLockNoSpin())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uTimeout != 0)
|
||||||
|
{
|
||||||
|
Time::monoabsns2ts(&tspec, uTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ThrdCfg::gPreferLinuxPrimitivesFutexNoSpin)
|
||||||
|
{
|
||||||
|
if (this->TryLockNoSpin())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->TryLockHeavy())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuAtomicAdd(&this->dwSleeping_, 1u);
|
||||||
|
|
||||||
|
while (!this->TryLockNoSpin())
|
||||||
|
{
|
||||||
|
if (uTimeout != 0)
|
||||||
|
{
|
||||||
|
if (Time::SteadyClockNS() >= uTimeout)
|
||||||
|
{
|
||||||
|
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret {};
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = futex_wait(&this->state_, 1, &tspec);
|
||||||
|
}
|
||||||
|
while (ret == -EINTR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ret {};
|
||||||
|
bool bStatus {};
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((ret = futex_wait(&this->state_, 1)) == 0)
|
||||||
|
{
|
||||||
|
bStatus = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == -EAGAIN)
|
||||||
|
{
|
||||||
|
bStatus = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
while (ret == -EINTR);
|
||||||
|
|
||||||
|
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "Mutex wait failed: {}", ret)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuAtomicSub(&this->dwSleeping_, 1u);
|
AuAtomicSub(&this->dwSleeping_, 1u);
|
||||||
|
@ -20,6 +20,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
void SlowLock() override;
|
void SlowLock() override;
|
||||||
bool LockMS(AuUInt64 timeout) override;
|
bool LockMS(AuUInt64 timeout) override;
|
||||||
bool LockNS(AuUInt64 timeout) override;
|
bool LockNS(AuUInt64 timeout) override;
|
||||||
|
bool LockAbsNS(AuUInt64 uTimeout);
|
||||||
void Unlock() override;
|
void Unlock() override;
|
||||||
|
|
||||||
auline bool TryLockNoSpin();
|
auline bool TryLockNoSpin();
|
||||||
|
@ -192,10 +192,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
|
|
||||||
auto old = this->dwState_;
|
while (!this->TryLockNoSpin())
|
||||||
//!tryLock (with old in a scope we can access)
|
|
||||||
while (!((old != 0) &&
|
|
||||||
(AuAtomicCompareExchange(&this->dwState_, old - 1, old) == old)))
|
|
||||||
{
|
{
|
||||||
if (uTimeout != 0)
|
if (uTimeout != 0)
|
||||||
{
|
{
|
||||||
@ -236,8 +233,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "semaphore wait failed: {}", ret)
|
RUNTIME_ASSERT_SHUTDOWN_SAFE(bStatus, "semaphore wait failed: {}", ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
old = this->dwState_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
|
Loading…
Reference in New Issue
Block a user