[*] More compact Win32 primitives!
This commit is contained in:
parent
869512e651
commit
5cc811be19
@ -20,18 +20,18 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)
|
||||
|
||||
static const auto kPrimitiveSize64NTMutex = 16;
|
||||
static const auto kPrimitiveSize64NTSemaphore = 64;
|
||||
static const auto kPrimitiveSize64NTSemaphore = 24;
|
||||
static const auto kPrimitiveSize64NTCS = 32;
|
||||
static const auto kPrimitiveSize64NTEvent = 64;
|
||||
static const auto kPrimitiveSize64NTRWLock = 88;
|
||||
static const auto kPrimitiveSize64NTEvent = 24;
|
||||
static const auto kPrimitiveSize64NTRWLock = 56;
|
||||
static const auto kPrimitiveSize64NTCond = 32;
|
||||
static const auto kPrimitiveSize64NTCondMutex = 16;
|
||||
|
||||
static const auto kPrimitiveSize32NTMutex = 8;
|
||||
static const auto kPrimitiveSize32NTSemaphore = 36;
|
||||
static const auto kPrimitiveSize32NTSemaphore = 20;
|
||||
static const auto kPrimitiveSize32NTCS = 20;
|
||||
static const auto kPrimitiveSize32NTEvent = 36;
|
||||
static const auto kPrimitiveSize32NTRWLock = 56;
|
||||
static const auto kPrimitiveSize32NTEvent = 20;
|
||||
static const auto kPrimitiveSize32NTRWLock = 44;
|
||||
static const auto kPrimitiveSize32NTCond = 20;
|
||||
static const auto kPrimitiveSize32NTCondMutex = 8;
|
||||
|
||||
|
@ -96,8 +96,7 @@ namespace Aurora::Threading
|
||||
AuResetMember(this->pAddress);
|
||||
}
|
||||
|
||||
WaitEntry::WaitEntry() :
|
||||
variable(AuUnsafeRaiiToShared(&this->mutex))
|
||||
WaitEntry::WaitEntry()
|
||||
{
|
||||
|
||||
}
|
||||
@ -134,7 +133,7 @@ namespace Aurora::Threading
|
||||
Win32DropSchedulerResolution();
|
||||
#endif
|
||||
|
||||
this->variable.WaitForSignalNS(uTimeRemNS);
|
||||
this->variable.WaitForSignalNsEx(&this->mutex, uTimeRemNS);
|
||||
|
||||
uNow = AuTime::SteadyClockNS();
|
||||
}
|
||||
@ -145,7 +144,7 @@ namespace Aurora::Threading
|
||||
{
|
||||
while (WaitBuffer::From(this->pAddress, this->uSize).Compare(state))
|
||||
{
|
||||
this->variable.WaitForSignal(0);
|
||||
this->variable.WaitForSignalNsEx(&this->mutex, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -45,8 +45,8 @@ namespace Aurora::Threading
|
||||
|
||||
// synch
|
||||
AuUInt32 uAtomic {}; // fastpath
|
||||
Primitives::ConditionMutexImpl 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::ConditionMutexInternal mutex; // mutex ctor must come before var
|
||||
Primitives::ConditionVariableInternal variable; // ...and something all 2007+ micro and monolithic kernels should have to yield for an event
|
||||
|
||||
// state
|
||||
const void *pAddress {};
|
||||
|
@ -181,15 +181,15 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
AUKN_SYM IConditionMutex *ConditionMutexNew()
|
||||
{
|
||||
return _new Win32ConditionMutex();
|
||||
return _new ConditionMutexImpl();
|
||||
}
|
||||
|
||||
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
|
@ -30,15 +30,15 @@ namespace Aurora::Threading::Primitives
|
||||
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();
|
||||
|
||||
auline bool TryLock() override;
|
||||
auline void Lock() override;
|
||||
auline void Unlock() override;
|
||||
AuUInt GetOSHandle() override;
|
||||
bool TryLock();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
AuUInt GetOSHandle();
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
auline bool TryLockHeavy();
|
||||
@ -50,6 +50,31 @@ namespace Aurora::Threading::Primitives
|
||||
#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
|
@ -19,42 +19,14 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
ConditionVariableImpl::ConditionVariableImpl(const AuSPtr<IConditionMutex> &pMutex) :
|
||||
mutex_(AuStaticCast<Win32ConditionMutex>(pMutex))
|
||||
ConditionVariableNT::ConditionVariableNT()
|
||||
{
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
::InitializeConditionVariable(&this->winCond_);
|
||||
#endif
|
||||
}
|
||||
|
||||
AuSPtr<IConditionMutex> ConditionVariableImpl::GetMutex()
|
||||
{
|
||||
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)
|
||||
bool ConditionVariableNT::WaitForSignalNsEx(Win32ConditionMutex *pMutex, AuUInt64 qwTimeout)
|
||||
{
|
||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||
bool bRet { true };
|
||||
@ -309,7 +281,7 @@ namespace Aurora::Threading::Primitives
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ConditionVariableImpl::CheckOut()
|
||||
bool ConditionVariableNT::CheckOut()
|
||||
{
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
return false;
|
||||
@ -343,7 +315,7 @@ namespace Aurora::Threading::Primitives
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConditionVariableImpl::Signal()
|
||||
void ConditionVariableNT::Signal()
|
||||
{
|
||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||
auto original = this->wlist;
|
||||
@ -379,7 +351,7 @@ namespace Aurora::Threading::Primitives
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConditionVariableImpl::Broadcast()
|
||||
void ConditionVariableNT::Broadcast()
|
||||
{
|
||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||
|
||||
|
@ -12,16 +12,13 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
struct ConditionVariableImpl final : IConditionVariable
|
||||
struct ConditionVariableNT final
|
||||
{
|
||||
ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex);
|
||||
ConditionVariableNT();
|
||||
|
||||
auline AuSPtr<IConditionMutex> GetMutex() override;
|
||||
auline bool WaitForSignal(AuUInt32 timeout) override;
|
||||
bool WaitForSignalNsEx(const std::shared_ptr<Win32ConditionMutex> &pMutex, AuUInt64 timeout);
|
||||
bool WaitForSignalNS(AuUInt64 qwTimeout) override;
|
||||
auline void Signal() override;
|
||||
auline void Broadcast() override;
|
||||
bool WaitForSignalNsEx(Win32ConditionMutex *pMutex, AuUInt64 timeout);
|
||||
void Signal();
|
||||
void Broadcast();
|
||||
|
||||
auline bool CheckOut();
|
||||
|
||||
@ -32,22 +29,52 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt32 wlist {};
|
||||
AuUInt32 signalCount {};
|
||||
#endif
|
||||
|
||||
std::shared_ptr<Win32ConditionMutex> mutex_;
|
||||
};
|
||||
|
||||
struct CondVarDummy : IConditionVariable
|
||||
using ConditionVariableInternal = ConditionVariableNT;
|
||||
|
||||
struct ConditionVariableImpl final : IConditionVariable
|
||||
{
|
||||
private:
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
CONDITION_VARIABLE winCond_;
|
||||
#else
|
||||
AuUInt32 wlist {};
|
||||
AuUInt32 signalCount {};
|
||||
#endif
|
||||
inline ConditionVariableImpl(const AuSPtr<IConditionMutex> &mutex) :
|
||||
mutex(mutex)
|
||||
{
|
||||
}
|
||||
|
||||
auline AuSPtr<IConditionMutex> GetMutex() override
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -14,8 +14,7 @@ namespace Aurora::Threading::Primitives
|
||||
EventImpl::EventImpl(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers) :
|
||||
bTriggered_(bTriggered),
|
||||
bAtomicRelease_(bAtomicRelease),
|
||||
bPermitMultipleTriggers_(bPermitMultipleTriggers),
|
||||
condition_(AuUnsafeRaiiToShared(&this->mutex_))
|
||||
bPermitMultipleTriggers_(bPermitMultipleTriggers)
|
||||
{}
|
||||
|
||||
EventImpl::~EventImpl() {}
|
||||
@ -58,7 +57,7 @@ namespace Aurora::Threading::Primitives
|
||||
uTimeoutNS = uEndTime - uStartTime;
|
||||
}
|
||||
|
||||
if (!this->condition_.WaitForSignalNS(uTimeoutNS))
|
||||
if (!this->condition_.WaitForSignalNsEx(&this->mutex_, uTimeoutNS))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ namespace Aurora::Threading::Primitives
|
||||
private:
|
||||
bool AtomicIsEventSetLogic();
|
||||
|
||||
ConditionMutexImpl mutex_; // must come first
|
||||
ConditionVariableImpl condition_;
|
||||
ConditionMutexInternal mutex_; // must come first
|
||||
ConditionVariableInternal condition_;
|
||||
|
||||
#if 0
|
||||
const bool bAtomicRelease_ {};
|
||||
|
@ -119,20 +119,20 @@ namespace Aurora::Threading::Primitives
|
||||
}
|
||||
|
||||
template<bool bIsWriteRecursionAllowed>
|
||||
ConditionVariableImpl &RWLockImpl<bIsWriteRecursionAllowed>::GetCondition()
|
||||
ConditionVariableInternal &RWLockImpl<bIsWriteRecursionAllowed>::GetCondition()
|
||||
{
|
||||
#if !defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
return *(ConditionVariableImpl *)this->conditionVariable_;
|
||||
return *(ConditionVariableInternal *)this->conditionVariable_;
|
||||
#else
|
||||
return this->condition_;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<bool bIsWriteRecursionAllowed>
|
||||
ConditionVariableImpl &RWLockImpl<bIsWriteRecursionAllowed>::GetConditionWriter()
|
||||
ConditionVariableInternal &RWLockImpl<bIsWriteRecursionAllowed>::GetConditionWriter()
|
||||
{
|
||||
#if !defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
return *(ConditionVariableImpl *)this->conditionVariableWriter_;
|
||||
return *(ConditionVariableInternal *)this->conditionVariableWriter_;
|
||||
#else
|
||||
return this->conditionWriter_;
|
||||
#endif
|
||||
@ -173,7 +173,7 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
if (!this->GetCondition().WaitForSignalNS(iSecondTimeout))
|
||||
#else
|
||||
if (!this->GetCondition().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout))
|
||||
if (!this->GetCondition().WaitForSignalNsEx(&this->mutex_, iSecondTimeout))
|
||||
#endif
|
||||
{
|
||||
return false;
|
||||
@ -229,7 +229,7 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
if (!this->GetCondition().WaitForSignalNS(iSecondTimeout))
|
||||
#else
|
||||
if (!this->GetCondition().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout))
|
||||
if (!this->GetCondition().WaitForSignalNsEx(&this->mutex_, iSecondTimeout))
|
||||
#endif
|
||||
{
|
||||
return false;
|
||||
@ -297,7 +297,7 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
bool bStatus = this->GetConditionWriter().WaitForSignalNS(iSecondTimeout);
|
||||
#else
|
||||
bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout);
|
||||
bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, iSecondTimeout);
|
||||
#endif
|
||||
|
||||
if constexpr (bIsWriteRecursionAllowed)
|
||||
@ -382,7 +382,7 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
bool bStatus = this->GetConditionWriter().WaitForSignalNS(uSecondTimeout);
|
||||
#else
|
||||
bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), uSecondTimeout);
|
||||
bool bStatus = this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, uSecondTimeout);
|
||||
#endif
|
||||
|
||||
if constexpr (bIsWriteRecursionAllowed)
|
||||
@ -624,7 +624,7 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
if (!this->GetConditionWriter().WaitForSignalNS(iSecondTimeout))
|
||||
#else
|
||||
if (!this->GetConditionWriter().WaitForSignalNsEx(AuUnsafeRaiiToShared(&this->mutex_), iSecondTimeout))
|
||||
if (!this->GetConditionWriter().WaitForSignalNsEx(&this->mutex_, iSecondTimeout))
|
||||
#endif
|
||||
{
|
||||
return false;
|
||||
|
@ -80,18 +80,18 @@ namespace Aurora::Threading::Primitives
|
||||
IWaitable *AsReadable() override;
|
||||
IWaitable *AsWritable() override;
|
||||
|
||||
auline ConditionVariableImpl &GetCondition();
|
||||
auline ConditionVariableImpl &GetConditionWriter();
|
||||
auline ConditionVariableInternal &GetCondition();
|
||||
auline ConditionVariableInternal &GetConditionWriter();
|
||||
|
||||
private:
|
||||
|
||||
RWLockAccessView<true, RWLockImpl> read_;
|
||||
RWLockAccessView<false, RWLockImpl> write_;
|
||||
|
||||
ConditionMutexImpl mutex_;
|
||||
ConditionMutexInternal mutex_;
|
||||
#if defined(AURWLOCK_NO_SIZE_OPTIMIZED_CONDVAR)
|
||||
ConditionVariableImpl condition_;
|
||||
ConditionVariableImpl conditionWriter_;
|
||||
ConditionVariableInternal condition_;
|
||||
ConditionVariableInternal conditionWriter_;
|
||||
#else
|
||||
char conditionVariable_[kSizeOfDummyCondVar] {};
|
||||
char conditionVariableWriter_[kSizeOfDummyCondVar] {};
|
||||
|
@ -15,15 +15,13 @@
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
SemaphoreImpl::SemaphoreImpl(AuUInt16 uIntialValue) :
|
||||
var(AuUnsafeRaiiToShared(&this->mutex))
|
||||
SemaphoreImpl::SemaphoreImpl(AuUInt16 uIntialValue)
|
||||
{
|
||||
this->dwState_ = uIntialValue;
|
||||
}
|
||||
|
||||
SemaphoreImpl::~SemaphoreImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool SemaphoreImpl::HasOSHandle(AuMach &mach)
|
||||
@ -110,11 +108,11 @@ namespace Aurora::Threading::Primitives
|
||||
return false;
|
||||
}
|
||||
|
||||
var.WaitForSignalNS(uEnd - uStart);
|
||||
var.WaitForSignalNsEx(&this->mutex, uEnd - uStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
var.WaitForSignalNS(0);
|
||||
var.WaitForSignalNsEx(&this->mutex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
private:
|
||||
AuUInt32 dwState_ {};
|
||||
ConditionMutexImpl mutex;
|
||||
ConditionVariableImpl var;
|
||||
ConditionMutexInternal mutex;
|
||||
ConditionVariableInternal var;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user