[*] 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 kPrimitiveSizeNTCS = 32;
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 kPrimitiveSizeNTCondMutex = 16;

View File

@ -50,10 +50,15 @@ namespace Aurora::Threading::Primitives
}
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)
bool bRet { true };
auto pThatMutex = reinterpret_cast<NT4Mutex *>(&this->mutex_->lock_);
auto pThatMutex = reinterpret_cast<NT4Mutex *>(&(AuStaticCast<Win32ConditionMutex>(pMutex)->lock_));
if (qwTimeout)
{

View File

@ -18,7 +18,8 @@ namespace Aurora::Threading::Primitives
auline AuSPtr<IConditionMutex> GetMutex() 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 Broadcast() override;
@ -35,6 +36,19 @@ namespace Aurora::Threading::Primitives
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;
// Future (Reece): I got future plans

View File

@ -66,9 +66,11 @@ namespace Aurora::Threading::Primitives
template<bool bIsWriteRecursionAllowed>
RWLockImpl<bIsWriteRecursionAllowed>::RWLockImpl() :
read_(*this),
write_(*this),
condition_(AuUnsafeRaiiToShared(&this->mutex_)),
write_(*this)
#if 0
, condition_(AuUnsafeRaiiToShared(&this->mutex_)),
conditionWriter_(AuUnsafeRaiiToShared(&this->mutex_))
#endif
{
}
@ -83,6 +85,27 @@ namespace Aurora::Threading::Primitives
{
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>
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;
}
if (this->writersPending_)
{
this->conditionWriter_.Broadcast();
this->GetConditionWriter().Broadcast();
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_--;
return false;
@ -206,7 +237,7 @@ namespace Aurora::Threading::Primitives
}
else
{
this->conditionWriter_.Broadcast();
this->GetConditionWriter().Broadcast();
}
}
@ -288,13 +319,13 @@ namespace Aurora::Threading::Primitives
if ((val == 1) && (this->bElevaterPending_))
{
this->conditionWriter_.Signal();
this->GetConditionWriter().Signal();
}
if (val == 0)
{
this->condition_.Signal();
this->conditionWriter_.Signal();
this->GetCondition().Signal();
this->GetConditionWriter().Signal();
}
}
@ -307,16 +338,16 @@ namespace Aurora::Threading::Primitives
{
this->reentrantWriteLockHandle_ = 0;
this->state_ = 0;
this->conditionWriter_.Broadcast();
this->condition_.Broadcast();
this->GetConditionWriter().Broadcast();
this->GetCondition().Broadcast();
}
else
{
if (AuAtomicAdd(&this->state_, 1) == 0)
{
this->reentrantWriteLockHandle_ = 0;
this->conditionWriter_.Broadcast();
this->condition_.Broadcast();
this->GetConditionWriter().Broadcast();
this->GetCondition().Broadcast();
}
}
}
@ -330,7 +361,7 @@ namespace Aurora::Threading::Primitives
{
this->bElevaterPending_ = true;
if (!this->conditionWriter_.WaitForSignal(timeout))
if (!this->GetConditionWriter().WaitForSignal(timeout))
{
return false;
}
@ -353,7 +384,7 @@ namespace Aurora::Threading::Primitives
}
this->state_ = 1;
this->condition_.Broadcast();
this->GetCondition().Broadcast();
return true;
}

View File

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