From 346a9f3bded304cf1a171816bc7713edc4d1a49c Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Sat, 26 Aug 2023 15:53:13 +0100 Subject: [PATCH] [*] More aggressively wake up reorder prone (unlikely) condvars under broadcast (unlikely) --- .../Threading/Waitables/FutexCondWaitable.hpp | 19 +++++++++---------- Source/Threading/Primitives/AuConditionEx.cpp | 19 +++++++++---------- .../Primitives/AuConditionVariable.Linux.cpp | 19 +++++++++---------- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/Include/Aurora/Threading/Waitables/FutexCondWaitable.hpp b/Include/Aurora/Threading/Waitables/FutexCondWaitable.hpp index abd6b67f..cc9b5e47 100644 --- a/Include/Aurora/Threading/Waitables/FutexCondWaitable.hpp +++ b/Include/Aurora/Threading/Waitables/FutexCondWaitable.hpp @@ -124,22 +124,21 @@ namespace Aurora::Threading::Waitables AuUInt32 uWaitCount {}; AuUInt32 uWaiters {}; - uWaiters = AuAtomicLoad(&this->uAtomicSleeping); - if (uWaiters > 0) + while (uWaiters = AuAtomicLoad(&this->uAtomicSleeping)) { AuAtomicAdd(&this->uAtomicState, uWaiters); WakeNOnAddress((const void *)&this->uAtomicState, uWaiters); uWaitCount = uWaiters; - } - while (uWaiters && - AuAtomicCompareExchange(&this->uAtomicSleeping, uWaiters - uWaitCount, uWaiters) != uWaiters) - { - uWaiters = this->uAtomicSleeping; - - if (uWaiters == 0) + while (uWaiters && + AuAtomicCompareExchange(&this->uAtomicSleeping, uWaiters - uWaitCount, uWaiters) != uWaiters) { - return; + uWaiters = this->uAtomicSleeping; + + if (uWaiters <= uWaitCount) + { + uWaitCount = uWaiters; + } } } } diff --git a/Source/Threading/Primitives/AuConditionEx.cpp b/Source/Threading/Primitives/AuConditionEx.cpp index 8cff8529..3cad8bb3 100644 --- a/Source/Threading/Primitives/AuConditionEx.cpp +++ b/Source/Threading/Primitives/AuConditionEx.cpp @@ -141,21 +141,20 @@ namespace Aurora::Threading::Primitives AuUInt32 uWaitCount {}; AuUInt32 uWaiters {}; - uWaiters = AuAtomicLoad(&this->uWaiters_); - if (uWaiters > 0) + while (uWaiters = AuAtomicLoad(&this->uWaiters_)) { this->s_.Unlock(uWaiters); uWaitCount = uWaiters; - } - while (uWaiters && - AuAtomicCompareExchange(&this->uWaiters_, uWaiters - uWaitCount, uWaiters) != uWaiters) - { - uWaiters = this->uWaiters_; - - if (uWaiters <= uWaitCount) + while (uWaiters && + AuAtomicCompareExchange(&this->uWaiters_, uWaiters - uWaitCount, uWaiters) != uWaiters) { - uWaitCount = uWaiters; + uWaiters = this->uWaiters_; + + if (uWaiters <= uWaitCount) + { + uWaitCount = uWaiters; + } } } } diff --git a/Source/Threading/Primitives/AuConditionVariable.Linux.cpp b/Source/Threading/Primitives/AuConditionVariable.Linux.cpp index 5e4e5da9..21d27426 100644 --- a/Source/Threading/Primitives/AuConditionVariable.Linux.cpp +++ b/Source/Threading/Primitives/AuConditionVariable.Linux.cpp @@ -163,22 +163,21 @@ namespace Aurora::Threading::Primitives AuUInt32 uWaitCount {}; AuUInt32 uWaiters {}; - uWaiters = AuAtomicLoad(&this->uSleeping_); - if (uWaiters > 0) + while (uWaiters = AuAtomicLoad(&this->uSleeping_)) { AuAtomicAdd(&this->uState_, uWaiters); futex_wake(&this->uState_, uWaiters); uWaitCount = uWaiters; - } - while (uWaiters && - AuAtomicCompareExchange(&this->uSleeping_, uWaiters - uWaitCount, uWaiters) != uWaiters) - { - uWaiters = this->uSleeping_; - - if (uWaiters <= uWaitCount) + while (uWaiters && + AuAtomicCompareExchange(&this->uSleeping_, uWaiters - uWaitCount, uWaiters) != uWaiters) { - uWaitCount = uWaiters; + uWaiters = AuAtomicLoad(&this->uSleeping_); + + if (uWaiters <= uWaitCount) + { + uWaitCount = uWaiters; + } } } }