[*] More compact Win32 primitives!

This commit is contained in:
Reece Wilson 2023-08-21 17:34:24 +01:00
parent 869512e651
commit 5cc811be19
13 changed files with 121 additions and 101 deletions

View File

@ -20,18 +20,18 @@ namespace Aurora::Threading::Primitives
#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86) #if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)
static const auto kPrimitiveSize64NTMutex = 16; static const auto kPrimitiveSize64NTMutex = 16;
static const auto kPrimitiveSize64NTSemaphore = 64; static const auto kPrimitiveSize64NTSemaphore = 24;
static const auto kPrimitiveSize64NTCS = 32; static const auto kPrimitiveSize64NTCS = 32;
static const auto kPrimitiveSize64NTEvent = 64; static const auto kPrimitiveSize64NTEvent = 24;
static const auto kPrimitiveSize64NTRWLock = 88; static const auto kPrimitiveSize64NTRWLock = 56;
static const auto kPrimitiveSize64NTCond = 32; static const auto kPrimitiveSize64NTCond = 32;
static const auto kPrimitiveSize64NTCondMutex = 16; static const auto kPrimitiveSize64NTCondMutex = 16;
static const auto kPrimitiveSize32NTMutex = 8; static const auto kPrimitiveSize32NTMutex = 8;
static const auto kPrimitiveSize32NTSemaphore = 36; static const auto kPrimitiveSize32NTSemaphore = 20;
static const auto kPrimitiveSize32NTCS = 20; static const auto kPrimitiveSize32NTCS = 20;
static const auto kPrimitiveSize32NTEvent = 36; static const auto kPrimitiveSize32NTEvent = 20;
static const auto kPrimitiveSize32NTRWLock = 56; static const auto kPrimitiveSize32NTRWLock = 44;
static const auto kPrimitiveSize32NTCond = 20; static const auto kPrimitiveSize32NTCond = 20;
static const auto kPrimitiveSize32NTCondMutex = 8; static const auto kPrimitiveSize32NTCondMutex = 8;

View File

@ -96,8 +96,7 @@ namespace Aurora::Threading
AuResetMember(this->pAddress); AuResetMember(this->pAddress);
} }
WaitEntry::WaitEntry() : WaitEntry::WaitEntry()
variable(AuUnsafeRaiiToShared(&this->mutex))
{ {
} }
@ -134,7 +133,7 @@ namespace Aurora::Threading
Win32DropSchedulerResolution(); Win32DropSchedulerResolution();
#endif #endif
this->variable.WaitForSignalNS(uTimeRemNS); this->variable.WaitForSignalNsEx(&this->mutex, uTimeRemNS);
uNow = AuTime::SteadyClockNS(); uNow = AuTime::SteadyClockNS();
} }
@ -145,7 +144,7 @@ namespace Aurora::Threading
{ {
while (WaitBuffer::From(this->pAddress, this->uSize).Compare(state)) while (WaitBuffer::From(this->pAddress, this->uSize).Compare(state))
{ {
this->variable.WaitForSignal(0); this->variable.WaitForSignalNsEx(&this->mutex, 0);
} }
return true; return true;

View File

@ -45,8 +45,8 @@ namespace Aurora::Threading
// synch // synch
AuUInt32 uAtomic {}; // fastpath AuUInt32 uAtomic {}; // fastpath
Primitives::ConditionMutexImpl mutex; // mutex ctor must come before var Primitives::ConditionMutexInternal mutex; // mutex ctor must come before var
Primitives::ConditionVariableImpl variable; // ...and something all 2007+ micro and monolithic kernels should have to yield for an event Primitives::ConditionVariableInternal variable; // ...and something all 2007+ micro and monolithic kernels should have to yield for an event
// state // state
const void *pAddress {}; const void *pAddress {};

View File

@ -181,15 +181,15 @@ namespace Aurora::Threading::Primitives
AUKN_SYM IConditionMutex *ConditionMutexNew() AUKN_SYM IConditionMutex *ConditionMutexNew()
{ {
return _new Win32ConditionMutex(); return _new ConditionMutexImpl();
} }
AUKN_SYM void ConditionMutexRelease(IConditionMutex *pMutex) AUKN_SYM void ConditionMutexRelease(IConditionMutex *pMutex)
{ {
AuSafeDelete<Win32ConditionMutex *>(pMutex); AuSafeDelete<ConditionMutexImpl *>(pMutex);
} }
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, ConditionMutex, Win32ConditionMutex) AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, ConditionMutex, ConditionMutexImpl)
} }
#endif #endif

