From 6642734aa86cddbf8ce5252062127d14feb8d074 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 18 Apr 2020 12:37:58 -0700 Subject: [PATCH] Removes the dumb timer wait for idle Turns out my Threadripper stomps these tests so the arbitrary wait time actually slows down my unit test time. Don't want to make it shorter since `strace -f` becomes ugly at that point. Instead set up a semaphore style waiting structure that waits until there are no longer any participants in the atomic --- .../Source/Interface/Context/Context.h | 5 +++ .../FEXCore/Source/Interface/Core/Core.cpp | 36 ++++++++----------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/External/FEXCore/Source/Interface/Context/Context.h b/External/FEXCore/Source/Interface/Context/Context.h index 62a007aa7..f8f228bb3 100644 --- a/External/FEXCore/Source/Interface/Context/Context.h +++ b/External/FEXCore/Source/Interface/Context/Context.h @@ -65,6 +65,11 @@ namespace FEXCore::Context { FEXCore::Core::InternalThreadState* ParentThread; std::vector Threads; std::atomic_bool ShouldStop{}; + + std::mutex IdleWaitMutex; + std::condition_variable IdleWaitCV; + std::atomic IdleWaitRefCount{}; + Event PauseWait; bool Running{}; CoreRunningMode RunningMode {CoreRunningMode::MODE_RUN}; diff --git a/External/FEXCore/Source/Interface/Core/Core.cpp b/External/FEXCore/Source/Interface/Core/Core.cpp index bb45dda66..996e63715 100644 --- a/External/FEXCore/Source/Interface/Core/Core.cpp +++ b/External/FEXCore/Source/Interface/Core/Core.cpp @@ -314,26 +314,10 @@ namespace FEXCore::Context { } void Context::WaitForIdle() { - do { - bool AllPaused = true; - { - std::lock_guard lk(ThreadCreationMutex); - { - // Grab the mutex lock so a thread doesn't try and spin up while we are waiting - for (size_t i = 0; i < Threads.size(); ++i) { - if (Threads[i]->State.RunningEvents.Running.load() || Threads[i]->State.RunningEvents.WaitingToStart.load()) { - AllPaused = false; - break; - } - } - } - } - - if (AllPaused) - break; - - PauseWait.WaitFor(std::chrono::milliseconds(250)); - } while (true); + std::unique_lock lk(IdleWaitMutex); + IdleWaitCV.wait(lk, [this] { + return IdleWaitRefCount.load() == 0; + }); Running = false; } @@ -656,6 +640,7 @@ namespace FEXCore::Context { // Let's do some initial bookkeeping here Thread->State.ThreadManager.TID = ::gettid(); + ++IdleWaitRefCount; // Now notify the thread that we are initialized Thread->ThreadWaiting.NotifyAll(); @@ -666,6 +651,9 @@ namespace FEXCore::Context { Thread->State.RunningEvents.ShouldStop.store(true); Thread->State.RunningEvents.Running.store(false); Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN; + + --IdleWaitRefCount; + IdleWaitCV.notify_all(); return; } @@ -797,6 +785,9 @@ namespace FEXCore::Context { ShouldStop = true; Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN; } + + --IdleWaitRefCount; + IdleWaitCV.notify_all(); break; } @@ -808,8 +799,10 @@ namespace FEXCore::Context { if (Thread->ExitReason == FEXCore::Context::ExitReason::EXIT_NONE) Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_DEBUG; - HandleExit(Thread); + --IdleWaitRefCount; + IdleWaitCV.notify_all(); + HandleExit(Thread); Thread->StartRunning.Wait(); @@ -819,6 +812,7 @@ namespace FEXCore::Context { Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_NONE; Thread->State.RunningEvents.Running = true; + ++IdleWaitRefCount; } } }