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