View File

@ -30,15 +30,15 @@ namespace Aurora::Threading::Primitives
volatile AuUInt32 uWaitCount {}; // yields while bits are high, dec to release one from the semaphore yield volatile AuUInt32 uWaitCount {}; // yields while bits are high, dec to release one from the semaphore yield
}; };
struct Win32ConditionMutex final : IConditionMutexEx struct Win32ConditionMutex final
{ {
Win32ConditionMutex(); Win32ConditionMutex();
~Win32ConditionMutex(); ~Win32ConditionMutex();
auline bool TryLock() override; bool TryLock();
auline void Lock() override; void Lock();
auline void Unlock() override; void Unlock();
AuUInt GetOSHandle() override; AuUInt GetOSHandle();
auline bool TryLockNoSpin(); auline bool TryLockNoSpin();
auline bool TryLockHeavy(); auline bool TryLockHeavy();
@ -49,7 +49,32 @@ namespace Aurora::Threading::Primitives
SRWLOCK lock_; SRWLOCK lock_;
#endif #endif
}; };
using ConditionMutexImpl = Win32ConditionMutex; using ConditionMutexInternal = Win32ConditionMutex;
struct ConditionMutexImpl final : IConditionMutexEx
{
auline bool TryLock()
{
return mutex.TryLock();
}
auline void Lock()
{
mutex.Unlock();
}
auline void Unlock()
{
mutex.Unlock();
}
inline AuUInt GetOSHandle()
{
return mutex.GetOSHandle();
}
ConditionMutexInternal mutex;
};
} }
#endif #endif

View File

