[*] (NT Condvar) Minor performance fix

[*] (NT Condvar) Suspected XP-Win7 deadlock
This commit is contained in:
Reece Wilson 2023-12-06 18:24:52 +00:00
parent e853b44ee6
commit 367118ab0c
2 changed files with 49 additions and 74 deletions

View File

@ -67,17 +67,10 @@ namespace Aurora::Threading::Primitives
// Reverted: 5b495f7fd9495aa55395666e166ac499955215dc
if (ThrdCfg::gPreferNtCondvarModernWinSpin)
{
if (!bIOU)
if (this->CheckOut())
{
#if 0
bIOU = CheckOut();
#else
if (CheckOut())
{
pMutex->Lock();
return true;
}
#endif
pMutex->Lock();
return true;
}
}
@ -91,7 +84,7 @@ namespace Aurora::Threading::Primitives
{
if (!bIOU)
{
bIOU = CheckOut();
bIOU = this->CheckOut();
}
}
@ -132,30 +125,14 @@ namespace Aurora::Threading::Primitives
pMutex->Lock();
}
#if !defined(AU_TRUST_NT_KERNEL_SCHED_TIMEOUT)
if (!bRet)
#else
if (!bRet && uEndTimeSteady <= AuTime::SteadyClockNS())
#endif
{
auto uNow = this->wlist;
auto uOld = (uNow >> kShiftCountByBits);
if (uOld == 0)
{
// broadcast has woken everyone up
if (bIOU || CheckOut()) // the cope acquire
{
// in which case we're good
return true;
}
else
{
// ...and now we might owe NtReleaseKeyedEvent a thread >:(
bRet = false;
continue;
}
continue;
}
// go for an atomic decrement while racing against ::Signal and ::Broadcast
@ -164,21 +141,17 @@ namespace Aurora::Threading::Primitives
if (AuAtomicCompareExchange(&this->wlist, uNext, uNow) == uNow)
{
// break if successful
return bIOU;
}
else
{
// block again because we couldn't decrement the counter
// broadcast still thinks we're asleep
// ...and we still owe NtReleaseKeyedEvent 1 therad
continue;
}
}
else
{
// we good?
if (bIOU || CheckOut())
if (bIOU || this->CheckOut())
{
return true;
}
@ -208,13 +181,10 @@ namespace Aurora::Threading::Primitives
{
if (ThrdCfg::gPreferNtCondvarModernWinSpin)
{
if (!bIOU)
if (this->CheckOut())
{
if (CheckOut())
{
pMutex->Lock();
return true;
}
pMutex->Lock();
return true;
}
}
@ -227,7 +197,7 @@ namespace Aurora::Threading::Primitives
{
if (!bIOU)
{
bIOU = CheckOut();
bIOU = this->CheckOut();
}
}
@ -236,7 +206,8 @@ namespace Aurora::Threading::Primitives
pMutex->Lock();
if (bIOU || CheckOut())
if (bIOU ||
this->CheckOutNoSpin())
{
return bRet;
}
@ -281,6 +252,41 @@ namespace Aurora::Threading::Primitives
#endif
}
bool ConditionVariableNT::CheckOutNoSpin()
{
auto uSignalNow = this->signalCount;
if (uSignalNow == 0)
{
return false;
}
auto uSignalNext = uSignalNow - 1;
if (AuAtomicCompareExchange(&this->signalCount, uSignalNext, uSignalNow) != uSignalNow)
{
return false;
}
if constexpr (kBoolRequiredLateSet)
{
if (uSignalNext == 0)
{
InterlockedOr((volatile LONG *)&this->wlist, 1);
// paranoia
#if 1
if (AuAtomicLoad(&this->signalCount) != 0) [[unlikely]]
{
AuAtomicUnset(&this->wlist, 0);
}
#endif
}
}
return true;
}
bool ConditionVariableNT::CheckOut()
{
#if defined(AURORA_FORCE_SRW_LOCKS)
@ -288,37 +294,7 @@ namespace Aurora::Threading::Primitives
#else
return DoTryIf([&]()
{
auto uSignalNow = this->signalCount;
if (uSignalNow == 0)
{
return false;
}
auto uSignalNext = uSignalNow - 1;
if (AuAtomicCompareExchange(&this->signalCount, uSignalNext, uSignalNow) != uSignalNow)
{
return false;
}
if constexpr (kBoolRequiredLateSet)
{
if (uSignalNext == 0)
{
InterlockedOr((volatile LONG *)&this->wlist, 1);
// paranoia
#if 1
if (AuAtomicLoad(&this->signalCount) != 0) [[unlikely]]
{
AuAtomicUnset(&this->wlist, 0);
}
#endif
}
}
return true;
return this->CheckOutNoSpin();
});
#endif
}
@ -362,7 +338,6 @@ namespace Aurora::Threading::Primitives
void ConditionVariableNT::Broadcast()
{
#if !defined(AURORA_FORCE_SRW_LOCKS)
if (gUseNativeWaitCondvar)
{
auto original = this->wlist;
@ -436,7 +411,6 @@ namespace Aurora::Threading::Primitives
void ConditionVariableNT::BroadcastN(AuUInt32 nBroadcast)
{
#if !defined(AURORA_FORCE_SRW_LOCKS)
if (gUseNativeWaitCondvar)
{
auto original = this->wlist;

View File

@ -22,6 +22,7 @@ namespace Aurora::Threading::Primitives
void BroadcastN(AuUInt32 nBroadcast);
auline bool CheckOut();
auline bool CheckOutNoSpin();
private:
#if defined(AURORA_FORCE_SRW_LOCKS)