[+] AuThreadPrimitives::SmallConditionVariable

[+] AuSmallCondvar
This commit is contained in:
Reece Wilson 2024-12-13 21:17:17 +00:00
parent b9277f0cd9
commit 673d7e3284
7 changed files with 146 additions and 32 deletions

View File

@ -69,21 +69,25 @@ using AuByteBuffer = AuMemory::ByteBuffer;
using AuSemaphore = AuThreadPrimitives::Semaphore;
#endif
using AuRenterableMutex = AuThreadPrimitives::CriticalSection;
using AuCriticalSection = AuThreadPrimitives::CriticalSection;
using AuRWRenterableLock = AuThreadPrimitives::RWRenterableLock;
using AuRWLock = AuThreadPrimitives::RWLock;
using AuCond = AuThreadPrimitives::ConditionVariable;
using AuConditionVariable = AuThreadPrimitives::ConditionVariable;
using AuConditionMutex = AuThreadPrimitives::ConditionMutex;
using AuCondition = AuThreadPrimitives::ConditionVariable;
using AuCondMutex = AuThreadPrimitives::ConditionMutex;
using AuSpinLock = AuThreadPrimitives::SpinLock;
using AuCondEx = AuThreadPrimitives::FlexibleConditionVariable;
using AuFlexibleConditionVariable = AuThreadPrimitives::FlexibleConditionVariable;
using AuConditionEx = AuThreadPrimitives::FlexibleConditionVariable;
using AuBinarySemaphore = AuThreadPrimitives::Event;
using AuEvent = AuThreadPrimitives::Event;
using AuRenterableMutex = AuThreadPrimitives::CriticalSection;
using AuCriticalSection = AuThreadPrimitives::CriticalSection;
using AuRWRenterableLock = AuThreadPrimitives::RWRenterableLock;
using AuRWLock = AuThreadPrimitives::RWLock;
using AuCond = AuThreadPrimitives::ConditionVariable;
using AuConditionVariable = AuThreadPrimitives::ConditionVariable;
using AuSmallConditionVariable = AuThreadPrimitives::SmallConditionVariable;
using AuConditionMutex = AuThreadPrimitives::ConditionMutex;
using AuCondition = AuThreadPrimitives::ConditionVariable;
using AuSmallCondition = AuThreadPrimitives::SmallConditionVariable;
using AuSmallCondVar = AuThreadPrimitives::SmallConditionVariable;
using AuCondVar = AuThreadPrimitives::ConditionVariable;
using AuCondMutex = AuThreadPrimitives::ConditionMutex;
using AuSpinLock = AuThreadPrimitives::SpinLock;
using AuCondEx = AuThreadPrimitives::FlexibleConditionVariable;
using AuFlexibleConditionVariable = AuThreadPrimitives::FlexibleConditionVariable;
using AuConditionEx = AuThreadPrimitives::FlexibleConditionVariable;
using AuBinarySemaphore = AuThreadPrimitives::Event;
using AuEvent = AuThreadPrimitives::Event;
using AuFutexMutex = AuThreading::Futexes::FutexWaitable;
using AuFutexMutexSpecial = AuThreading::Futexes::FutexWaitableNoVTblMovable;

View File

@ -27,14 +27,14 @@ namespace Aurora::Threading::Primitives
* @brief
* @param uTimeoutMS timeout in milliseconds or zero for an indefinite amount of time
* @return
*/
*/
virtual bool WaitForSignal(AuUInt32 uTimeoutMS = 0) = 0;
/**
* @brief
* @param uTimeoutMS timeout in nanoseconds or zero for an indefinite amount of time
* @return
*/
*/
virtual bool WaitForSignalNS(AuUInt64 uTimeoutNS = 0) = 0;
/**
@ -43,13 +43,45 @@ namespace Aurora::Threading::Primitives
*/
virtual void Broadcast() = 0;
/**
* @brief Schedules a single thread for wake up without guaranteed respect for ordering.
*/
virtual void Signal() = 0;
};
AUKN_SHARED_SOO2_NCM(ConditionVariable, IConditionVariable, kPrimitiveSizeCond,
((const AuSPtr<IConditionMutex>&, pMutex)),
const AuSPtr<IConditionMutex> &pMutex);
struct ISmallConditionVariable
{
/**
* @brief
* @param uTimeoutMS timeout in milliseconds or zero for an indefinite amount of time
* @return
*/
virtual bool WaitForSignal(IConditionMutex *pMutex,
AuUInt32 uTimeoutMS = 0) = 0;
/**
* @brief
* @param uTimeoutMS timeout in nanoseconds or zero for an indefinite amount of time
* @return
*/
virtual bool WaitForSignalNS(IConditionMutex *pMutex,
AuUInt64 uTimeoutNS = 0) = 0;
/**
* @brief Wakes the count of currently sleeping threads without guaranteed respect for ordering.
* Assuming correctness of your mutex paths, this will wake all threads up-to your everyone-be-alert condition.
*/
virtual void Broadcast() = 0;
/**
* @brief Schedules a single thread for wake up without guaranteed respect for ordering.
*/
virtual void Signal() = 0;
};
AUKN_SHARED_SOO2_NCM(ConditionVariable, IConditionVariable, kPrimitiveSizeCond,
((const AuSPtr<IConditionMutex>&, pMutex)),
const AuSPtr<IConditionMutex> &pMutex);
AUKN_SHARED_SOO2_NCM(SmallConditionVariable, ISmallConditionVariable, kPrimitiveSizeCond2, ());
}