@ -19,42 +19,14 @@
namespace Aurora::Threading::Primitives namespace Aurora::Threading::Primitives
{ {
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &pMutex) : ConditionVariableNT::ConditionVariableNT()
mutex_(AuStaticCast<Win32ConditionMutex>(pMutex))
{ {
#if defined(AURORA_FORCE_SRW_LOCKS) #if defined(AURORA_FORCE_SRW_LOCKS)
::InitializeConditionVariable(&this->winCond_); ::InitializeConditionVariable(&this->winCond_);
#endif #endif
} }
AuSPtr<IConditionMutex> ConditionVariableImpl::GetMutex() bool ConditionVariableNT::WaitForSignalNsEx(Win32ConditionMutex *pMutex, AuUInt64 qwTimeout)
{
return this->mutex_;
}
bool ConditionVariableImpl::WaitForSignal(AuUInt32 uTimeout)
{
#if !defined(AURORA_FORCE_SRW_LOCKS)
return WaitForSignalNS(AuMSToNS<AuUInt64>(uTimeout));
#else
auto bOK = ::SleepConditionVariableSRW(&this->winCond_, reinterpret_cast<PSRWLOCK>(this->mutex_->GetOSHandle()), uTimeout ? uTimeout : INFINITE, 0);
if (!bOK)
{
SysAssert(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariable failure");
return false;
}
return true;
#endif
}
bool ConditionVariableImpl::WaitForSignalNS(AuUInt64 qwTimeout)
{
return this->WaitForSignalNsEx(this->mutex_, qwTimeout);
}
bool ConditionVariableImpl::WaitForSignalNsEx(const std::shared_ptr<Win32ConditionMutex> &pMutex, AuUInt64 qwTimeout)
{ {
#if !defined(AURORA_FORCE_SRW_LOCKS) #if !defined(AURORA_FORCE_SRW_LOCKS)
bool bRet { true }; bool bRet { true };
@ -309,7 +281,7 @@ namespace Aurora::Threading::Primitives
#endif #endif
} }
bool ConditionVariableImpl::CheckOut() bool ConditionVariableNT::CheckOut()
{ {
#if defined(AURORA_FORCE_SRW_LOCKS) #if defined(AURORA_FORCE_SRW_LOCKS)
return false; return false;
@ -343,7 +315,7 @@ namespace Aurora::Threading::Primitives
#endif #endif
} }
void ConditionVariableImpl::Signal() void ConditionVariableNT::Signal()
{ {
#if !defined(AURORA_FORCE_SRW_LOCKS) #if !defined(AURORA_FORCE_SRW_LOCKS)
auto original = this->wlist; auto original = this->wlist;
@ -379,7 +351,7 @@ namespace Aurora::Threading::Primitives
#endif #endif
} }
void ConditionVariableImpl::Broadcast() void ConditionVariableNT::Broadcast()
{ {
#if !defined(AURORA_FORCE_SRW_LOCKS) #if !defined(AURORA_FORCE_SRW_LOCKS)

View File

@ -12,16 +12,13 @@
namespace Aurora::Threading::Primitives namespace Aurora::Threading::Primitives
{ {
struct ConditionVariableImpl final : IConditionVariable struct ConditionVariableNT final
{ {
ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex); ConditionVariableNT();
auline AuSPtr<IConditionMutex> GetMutex() override; bool WaitForSignalNsEx(Win32ConditionMutex *pMutex, AuUInt64 timeout);
auline bool WaitForSignal(AuUInt32 timeout) override; void Signal();
bool WaitForSignalNsEx(const std::shared_ptr<Win32ConditionMutex> &pMutex, AuUInt64 timeout); void Broadcast();
bool WaitForSignalNS(AuUInt64 qwTimeout) override;
auline void Signal() override;
auline void Broadcast() override;
auline bool CheckOut(); auline bool CheckOut();
@ -32,22 +29,52 @@ namespace Aurora::Threading::Primitives
AuUInt32 wlist {}; AuUInt32 wlist {};
AuUInt32 signalCount {}; AuUInt32 signalCount {};
#endif #endif
std::shared_ptr<Win32ConditionMutex> mutex_;
}; };
struct CondVarDummy : IConditionVariable using ConditionVariableInternal = ConditionVariableNT;
struct ConditionVariableImpl final : IConditionVariable
{ {
private: inline ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex) :
#if defined(AURORA_FORCE_SRW_LOCKS) mutex(mutex)
CONDITION_VARIABLE winCond_; {
#else }
AuUInt32 wlist {};
AuUInt32 signalCount {}; auline AuSPtr<IConditionMutex> GetMutex() override
#endif {
return mutex;
}
auline bool WaitForSignal(AuUInt32 timeout) override
{
return cond.WaitForSignalNsEx(&std::static_pointer_cast<ConditionMutexImpl>(this->mutex)->mutex, AuMSToNS<AuUInt64>(timeout));
}
auline bool WaitForSignalNS(AuUInt64 qwTimeout) override
{
return cond.WaitForSignalNsEx(&std::static_pointer_cast<ConditionMutexImpl>(this->mutex)->mutex, qwTimeout);
}
inline bool WaitForSignalNsEx(const std::shared_ptr<Win32ConditionMutex> &pMutex, AuUInt64 timeout)
{
return cond.WaitForSignalNsEx(pMutex.get(), timeout);
}
auline void Signal() override
{
cond.Signal();
}
auline void Broadcast() override
{
cond.Broadcast();
}
ConditionVariableNT cond;
std::shared_ptr<IConditionMutex> mutex;
}; };
static const auto kSizeOfDummyCondVar = sizeof(CondVarDummy); static const auto kSizeOfDummyCondVar = sizeof(ConditionVariableInternal);
static const auto kBoolRequiredLateSet = true; static const auto kBoolRequiredLateSet = true;

View File

@ -14,8 +14,7 @@ namespace Aurora::Threading::Primitives
EventImpl::EventImpl(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers) : EventImpl::EventImpl(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers) :
bTriggered_(bTriggered), bTriggered_(bTriggered),
bAtomicRelease_(bAtomicRelease), bAtomicRelease_(bAtomicRelease),
bPermitMultipleTriggers_(bPermitMultipleTriggers), bPermitMultipleTriggers_(bPermitMultipleTriggers)
condition_(AuUnsafeRaiiToShared(&this->mutex_))
{} {}
EventImpl::~EventImpl() {} EventImpl::~EventImpl() {}
@ -58,7 +57,7 @@ namespace Aurora::Threading::Primitives
uTimeoutNS = uEndTime - uStartTime; uTimeoutNS = uEndTime - uStartTime;
} }
if (!this->condition_.WaitForSignalNS(uTimeoutNS)) if (!this->condition_.WaitForSignalNsEx(&this->mutex_, uTimeoutNS))
{ {
continue; continue;
} }

View File

@ -31,8 +31,8 @@ namespace Aurora::Threading::Primitives
private: private:
bool AtomicIsEventSetLogic(); bool AtomicIsEventSetLogic();
ConditionMutexImpl mutex_; // must come first ConditionMutexInternal mutex_; // must come first
ConditionVariableImpl condition_; ConditionVariableInternal condition_;
#if 0 #if 0
const bool bAtomicRelease_ {}; const bool bAtomicRelease_ {};

View File

@ -119,20 +119,20 @@ namespace Aurora::Threading::Primitives
} }
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
ConditionVariableImpl &RWLockImpl<bIsWriteRecursionAllowed>::GetCondition() ConditionVariableInternal &RWLockImpl<bIsWriteRecursionAllowed>::GetCondition()
{ {
#if !defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if !defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
return *(ConditionVariableImpl *)this->conditionVariable_; return *(ConditionVariableInternal *)this->conditionVariable_;
#else #else
return this->condition_; return this->condition_;
#endif #endif
} }
template<bool bIsWriteRecursionAllowed> template<bool bIsWriteRecursionAllowed>
ConditionVariableImpl &RWLockImpl<bIsWriteRecursionAllowed>::GetConditionWriter() ConditionVariableInternal &RWLockImpl<bIsWriteRecursionAllowed>::GetConditionWriter()
{ {
#if !defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if !defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
return *(ConditionVariableImpl *)this->conditionVariableWriter_; return *(ConditionVariableInternal *)this->conditionVariableWriter_;
#else #else
return this->conditionWriter_; return this->conditionWriter_;
#endif #endif
@ -173,7 +173,7 @@ namespace Aurora::Threading::Primitives
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
if (!this->GetCondition().WaitForSignalNS(iSecondTimeout)) if (!this->GetCondition().WaitForSignalNS(iSecondTimeout))
#else #else
if (!this->GetCondition().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout)) if (!this->GetCondition().WaitForSignalNsEx(&this->mutex_, iSecondTimeout))
#endif #endif
{ {
return false; return false;
@ -229,7 +229,7 @@ namespace Aurora::Threading::Primitives
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
if (!this->GetCondition().WaitForSignalNS(iSecondTimeout)) if (!this->GetCondition().WaitForSignalNS(iSecondTimeout))
#else #else
if (!this->GetCondition().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout)) if (!this->GetCondition().WaitForSignalNsEx(&this->mutex_, iSecondTimeout))
#endif #endif
{ {
return false; return false;
@ -297,7 +297,7 @@ namespace Aurora::Threading::Primitives
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
bool bStatus = this->GetConditionWriter().WaitForSignalNS(iSecondTimeout); bool bStatus = this->GetConditionWriter().WaitForSignalNS(iSecondTimeout);
#else #else
bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout); bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, iSecondTimeout);
#endif #endif
if constexpr (bIsWriteRecursionAllowed) if constexpr (bIsWriteRecursionAllowed)
@ -382,7 +382,7 @@ namespace Aurora::Threading::Primitives
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
bool bStatus = this->GetConditionWriter().WaitForSignalNS(uSecondTimeout); bool bStatus = this->GetConditionWriter().WaitForSignalNS(uSecondTimeout);
#else #else
bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), uSecondTimeout); bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, uSecondTimeout);
#endif #endif
if constexpr (bIsWriteRecursionAllowed) if constexpr (bIsWriteRecursionAllowed)
@ -624,7 +624,7 @@ namespace Aurora::Threading::Primitives
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
if (!this->GetConditionWriter().WaitForSignalNS(iSecondTimeout)) if (!this->GetConditionWriter().WaitForSignalNS(iSecondTimeout))
#else #else
if (!this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout)) if (!this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, iSecondTimeout))
#endif #endif
{ {
return false; return false;

View File

@ -80,18 +80,18 @@ namespace Aurora::Threading::Primitives
IWaitable *AsReadable() override; IWaitable *AsReadable() override;
IWaitable *AsWritable() override; IWaitable *AsWritable() override;
auline ConditionVariableImpl &GetCondition(); auline ConditionVariableInternal &GetCondition();
auline ConditionVariableImpl &GetConditionWriter(); auline ConditionVariableInternal &GetConditionWriter();
private: private:
RWLockAccessView<true, RWLockImpl> read_; RWLockAccessView<true, RWLockImpl> read_;
RWLockAccessView<false, RWLockImpl> write_; RWLockAccessView<false, RWLockImpl> write_;
ConditionMutexImpl mutex_; ConditionMutexInternal mutex_;
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR) #if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
ConditionVariableImpl condition_; ConditionVariableInternal condition_;
ConditionVariableImpl conditionWriter_; ConditionVariableInternal conditionWriter_;
#else #else
char conditionVariable_[kSizeOfDummyCondVar] {}; char conditionVariable_[kSizeOfDummyCondVar] {};
char conditionVariableWriter_[kSizeOfDummyCondVar] {}; char conditionVariableWriter_[kSizeOfDummyCondVar] {};

View File

@ -15,15 +15,13 @@
namespace Aurora::Threading::Primitives namespace Aurora::Threading::Primitives
{ {
SemaphoreImpl::SemaphoreImpl(AuUInt16 uIntialValue) : SemaphoreImpl::SemaphoreImpl(AuUInt16 uIntialValue)
var(AuUnsafeRaiiToShared(&this->mutex))
{ {
this->dwState_ = uIntialValue; this->dwState_ = uIntialValue;
} }
SemaphoreImpl::~SemaphoreImpl() SemaphoreImpl::~SemaphoreImpl()
{ {
} }
bool SemaphoreImpl::HasOSHandle(AuMach &mach) bool SemaphoreImpl::HasOSHandle(AuMach &mach)
@ -110,11 +108,11 @@ namespace Aurora::Threading::Primitives
return false; return false;
} }
var.WaitForSignalNS(uEnd - uStart); var.WaitForSignalNsEx(&this->mutex, uEnd - uStart);
} }
else else
{ {
var.WaitForSignalNS(0); var.WaitForSignalNsEx(&this->mutex, 0);
} }
} }

View File

@ -31,7 +31,7 @@ namespace Aurora::Threading::Primitives
private: private:
AuUInt32 dwState_ {}; AuUInt32 dwState_ {};
ConditionMutexImpl mutex; ConditionMutexInternal mutex;
ConditionVariableImpl var; ConditionVariableInternal var;
}; };
} }