[*] 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:
parent
e11028bb03
commit
25b933aafa
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {};
|
||||
|
Loading…
Reference in New Issue
Block a user