[*] I'm going to let the reference waitaible/woa/futex primitives be copy and movable now.

condvars -> cannot matter, you're creating a new object
mutex -> cannot mater, you're creating a new object, perhaps copy assignment under lock might be required depending on the parent. either way, a copy ctor is not required
semaphore -> copy state in case of the timelime barrier use case. semaphores emulating condvars and similar logic wont mind the overshoot. best case, we do want to copy the previous state as the initial count. worst case, your code is fundamentally broken.
This commit is contained in:
Reece Wilson 2024-05-28 00:37:00 +01:00
parent 78d4ce3d58
commit d520b0ce42
3 changed files with 40 additions and 15 deletions

View File

@ -16,8 +16,12 @@ namespace Aurora::Threading::Waitables
{ {
inline constexpr FutexCondWaitable() inline constexpr FutexCondWaitable()
{} {}
AU_MOVE(FutexCondWaitable)
AU_NO_COPY_NO_MOVE(FutexCondWaitable); inline constexpr FutexCondWaitable(const FutexCondWaitable &that)
{
// NOP
}
AU_OPERATOR_COPY(FutexCondWaitable)
template <class T> template <class T>
inline bool WaitNS(T pWaitable, AuUInt64 uRelativeNanoseconds) inline bool WaitNS(T pWaitable, AuUInt64 uRelativeNanoseconds)
@ -95,7 +99,7 @@ namespace Aurora::Threading::Waitables
return bSuccess; return bSuccess;
} }
auline void NotifyOne() inline auline void NotifyOne()
{ {
AuUInt32 uWaiters = AuAtomicLoad(&this->uAtomicSleeping); AuUInt32 uWaiters = AuAtomicLoad(&this->uAtomicSleeping);
if (uWaiters == 0) if (uWaiters == 0)
@ -117,7 +121,7 @@ namespace Aurora::Threading::Waitables
} }
} }
auline void Broadcast() inline auline void Broadcast()
{ {
AuUInt32 uWaitCount {}; AuUInt32 uWaitCount {};
AuUInt32 uWaiters {}; AuUInt32 uWaiters {};
@ -145,7 +149,7 @@ namespace Aurora::Threading::Waitables
} }
} }
auline void NotifyN(AuUInt32 uThreads) inline auline void NotifyN(AuUInt32 uThreads)
{ {
AuUInt32 uWaitCount {}; AuUInt32 uWaitCount {};
AuUInt32 uWaiters {}; AuUInt32 uWaiters {};
@ -175,13 +179,13 @@ namespace Aurora::Threading::Waitables
AuAUInt32 uAtomicSleeping {}; AuAUInt32 uAtomicSleeping {};
private: private:
auline bool TryLock3() inline auline bool TryLock3()
{ {
auto old = AuAtomicLoad(&this->uAtomicState); auto old = AuAtomicLoad(&this->uAtomicState);
return ((old != 0 && AuAtomicCompareExchange(&this->uAtomicState, old - 1, old) == old)); return ((old != 0 && AuAtomicCompareExchange(&this->uAtomicState, old - 1, old) == old));
} }
auline bool TryLock2() inline auline bool TryLock2()
{ {
static const AuUInt32 kRef { 0 }; static const AuUInt32 kRef { 0 };
@ -201,7 +205,7 @@ namespace Aurora::Threading::Waitables
}); });
} }
auline bool SleepOne(AuUInt64 qwTimeout) inline auline bool SleepOne(AuUInt64 qwTimeout)
{ {
static const AuUInt32 kRef { 0 }; static const AuUInt32 kRef { 0 };

View File

@ -16,10 +16,14 @@ namespace Aurora::Threading::Waitables
{ {
inline constexpr FutexSemaphoreWaitable() inline constexpr FutexSemaphoreWaitable()
{} {}
AU_MOVE(FutexSemaphoreWaitable)
inline constexpr FutexSemaphoreWaitable(const FutexSemaphoreWaitable &that)
{
// NOP
}
AU_OPERATOR_COPY(FutexSemaphoreWaitable)
AU_NO_COPY_NO_MOVE(FutexSemaphoreWaitable); inline auline bool TryLockNoSpin()
auline bool TryLockNoSpin()
{ {
auto uState = this->uAtomicState; auto uState = this->uAtomicState;
return (uState != 0 && AuAtomicCompareExchange(&this->uAtomicState, uState - 1, uState) == uState); return (uState != 0 && AuAtomicCompareExchange(&this->uAtomicState, uState - 1, uState) == uState);

View File

@ -16,8 +16,12 @@ namespace Aurora::Threading::Waitables
{ {
inline constexpr FutexWaitable() inline constexpr FutexWaitable()
{} {}
AU_MOVE(FutexWaitable)
AU_NO_COPY_NO_MOVE(FutexWaitable); inline constexpr FutexWaitable(const FutexWaitable &that)
{
// NOP
}
AU_OPERATOR_COPY(FutexWaitable)
inline bool TryLockNoSpin() inline bool TryLockNoSpin()
{ {
@ -156,7 +160,14 @@ namespace Aurora::Threading::Waitables
struct FutexWaitableNoVTblMovable final struct FutexWaitableNoVTblMovable final
{ {
AU_COPY_MOVE_DEF(FutexWaitableNoVTblMovable); inline constexpr FutexWaitableNoVTblMovable()
{}
AU_MOVE(FutexWaitableNoVTblMovable)
inline constexpr FutexWaitableNoVTblMovable(const FutexWaitableNoVTblMovable &that)
{
// NOP
}
AU_OPERATOR_COPY(FutexWaitableNoVTblMovable)
inline bool TryLockNoSpin() inline bool TryLockNoSpin()
{ {
@ -285,7 +296,13 @@ namespace Aurora::Threading::Waitables
struct FutexWaitableNoVTblMovableSmallest final struct FutexWaitableNoVTblMovableSmallest final
{ {
AU_COPY_MOVE_DEF(FutexWaitableNoVTblMovableSmallest); //AU_COPY_MOVE_DEF(FutexWaitableNoVTblMovableSmallest);
AU_MOVE(FutexWaitableNoVTblMovableSmallest) AU_DEF(FutexWaitableNoVTblMovableSmallest)
inline FutexWaitableNoVTblMovableSmallest(const FutexWaitableNoVTblMovableSmallest &that)
{
// NOP
}
AU_OPERATOR_COPY(FutexWaitableNoVTblMovableSmallest)
inline bool TryLockNoSpin() inline bool TryLockNoSpin()
{ {