[*] RWLock: simplify writersPending_ guard

[*] Fix RWLock: I may have messed up the new fast path timeouts in RWLock
[*] RWLock: refactoring/improvements
This commit is contained in:
Reece Wilson 2023-08-30 15:09:09 +01:00
parent cf118d0b4b
commit affe4cc496

View File

@ -277,6 +277,8 @@ namespace Aurora::Threading::Primitives
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
bool RWLockImpl<bIsWriteRecursionAllowed>::LockWriteNSAbs(AuUInt64 uTimeout) bool RWLockImpl<bIsWriteRecursionAllowed>::LockWriteNSAbs(AuUInt64 uTimeout)
{ {
bool bRet {};
if constexpr (!bIsWriteRecursionAllowed) if constexpr (!bIsWriteRecursionAllowed)
{ {
if (TryLockWrite()) if (TryLockWrite())
@ -305,15 +307,23 @@ namespace Aurora::Threading::Primitives
} }
} }
AuAtomicAdd(&this->writersPending_, 1);
if (gUseFutexRWLock) if (gUseFutexRWLock)
{ {
return this->LockWriteNSAbsUnlocked(uTimeout); bRet = this->LockWriteNSAbsUnlocked(uTimeout);
} }
else else
{ {
AU_LOCK_GUARD(this->mutex_); AU_LOCK_GUARD(this->mutex_);
return this->LockWriteNSAbsUnlocked(uTimeout);
bRet = this->LockWriteNSAbsUnlocked(uTimeout);
} }
AuAtomicSub(&this->writersPending_, 1);
return bRet;
} }
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
@ -371,20 +381,28 @@ namespace Aurora::Threading::Primitives
} }
} }
bool bRet {};
AuInt64 uEndTime {};
AuAtomicAdd(&this->writersPending_, 1);
if (gUseFutexRWLock) if (gUseFutexRWLock)
{ {
AuInt64 uEndTime = uTimeout ? AuTime::SteadyClockNS() + uTimeout : 0; uEndTime = uTimeout ? AuTime::SteadyClockNS() + uTimeout : 0;
return this->LockWriteNSAbsUnlocked(uEndTime); bRet = this->LockWriteNSAbsUnlocked(uEndTime);
} }
else else
{ {
uEndTime = uTimeout ? AuTime::SteadyClockNS() + uTimeout : 0;
AU_LOCK_GUARD(this->mutex_); AU_LOCK_GUARD(this->mutex_);
AuInt64 uEndTime = uTimeout ? AuTime::SteadyClockNS() + uTimeout : 0; bRet = this->LockWriteNSAbsUnlocked(uEndTime);
return this->LockWriteNSAbsUnlocked(uEndTime);
} }
AuAtomicSub(&this->writersPending_, 1);
return bRet;
} }
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
@ -405,35 +423,21 @@ namespace Aurora::Threading::Primitives
AuInt32 iCurState; AuInt32 iCurState;
while ((iCurState = AuAtomicLoad(&this->state_)) != 0) while ((iCurState = AuAtomicLoad(&this->state_)) != 0)
{ {
bool bStatusTwo {};
AuAtomicAdd(&this->writersPending_, 1);
static const AuUInt32 kExpect { 0 }; static const AuUInt32 kExpect { 0 };
if ((iCurState = AuAtomicLoad(&this->state_)) == 0) if (!WaitOnAddressSteady(pSemaphore, &kExpect, sizeof(kExpect), qwTimeoutNS))
{
bStatus = true;
bStatusTwo = true;
}
else
{
bStatus = WaitOnAddress(pSemaphore, &kExpect, sizeof(kExpect), qwTimeoutNS);
}
AuAtomicSub(&this->writersPending_, 1);
if (!bStatus)
{ {
break; break;
} }
if constexpr (bIsWriteRecursionAllowed) if constexpr (bIsWriteRecursionAllowed)
{ {
if (AuAtomicLoad(&this->state_) == 1) if (AuAtomicLoad(&this->state_) == 1 &&
AuAtomicLoad(&this->writersPending_) > 1)
{ {
this->SignalManyWriter(); this->SignalManyWriter();
} }
} }
if (!bStatusTwo)
{
while (true) while (true)
{ {
auto uState = *pSemaphore; auto uState = *pSemaphore;
@ -450,7 +454,6 @@ namespace Aurora::Threading::Primitives
} }
} }
} }
}
else else
{ {
if (qwTimeoutNS) if (qwTimeoutNS)
@ -463,19 +466,17 @@ namespace Aurora::Threading::Primitives
} }
} }
AuAtomicAdd(&this->writersPending_, 1);
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
bStatus = this->GetConditionWriter().WaitForSignalNS(uSecondTimeout); bStatus = this->GetConditionWriter().WaitForSignalNS(uSecondTimeout);
#else #else
bStatus = this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, uSecondTimeout); bStatus = this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, uSecondTimeout);
#endif #endif
AuAtomicSub(&this->writersPending_, 1);
} }
if constexpr (bIsWriteRecursionAllowed) if constexpr (bIsWriteRecursionAllowed)
{ {
if (AuAtomicLoad(&this->state_) == 1 && if (AuAtomicLoad(&this->state_) == 1 &&
AuAtomicLoad(&this->writersPending_)) AuAtomicLoad(&this->writersPending_) > 1)
{ {
this->SignalManyWriter(); this->SignalManyWriter();
} }
@ -821,7 +822,7 @@ namespace Aurora::Threading::Primitives
} }
else else
{ {
bStatus = WaitOnAddress(pSemaphore, &kExpect, sizeof(kExpect), uEndTime); bStatus = WaitOnAddressSteady(pSemaphore, &kExpect, sizeof(kExpect), uEndTime);
} }
AuAtomicSub(&this->writersPending_, 1); AuAtomicSub(&this->writersPending_, 1);
@ -885,7 +886,8 @@ namespace Aurora::Threading::Primitives
return true; return true;
} }
} }
else
{
AU_LOCK_GUARD(this->mutex_); AU_LOCK_GUARD(this->mutex_);
if (AuAtomicCompareExchange(&this->state_, 1, -1) == -1) if (AuAtomicCompareExchange(&this->state_, 1, -1) == -1)
@ -898,6 +900,7 @@ namespace Aurora::Threading::Primitives
return false; return false;
} }
} }
}
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
IWaitable *RWLockImpl<bIsWriteRecursionAllowed>::AsReadable() IWaitable *RWLockImpl<bIsWriteRecursionAllowed>::AsReadable()