[*] RWLock improvements
This commit is contained in:
parent
8bede175e3
commit
9a2e5674e8
@ -18,6 +18,8 @@ namespace Aurora::Threading::Primitives
|
|||||||
#define ViewParent ((T *)(((char *)this) - (bIsReadView ? RWLockImpl<true>::kOffsetOfRead : RWLockImpl<true>::kOffsetOfWrite)))
|
#define ViewParent ((T *)(((char *)this) - (bIsReadView ? RWLockImpl<true>::kOffsetOfRead : RWLockImpl<true>::kOffsetOfWrite)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const auto kRWThreadWriterHardContextSwitchBias = 15;
|
||||||
|
|
||||||
template<bool bIsReadView, typename T>
|
template<bool bIsReadView, typename T>
|
||||||
void RWLockAccessView<bIsReadView, T>::Unlock()
|
void RWLockAccessView<bIsReadView, T>::Unlock()
|
||||||
{
|
{
|
||||||
@ -152,12 +154,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->writersPending_)
|
|
||||||
{
|
|
||||||
this->GetConditionWriter().Broadcast();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,8 +194,9 @@ namespace Aurora::Threading::Primitives
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuAtomicAdd(&this->writersPending_, 1);
|
||||||
|
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
this->writersPending_++;
|
|
||||||
|
|
||||||
AuInt64 uEndTime = uTimeout ? AuTime::SteadyClockNS() + uTimeout : 0;
|
AuInt64 uEndTime = uTimeout ? AuTime::SteadyClockNS() + uTimeout : 0;
|
||||||
|
|
||||||
@ -215,7 +212,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
if (uSecondTimeout <= 0)
|
if (uSecondTimeout <= 0)
|
||||||
{
|
{
|
||||||
this->writersPending_--;
|
AuAtomicSub(&this->writersPending_, 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +223,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
if (!this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), uSecondTimeout))
|
if (!this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), uSecondTimeout))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
this->writersPending_--;
|
AuAtomicSub(&this->writersPending_, 1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,12 +231,13 @@ namespace Aurora::Threading::Primitives
|
|||||||
if (AuAtomicCompareExchange(&this->state_, -1, 0) == 0)
|
if (AuAtomicCompareExchange(&this->state_, -1, 0) == 0)
|
||||||
{
|
{
|
||||||
this->reentrantWriteLockHandle_ = GetThreadCookie();
|
this->reentrantWriteLockHandle_ = GetThreadCookie();
|
||||||
this->writersPending_--;
|
AuAtomicSub(&this->writersPending_, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->GetConditionWriter().Broadcast();
|
this->GetConditionWriter().Broadcast();
|
||||||
|
this->GetCondition().Broadcast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +263,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
template<bool bIsWriteRecursionAllowed>
|
template<bool bIsWriteRecursionAllowed>
|
||||||
bool RWLockImpl<bIsWriteRecursionAllowed>::TryLockWrite()
|
bool RWLockImpl<bIsWriteRecursionAllowed>::TryLockWrite()
|
||||||
{
|
{
|
||||||
for (AuUInt i = 0; i < 20; i++)
|
for (AU_ITERATE_N(i, kRWThreadWriterHardContextSwitchBias))
|
||||||
{
|
{
|
||||||
auto curVal = this->state_;
|
auto curVal = this->state_;
|
||||||
|
|
||||||
@ -309,61 +307,82 @@ namespace Aurora::Threading::Primitives
|
|||||||
template<bool bIsWriteRecursionAllowed>
|
template<bool bIsWriteRecursionAllowed>
|
||||||
void RWLockImpl<bIsWriteRecursionAllowed>::UnlockRead()
|
void RWLockImpl<bIsWriteRecursionAllowed>::UnlockRead()
|
||||||
{
|
{
|
||||||
|
AuInt32 uVal {};
|
||||||
|
|
||||||
if (this->state_ < 0)
|
if (this->state_ < 0)
|
||||||
{
|
{
|
||||||
SysAssertDbg(this->reentrantWriteLockHandle_ == GetThreadCookie());
|
SysAssertDbg(this->reentrantWriteLockHandle_ == GetThreadCookie());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuInt32 val {};
|
uVal = AuAtomicSub(&this->state_, 1);
|
||||||
bool bElevation {};
|
|
||||||
|
|
||||||
|
if (uVal == 0)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
bool bElevation {};
|
||||||
val = AuAtomicSub(&this->state_, 1);
|
|
||||||
bElevation = this->bElevaterPending_;
|
{
|
||||||
}
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
bElevation = this->writersPending_ > 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((val == 0) && (bElevation))
|
if (bElevation)
|
||||||
{
|
{
|
||||||
this->GetConditionWriter().Signal();
|
this->GetConditionWriter().Signal();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (val == 0)
|
{
|
||||||
{
|
this->GetCondition().Broadcast();
|
||||||
this->GetCondition().Signal();
|
}
|
||||||
this->GetConditionWriter().Signal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool bIsWriteRecursionAllowed>
|
template<bool bIsWriteRecursionAllowed>
|
||||||
void RWLockImpl<bIsWriteRecursionAllowed>::UnlockWrite()
|
void RWLockImpl<bIsWriteRecursionAllowed>::UnlockWrite()
|
||||||
{
|
{
|
||||||
|
bool bElevationPending {};
|
||||||
|
|
||||||
if constexpr (!bIsWriteRecursionAllowed)
|
if constexpr (!bIsWriteRecursionAllowed)
|
||||||
{
|
{
|
||||||
|
this->reentrantWriteLockHandle_ = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
this->reentrantWriteLockHandle_ = 0;
|
|
||||||
this->state_ = 0;
|
this->state_ = 0;
|
||||||
|
bElevationPending = this->writersPending_ > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GetConditionWriter().Broadcast();
|
if (bElevationPending)
|
||||||
this->GetCondition().Broadcast();
|
{
|
||||||
|
this->GetConditionWriter().Signal();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->GetCondition().Broadcast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AuInt32 val {};
|
AuInt32 val {};
|
||||||
|
|
||||||
{
|
this->reentrantWriteLockHandle_ = 0;
|
||||||
AU_LOCK_GUARD(this->mutex_);
|
val = AuAtomicAdd(&this->state_, 1);
|
||||||
val = AuAtomicAdd(&this->state_, 1);
|
|
||||||
this->reentrantWriteLockHandle_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
{
|
{
|
||||||
this->GetConditionWriter().Broadcast();
|
{
|
||||||
this->GetCondition().Broadcast();
|
AU_LOCK_GUARD(this->mutex_);
|
||||||
|
bElevationPending = this->writersPending_ > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bElevationPending)
|
||||||
|
{
|
||||||
|
this->GetConditionWriter().Signal();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->GetCondition().Broadcast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,7 +394,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
while (this->state_ != 1)
|
while (this->state_ != 1)
|
||||||
{
|
{
|
||||||
this->bElevaterPending_ = true;
|
AuAtomicAdd(&this->writersPending_, 1);
|
||||||
|
|
||||||
if (!this->GetConditionWriter().WaitForSignal(timeout))
|
if (!this->GetConditionWriter().WaitForSignal(timeout))
|
||||||
{
|
{
|
||||||
@ -383,7 +402,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->bElevaterPending_ = false;
|
AuAtomicSub(&this->writersPending_, 1);
|
||||||
this->reentrantWriteLockHandle_ = GetThreadCookie();
|
this->reentrantWriteLockHandle_ = GetThreadCookie();
|
||||||
this->state_ = -1;
|
this->state_ = -1;
|
||||||
return true;
|
return true;
|
||||||
|
@ -93,10 +93,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
#endif
|
#endif
|
||||||
ThreadCookie_t reentrantWriteLockHandle_ {};
|
ThreadCookie_t reentrantWriteLockHandle_ {};
|
||||||
volatile AuInt32 state_ {};
|
volatile AuInt32 state_ {};
|
||||||
AuInt32 writersPending_ : 31 {};
|
AuInt32 writersPending_ {};
|
||||||
AuInt32 bElevaterPending_ : 1 {};
|
|
||||||
//bool bElevaterPending_{};
|
|
||||||
//bool reentrantWriteLock_ {true};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cstatic const AuUInt8 kOffsetOfRead = AuOffsetOf(&RWLockImpl::read_);
|
cstatic const AuUInt8 kOffsetOfRead = AuOffsetOf(&RWLockImpl::read_);
|
||||||
|
Loading…
Reference in New Issue
Block a user