[*] (NT Condvar) Minor performance fix
[*] (NT Condvar) Suspected XP-Win7 deadlock
This commit is contained in:
parent
e853b44ee6
commit
367118ab0c
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user