[*] Fixed regression in RWLock size without sacrificing on features

(TODO: I would like to WoA optimize it for modern oses at some point)
This commit is contained in:
Reece Wilson 2023-06-15 23:59:47 +01:00
parent e11028bb03
commit 25b933aafa
5 changed files with 76 additions and 18 deletions

View File

@ -20,7 +20,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSizeNTSemaphore = 64; static const auto kPrimitiveSizeNTSemaphore = 64;
static const auto kPrimitiveSizeNTCS = 32; static const auto kPrimitiveSizeNTCS = 32;
static const auto kPrimitiveSizeNTEvent = 64; static const auto kPrimitiveSizeNTEvent = 64;
static const auto kPrimitiveSizeNTRWLock = 136; //104; (made it a bit bigger to optimize wakeup order. this is still ~100 bytes shy of std::shared_timed_mutex) static const auto kPrimitiveSizeNTRWLock = 104;
static const auto kPrimitiveSizeNTCond = 32; static const auto kPrimitiveSizeNTCond = 32;
static const auto kPrimitiveSizeNTCondMutex = 16; static const auto kPrimitiveSizeNTCondMutex = 16;

View File

@ -50,10 +50,15 @@ namespace Aurora::Threading::Primitives
} }
bool ConditionVariableImpl::WaitForSignalNS(AuUInt64 qwTimeout) bool ConditionVariableImpl::WaitForSignalNS(AuUInt64 qwTimeout)
{
return this->WaitForSignalNsEx(this->mutex_, qwTimeout);
}
bool ConditionVariableImpl::WaitForSignalNsEx(const AuSPtr<IConditionMutex> &pMutex, AuUInt64 qwTimeout)
{ {
#if !defined(AURORA_FORCE_SRW_LOCKS) #if !defined(AURORA_FORCE_SRW_LOCKS)
bool bRet { true }; bool bRet { true };
auto pThatMutex = reinterpret_cast<NT4Mutex *>(&this->mutex_->lock_); auto pThatMutex = reinterpret_cast<NT4Mutex *>(&(AuStaticCast<Win32ConditionMutex>(pMutex)->lock_));
if (qwTimeout) if (qwTimeout)
{ {

View File

@ -18,7 +18,8 @@ namespace Aurora::Threading::Primitives
auline AuSPtr<IConditionMutex> GetMutex() override; auline AuSPtr<IConditionMutex> GetMutex() override;
auline bool WaitForSignal(AuUInt32 timeout) override; auline bool WaitForSignal(AuUInt32 timeout) override;
bool WaitForSignalNS(AuUInt64 qwTimeout); auline bool WaitForSignalNsEx(const AuSPtr<IConditionMutex> &pMutex, AuUInt64 timeout);
auline bool WaitForSignalNS(AuUInt64 qwTimeout);
auline void Signal() override; auline void Signal() override;
auline void Broadcast() override; auline void Broadcast() override;
@ -35,6 +36,19 @@ namespace Aurora::Threading::Primitives
std::shared_ptr<Win32ConditionMutex> mutex_; std::shared_ptr<Win32ConditionMutex> mutex_;
}; };
struct CondVarDummy : IConditionVariable
{
private:
#if defined(AURORA_FORCE_SRW_LOCKS)
CONDITION_VARIABLE winCond_;
#else
AuUInt32 wlist {};
AuUInt32 signalCount {};
#endif
};
static const auto kSizeOfDummyCondVar = sizeof(CondVarDummy);
static const auto kBoolRequiredLateSet = true; static const auto kBoolRequiredLateSet = true;
// Future (Reece): I got future plans // Future (Reece): I got future plans

View File

@ -66,9 +66,11 @@ namespace Aurora::Threading::Primitives
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
RWLockImpl<bIsWriteRecursionAllowed>::RWLockImpl() : RWLockImpl<bIsWriteRecursionAllowed>::RWLockImpl() :
read_(*this), read_(*this),
write_(*this), write_(*this)
condition_(AuUnsafeRaiiToShared(&this->mutex_)), #if 0
, condition_(AuUnsafeRaiiToShared(&this->mutex_)),
conditionWriter_(AuUnsafeRaiiToShared(&this->mutex_)) conditionWriter_(AuUnsafeRaiiToShared(&this->mutex_))
#endif
{ {
} }
@ -83,6 +85,27 @@ namespace Aurora::Threading::Primitives
{ {
return true; return true;
} }
template<bool bIsWriteRecursionAllowed>
ConditionVariableImpl &RWLockImpl<bIsWriteRecursionAllowed>::GetCondition()
{
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
return *(ConditionVariableImpl *)this->conditionVariable_;
#else
return this->condition_;
#endif
}
template<bool bIsWriteRecursionAllowed>
ConditionVariableImpl &RWLockImpl<bIsWriteRecursionAllowed>::GetConditionWriter()
{
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
return *(ConditionVariableImpl *)this->conditionVariableWriter_;
#else
return this->conditionWriter_;
#endif
}
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
bool RWLockImpl<bIsWriteRecursionAllowed>::LockReadNS(AuUInt64 uTimeout) bool RWLockImpl<bIsWriteRecursionAllowed>::LockReadNS(AuUInt64 uTimeout)
@ -119,14 +142,18 @@ namespace Aurora::Threading::Primitives
} }
} }
if (!this->condition_.WaitForSignalNS(uSecondTimeout)) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
if (!this->GetCondition().WaitForSignalNS(uSecondTimeout))
#else
if (!this->GetCondition().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), uSecondTimeout))
#endif
{ {
return false; return false;
} }
if (this->writersPending_) if (this->writersPending_)
{ {
this->conditionWriter_.Broadcast(); this->GetConditionWriter().Broadcast();
continue; continue;
} }
} }
@ -191,7 +218,11 @@ namespace Aurora::Threading::Primitives
} }
} }
if (!this->conditionWriter_.WaitForSignalNS(uSecondTimeout)) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
if (!this->GetConditionWriter().WaitForSignalNS(uSecondTimeout))
#else
if (!this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), uSecondTimeout))
#endif
{ {
this->writersPending_--; this->writersPending_--;
return false; return false;
@ -206,7 +237,7 @@ namespace Aurora::Threading::Primitives
} }
else else
{ {
this->conditionWriter_.Broadcast(); this->GetConditionWriter().Broadcast();
} }
} }
@ -288,13 +319,13 @@ namespace Aurora::Threading::Primitives
if ((val == 1) && (this->bElevaterPending_)) if ((val == 1) && (this->bElevaterPending_))
{ {
this->conditionWriter_.Signal(); this->GetConditionWriter().Signal();
} }
if (val == 0) if (val == 0)
{ {
this->condition_.Signal(); this->GetCondition().Signal();
this->conditionWriter_.Signal(); this->GetConditionWriter().Signal();
} }
} }
@ -307,16 +338,16 @@ namespace Aurora::Threading::Primitives
{ {
this->reentrantWriteLockHandle_ = 0; this->reentrantWriteLockHandle_ = 0;
this->state_ = 0; this->state_ = 0;
this->conditionWriter_.Broadcast(); this->GetConditionWriter().Broadcast();
this->condition_.Broadcast(); this->GetCondition().Broadcast();
} }
else else
{ {
if (AuAtomicAdd(&this->state_, 1) == 0) if (AuAtomicAdd(&this->state_, 1) == 0)
{ {
this->reentrantWriteLockHandle_ = 0; this->reentrantWriteLockHandle_ = 0;
this->conditionWriter_.Broadcast(); this->GetConditionWriter().Broadcast();
this->condition_.Broadcast(); this->GetCondition().Broadcast();
} }
} }
} }
@ -330,7 +361,7 @@ namespace Aurora::Threading::Primitives
{ {
this->bElevaterPending_ = true; this->bElevaterPending_ = true;
if (!this->conditionWriter_.WaitForSignal(timeout)) if (!this->GetConditionWriter().WaitForSignal(timeout))
{ {
return false; return false;
} }
@ -353,7 +384,7 @@ namespace Aurora::Threading::Primitives
} }
this->state_ = 1; this->state_ = 1;
this->condition_.Broadcast(); this->GetCondition().Broadcast();
return true; return true;
} }

View File

@ -71,6 +71,9 @@ namespace Aurora::Threading::Primitives
IWaitable *AsWritable() override; IWaitable *AsWritable() override;
bool Init(); bool Init();
auline ConditionVariableImpl &GetCondition();
auline ConditionVariableImpl &GetConditionWriter();
private: private:
@ -81,8 +84,13 @@ namespace Aurora::Threading::Primitives
RWLockAccessView<false, RWLockImpl> write_; RWLockAccessView<false, RWLockImpl> write_;
ConditionMutexImpl mutex_; ConditionMutexImpl mutex_;
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
ConditionVariableImpl condition_; ConditionVariableImpl condition_;
ConditionVariableImpl conditionWriter_; ConditionVariableImpl conditionWriter_;
#else
char conditionVariable_[kSizeOfDummyCondVar] {};
char conditionVariableWriter_[kSizeOfDummyCondVar] {};
#endif
volatile AuInt32 state_ {}; volatile AuInt32 state_ {};
AuInt32 writersPending_ : 31 {}; AuInt32 writersPending_ : 31 {};
AuInt32 bElevaterPending_ : 1 {}; AuInt32 bElevaterPending_ : 1 {};