[*] Finally fixed an old regression: RWLock is back to being write-biased to prevent forever-read conditions
This commit is contained in:
parent
109b0cff3f
commit
cea3362186
@ -382,6 +382,8 @@ namespace Aurora
|
|||||||
AuUInt64 bWinXpThrough7BlazeOptimizerPower : 7 { 6 }; // dont worry about it. we dont care about old portables. lets try to make older win32 targets tweak the scheduling in our favor a bit.
|
AuUInt64 bWinXpThrough7BlazeOptimizerPower : 7 { 6 }; // dont worry about it. we dont care about old portables. lets try to make older win32 targets tweak the scheduling in our favor a bit.
|
||||||
AuUInt64 bPreferLinuxPrimitivesFutexNoSpin : 1 { false };
|
AuUInt64 bPreferLinuxPrimitivesFutexNoSpin : 1 { false };
|
||||||
AuUInt64 bPreferUnixPrimitivesNoSpin : 1 { false };
|
AuUInt64 bPreferUnixPrimitivesNoSpin : 1 { false };
|
||||||
|
AuUInt64 bAlwaysRWLockWriteBiasOnReadLock : 1 { false };
|
||||||
|
AuUInt64 bEnableRWLockWriteBiasOnReadLock : 1 { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DummyConfig
|
struct DummyConfig
|
||||||
|
@ -208,11 +208,11 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool bIsWriteRecursionAllowed>
|
template<bool bIsWriteRecursionAllowed>
|
||||||
bool RWLockImpl<bIsWriteRecursionAllowed>::LockReadNS(AuUInt64 uTimeout)
|
bool RWLockImpl<bIsWriteRecursionAllowed>::LockReadNS(AuUInt64 uTimeout)
|
||||||
{
|
{
|
||||||
if (this->TryLockReadNoSpin())
|
if (this->TryLockReadNoSpin<true>())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
if (AuAtomicLoad(&this->state_) == 1 &&
|
if (AuAtomicLoad(&this->state_) == 1 &&
|
||||||
AuAtomicLoad(&this->writersPending_) > 1)
|
AuAtomicLoad(&this->writersPending_) > 1)
|
||||||
{
|
{
|
||||||
this->SignalManyWriter();
|
this->SignalManyWriter(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +479,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
if (AuAtomicLoad(&this->state_) == 1 &&
|
if (AuAtomicLoad(&this->state_) == 1 &&
|
||||||
AuAtomicLoad(&this->writersPending_) > 1)
|
AuAtomicLoad(&this->writersPending_) > 1)
|
||||||
{
|
{
|
||||||
this->SignalManyWriter();
|
this->SignalManyWriter(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,12 +541,12 @@ namespace Aurora::Threading::Primitives
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool bIsWriteRecursionAllowed>
|
template<bool bIsWriteRecursionAllowed>
|
||||||
void RWLockImpl<bIsWriteRecursionAllowed>::SignalManyWriter()
|
void RWLockImpl<bIsWriteRecursionAllowed>::SignalManyWriter(int iBias)
|
||||||
{
|
{
|
||||||
if (gUseFutexRWLock)
|
if (gUseFutexRWLock)
|
||||||
{
|
{
|
||||||
auto pThat = this->GetFutexConditionWriter();
|
auto pThat = this->GetFutexConditionWriter();
|
||||||
AuUInt32 uCount = AuAtomicLoad(&this->writersPending_);
|
AuUInt32 uCount = AuAtomicLoad(&this->writersPending_) + iBias;
|
||||||
AuAtomicAdd(pThat, uCount);
|
AuAtomicAdd(pThat, uCount);
|
||||||
InternalLTSWakeCount(pThat, uCount);
|
InternalLTSWakeCount(pThat, uCount);
|
||||||
}
|
}
|
||||||
@ -563,16 +563,17 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
return DoTryIf([=]()
|
return DoTryIf([=]()
|
||||||
{
|
{
|
||||||
return TryLockReadNoSpin();
|
return TryLockReadNoSpin<true>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return TryLockReadNoSpin();
|
return TryLockReadNoSpin<true>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool bIsWriteRecursionAllowed>
|
template<bool bIsWriteRecursionAllowed>
|
||||||
|
template<bool CheckWrite>
|
||||||
bool RWLockImpl<bIsWriteRecursionAllowed>::TryLockReadNoSpin()
|
bool RWLockImpl<bIsWriteRecursionAllowed>::TryLockReadNoSpin()
|
||||||
{
|
{
|
||||||
auto iCurState = this->state_;
|
auto iCurState = this->state_;
|
||||||
@ -582,6 +583,16 @@ namespace Aurora::Threading::Primitives
|
|||||||
return this->reentrantWriteLockHandle_ == GetThreadCookie();
|
return this->reentrantWriteLockHandle_ == GetThreadCookie();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constexpr (CheckWrite)
|
||||||
|
{
|
||||||
|
if ((AuAtomicLoad(&this->writersPending_)) &&
|
||||||
|
(iCurState > 0 || gRuntimeConfig.threadingConfig.bAlwaysRWLockWriteBiasOnReadLock) &&
|
||||||
|
(gRuntimeConfig.threadingConfig.bEnableRWLockWriteBiasOnReadLock))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AuAtomicCompareExchange(&this->state_, iCurState + 1, iCurState) == iCurState;
|
return AuAtomicCompareExchange(&this->state_, iCurState + 1, iCurState) == iCurState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,8 @@ namespace Aurora::Threading::Primitives
|
|||||||
auline bool LockWriteNS(AuUInt64 timeout);// override;
|
auline bool LockWriteNS(AuUInt64 timeout);// override;
|
||||||
auline bool LockWriteNSAbs(AuUInt64 timeout);// override;
|
auline bool LockWriteNSAbs(AuUInt64 timeout);// override;
|
||||||
auline bool TryLockRead();// override;
|
auline bool TryLockRead();// override;
|
||||||
auline bool TryLockReadNoSpin();// override;
|
template<bool CheckWrite>
|
||||||
|
auline bool TryLockReadNoSpin();
|
||||||
auline bool TryLockWrite();// override;
|
auline bool TryLockWrite();// override;
|
||||||
auline void UnlockRead();// override;
|
auline void UnlockRead();// override;
|
||||||
auline void UnlockWrite();// override;
|
auline void UnlockWrite();// override;
|
||||||
@ -94,7 +95,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
auline void SignalOneReader();
|
auline void SignalOneReader();
|
||||||
auline void SignalOneWriter();
|
auline void SignalOneWriter();
|
||||||
auline void SignalManyReader();
|
auline void SignalManyReader();
|
||||||
auline void SignalManyWriter();
|
auline void SignalManyWriter(int iBias = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user