View File

@ -25,6 +25,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize64NTEvent = 24;
static const auto kPrimitiveSize64NTRWLock = 56;
static const auto kPrimitiveSize64NTCond = 32;
static const auto kPrimitiveSize64NTCond2 = 16;
static const auto kPrimitiveSize64NTCondMutex = 16;
static const auto kPrimitiveSize32NTMutex = 8;
@ -33,6 +34,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize32NTEvent = 20;
static const auto kPrimitiveSize32NTRWLock = 44;
static const auto kPrimitiveSize32NTCond = 20;
static const auto kPrimitiveSize32NTCond2 = 12;
static const auto kPrimitiveSize32NTCondMutex = 8;
static const auto kPrimitiveSize64LinuxMutex = 16;
@ -41,6 +43,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize64LinuxEvent = 32;
static const auto kPrimitiveSize64LinuxRWLock = 48;
static const auto kPrimitiveSize64LinuxCond = 32;
static const auto kPrimitiveSize64LinuxCond2 = 16;
static const auto kPrimitiveSize64LinuxCondMutex = 16;
// TODO: These values aren't quite correct yet:
@ -50,6 +53,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize32LinuxEvent = 32;
static const auto kPrimitiveSize32LinuxRWLock = 48;
static const auto kPrimitiveSize32LinuxCond = 32;
static const auto kPrimitiveSize32LinuxCond2 = 16;
static const auto kPrimitiveSize32LinuxCondMutex = 12;
// TODO: Other platforms...
@ -69,6 +73,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize64Event = kPrimitiveSize64NTEvent;
static const auto kPrimitiveSize64RWLock = kPrimitiveSize64NTRWLock;
static const auto kPrimitiveSize64Cond = kPrimitiveSize64NTCond;
static const auto kPrimitiveSize64Cond2 = kPrimitiveSize64NTCond2;
static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64NTCondMutex;
static const auto kPrimitiveSize32Mutex = kPrimitiveSize32NTMutex;
@ -77,6 +82,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize32Event = kPrimitiveSize32NTEvent;
static const auto kPrimitiveSize32RWLock = kPrimitiveSize32NTRWLock;
static const auto kPrimitiveSize32Cond = kPrimitiveSize32NTCond;
static const auto kPrimitiveSize32Cond2 = kPrimitiveSize32NTCond2;
static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32NTCondMutex;
#define AURT_ENABLE_HYPER_MUTEX
@ -89,6 +95,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize64Event = kPrimitiveSize64LinuxEvent;
static const auto kPrimitiveSize64RWLock = kPrimitiveSize64LinuxRWLock;
static const auto kPrimitiveSize64Cond = kPrimitiveSize64LinuxCond;
static const auto kPrimitiveSize64Cond2 = kPrimitiveSize64LinuxCond2;
static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64LinuxCondMutex;
static const auto kPrimitiveSize32Mutex = kPrimitiveSize32LinuxMutex;
@ -97,6 +104,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize32Event = kPrimitiveSize32LinuxEvent;
static const auto kPrimitiveSize32RWLock = kPrimitiveSize32LinuxRWLock;
static const auto kPrimitiveSize32Cond = kPrimitiveSize32LinuxCond;
static const auto kPrimitiveSize32Cond2 = kPrimitiveSize32LinuxCond2;
static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32LinuxCondMutex;
#define AURT_ENABLE_HYPER_MUTEX
@ -109,6 +117,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSize64Event = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64 * 2;
static const auto kPrimitiveSize64Cond = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64Cond2 = kDefaultPrimitiveSize64;
static const auto kPrimitiveSize64CondMutex = kDefaultPrimitiveSize64;
#endif
@ -121,6 +130,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSizeEvent = kPrimitiveSize64Event;
static const auto kPrimitiveSizeRWLock = kPrimitiveSize64RWLock;
static const auto kPrimitiveSizeCond = kPrimitiveSize64Cond;
static const auto kPrimitiveSizeCond2 = kPrimitiveSize64Cond2;
static const auto kPrimitiveSizeCondMutex = kPrimitiveSize64CondMutex;
#else
@ -131,6 +141,7 @@ namespace Aurora::Threading::Primitives
static const auto kPrimitiveSizeEvent = kPrimitiveSize32Event;
static const auto kPrimitiveSizeRWLock = kPrimitiveSize32RWLock;
static const auto kPrimitiveSizeCond = kPrimitiveSize32Cond;
static const auto kPrimitiveSizeCond2 = kPrimitiveSize32Cond2;
static const auto kPrimitiveSizeCondMutex = kPrimitiveSize32CondMutex;
#endif

