diff --git a/Include/Aurora/Async/IThreadPool.hpp b/Include/Aurora/Async/IThreadPool.hpp index be2d1f30..ac6552de 100644 --- a/Include/Aurora/Async/IThreadPool.hpp +++ b/Include/Aurora/Async/IThreadPool.hpp @@ -93,13 +93,19 @@ namespace Aurora::Async static AuSPtr GetSelfIONetWorker(); // Synchronization + + // Legacy Barrier: blocks a/a group of threads // Note: syncing to yourself will nullify requireSignal to prevent deadlock conditions virtual bool Sync(WorkerId_t workerId, AuUInt32 timeoutMs = 0, bool bRequireSignal = false) = 0; + // Legacy Barrier: wakes up a/a group of ::Sync()'d threads virtual void Signal(WorkerId_t workerId) = 0; + // Breaks ::RunOnce() + virtual void Wakeup(WorkerId_t workerId) = 0; + virtual AuSPtr WorkerToLoopSource(WorkerId_t id) = 0; virtual void SyncAllSafe() = 0; diff --git a/Source/Async/AsyncApp.cpp b/Source/Async/AsyncApp.cpp index 770b2618..885b2757 100644 --- a/Source/Async/AsyncApp.cpp +++ b/Source/Async/AsyncApp.cpp @@ -208,6 +208,11 @@ namespace Aurora::Async ThreadPool::Signal(workerId); } + void AsyncApp::Wakeup(WorkerId_t workerId) + { + ThreadPool::Wakeup(workerId); + } + void AsyncApp::SyncAllSafe() { ThreadPool::SyncAllSafe(); diff --git a/Source/Async/AsyncApp.hpp b/Source/Async/AsyncApp.hpp index 8f4c070a..30c587ed 100644 --- a/Source/Async/AsyncApp.hpp +++ b/Source/Async/AsyncApp.hpp @@ -38,6 +38,7 @@ namespace Aurora::Async bool Sync(WorkerId_t workerId, AuUInt32 timeoutMs = 0, bool requireSignal = false) override; AuSPtr WorkerToLoopSource(WorkerId_t id) override; void Signal(WorkerId_t workerId) override; + void Wakeup(WorkerId_t workerId) override; void SyncAllSafe() override; void AddFeature(WorkerId_t id, AuSPtr feature, bool async) override; void AssertInThreadGroup(ThreadGroup_t group) override; diff --git a/Source/Async/AuGroupState.cpp b/Source/Async/AuGroupState.cpp index 1294450f..36f7c502 100644 --- a/Source/Async/AuGroupState.cpp +++ b/Source/Async/AuGroupState.cpp @@ -69,7 +69,7 @@ namespace Aurora::Async } } - void GroupState::SignalAll() + void GroupState::SignalAll(bool bHasWork) { AU_LOCK_GUARD(this->workersMutex); @@ -80,7 +80,7 @@ namespace Aurora::Async continue; } - pWorker->sync.SetEvent(true, true); + pWorker->sync.SetEvent(true, bHasWork); } } diff --git a/Source/Async/AuGroupState.hpp b/Source/Async/AuGroupState.hpp index f85643d4..087fa0e8 100644 --- a/Source/Async/AuGroupState.hpp +++ b/Source/Async/AuGroupState.hpp @@ -32,7 +32,7 @@ namespace Aurora::Async bool Init(); - void SignalAll(); + void SignalAll(bool bHasWork = true); void Decommit(ThreadId_t id); bool AddWorker(ThreadId_t id, AuSPtr pState); diff --git a/Source/Async/AuThreadState.cpp b/Source/Async/AuThreadState.cpp index 33cf1ce6..f52453b2 100644 --- a/Source/Async/AuThreadState.cpp +++ b/Source/Async/AuThreadState.cpp @@ -74,6 +74,11 @@ namespace Aurora::Async void ThreadStateSync::SetEvent(bool bBoth, bool bHasWork) { + if (bHasWork) + { + AuAtomicAdd(&this->cvHasWork, 1u); + } + if (auto pEvent = this->eventLs) { if (AuAtomicTestAndSet(&this->cvLSActive, 0u) == 0) @@ -82,11 +87,6 @@ namespace Aurora::Async } } - if (bHasWork) - { - AuAtomicAdd(&this->cvHasWork, 1u); - } - if (bBoth) { this->cvWorkMutex->Lock(); diff --git a/Source/Async/ThreadPool.cpp b/Source/Async/ThreadPool.cpp index 83b7270c..d87a60e5 100644 --- a/Source/Async/ThreadPool.cpp +++ b/Source/Async/ThreadPool.cpp @@ -894,7 +894,7 @@ namespace Aurora::Async return true; } - + void ThreadPool::Signal(WorkerId_t workerId) { auto group = GetGroup(workerId.first); @@ -906,9 +906,22 @@ namespace Aurora::Async jobWorker.second->running->Set(); } } - else + else if (auto pThread = GetThreadHandle(workerId)) { - GetThreadHandle(workerId)->running->Set(); + pThread->running->Set(); + } + } + + void ThreadPool::Wakeup(WorkerId_t workerId) + { + auto group = GetGroup(workerId.first); + if (workerId.second == Async::kThreadIdAny) + { + group->SignalAll(false); + } + else if (auto pThread = GetThreadHandle(workerId)) + { + pThread->sync.SetEvent(true, false); } } diff --git a/Source/Async/ThreadPool.hpp b/Source/Async/ThreadPool.hpp index 472ca406..e6bff9ac 100644 --- a/Source/Async/ThreadPool.hpp +++ b/Source/Async/ThreadPool.hpp @@ -70,6 +70,7 @@ namespace Aurora::Async virtual bool Sync(WorkerId_t workerId, AuUInt32 timeoutMs, bool requireSignal) override; virtual void Signal(WorkerId_t workerId) override; + virtual void Wakeup(WorkerId_t workerId) override; virtual AuSPtr WorkerToLoopSource(WorkerId_t id) override; virtual void SyncAllSafe() override;