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