View File

@ -215,6 +215,7 @@ namespace Aurora::Threading::Primitives
}
AUROXTL_INTERFACE_SOO_SRC(ConditionVariable, ConditionVariableImpl, (const AuSPtr<IConditionMutex> &, pMutex))
AUROXTL_INTERFACE_SOO_SRC(SmallConditionVariable, ConditionVariableImpl2)
}
#endif

View File

@ -45,37 +45,70 @@ namespace Aurora::Threading::Primitives
auline AuSPtr<IConditionMutex> GetMutex() override
{
return mutex;
return this->mutex;
}
auline bool WaitForSignal(AuUInt32 timeout) override
{
return cond.WaitForSignalNsEx(&std::static_pointer_cast<ConditionMutexImpl>(this->mutex)->mutex, AuMSToNS<AuUInt64>(timeout));
return this->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);
return this->cond.WaitForSignalNsEx(&std::static_pointer_cast<ConditionMutexImpl>(this->mutex)->mutex, qwTimeout);
}
inline bool WaitForSignalNsEx(const std::shared_ptr<LinuxConditionMutex> &pMutex, AuUInt64 timeout)
{
return cond.WaitForSignalNsEx(pMutex.get(), timeout);
return this->cond.WaitForSignalNsEx(pMutex.get(), timeout);
}
auline void Signal() override
{
cond.Signal();
this->cond.Signal();
}
auline void Broadcast() override
{
cond.Broadcast();
this->cond.Broadcast();
}
ConditionVariableInternal cond;
std::shared_ptr<IConditionMutex> mutex;
};
struct ConditionVariableImpl2 final : ISmallConditionVariable
{
auline bool WaitForSignal(IConditionMutex *pMutex,
AuUInt32 timeout) override
{
return this->cond.WaitForSignalNsEx(&AuStaticCast<ConditionMutexImpl>(pMutex)->mutex, AuMSToNS<AuUInt64>(timeout));
}
auline bool WaitForSignalNS(IConditionMutex *pMutex,
AuUInt64 qwTimeout) override
{
return this->cond.WaitForSignalNsEx(&AuStaticCast<ConditionMutexImpl>(pMutex)->mutex, qwTimeout);
}
inline bool WaitForSignalNsEx(const std::shared_ptr<LinuxConditionMutex> &pMutex, AuUInt64 timeout)
{
return this->cond.WaitForSignalNsEx(pMutex.get(), timeout);
}
auline void Signal() override
{
this->cond.Signal();
}
auline void Broadcast() override
{
this->cond.Broadcast();
}
ConditionVariableInternal cond;
};
static const auto kSizeOfDummyCondVar = sizeof(ConditionVariableInternal);

View File

@ -545,6 +545,7 @@ namespace Aurora::Threading::Primitives
}
AUROXTL_INTERFACE_SOO_SRC(ConditionVariable, ConditionVariableImpl, (const AuSPtr<IConditionMutex> &, pMutex))
AUROXTL_INTERFACE_SOO_SRC(SmallConditionVariable, ConditionVariableImpl2)
}
#endif

View File

@ -46,38 +46,70 @@ namespace Aurora::Threading::Primitives
auline AuSPtr<IConditionMutex> GetMutex() override
{
return mutex;
return this->mutex;
}
auline bool WaitForSignal(AuUInt32 timeout) override
{
return cond.WaitForSignalNsEx(&std::static_pointer_cast<ConditionMutexImpl>(this->mutex)->mutex, AuMSToNS<AuUInt64>(timeout));
return this->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);
return this->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);
return this->cond.WaitForSignalNsEx(pMutex.get(), timeout);
}
auline void Signal() override
{
cond.Signal();
this->cond.Signal();
}
auline void Broadcast() override
{
cond.Broadcast();
this->cond.Broadcast();
}
ConditionVariableNT cond;
std::shared_ptr<IConditionMutex> mutex;
};
struct ConditionVariableImpl2 final : ISmallConditionVariable
{
auline bool WaitForSignal(IConditionMutex *pMutex,
AuUInt32 timeout) override
{
return this->cond.WaitForSignalNsEx(&AuStaticCast<ConditionMutexImpl>(pMutex)->mutex, AuMSToNS<AuUInt64>(timeout));
}
auline bool WaitForSignalNS(IConditionMutex *pMutex,
AuUInt64 qwTimeout) override
{
return this->cond.WaitForSignalNsEx(&AuStaticCast<ConditionMutexImpl>(pMutex)->mutex, qwTimeout);
}
inline bool WaitForSignalNsEx(const std::shared_ptr<Win32ConditionMutex> &pMutex, AuUInt64 timeout)
{
return this->cond.WaitForSignalNsEx(pMutex.get(), timeout);
}
auline void Signal() override
{
this->cond.Signal();
}
auline void Broadcast() override
{
this->cond.Broadcast();
}
ConditionVariableNT cond;
};
static const auto kSizeOfDummyCondVar = sizeof(ConditionVariableInternal);
static const auto kBoolRequiredLateSet = true;