Skip to content
Permalink
Browse files

Merge pull request #8320 from CookiePLMonster/cpu-lock-yield-fix

Do not yield to UI from PauseAndLock
  • Loading branch information
JosJuice committed Nov 24, 2019
2 parents 17a0336 + 23f335b commit 45ba745bc8c2f7a858b9f0379777481432792e15
Showing with 12 additions and 21 deletions.
  1. +12 −21 Source/Core/Core/HW/CPU.cpp
@@ -87,7 +87,7 @@ static void ExecutePendingJobs(std::unique_lock<std::mutex>& state_lock)

void Run()
{
std::unique_lock<std::mutex> state_lock(s_state_change_lock);
std::unique_lock state_lock(s_state_change_lock);
while (s_state != State::PowerDown)
{
s_state_cpu_cvar.wait(state_lock, [] { return !s_state_paused_and_locked; });
@@ -177,16 +177,13 @@ void Stop()
// Change state and wait for it to be acknowledged.
// We don't need the stepping lock because State::PowerDown is a priority state which
// will stick permanently.
std::unique_lock<std::mutex> state_lock(s_state_change_lock);
std::unique_lock state_lock(s_state_change_lock);
s_state = State::PowerDown;
s_state_cpu_cvar.notify_one();

while (s_state_cpu_thread_active)
{
std::cv_status status =
s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::milliseconds(100));
if (status == std::cv_status::timeout)
Host_YieldToUI();
s_state_cpu_idle_cvar.wait(state_lock);
}

RunAdjacentSystems(false);
@@ -214,7 +211,7 @@ void Reset()

void StepOpcode(Common::Event* event)
{
std::lock_guard<std::mutex> state_lock(s_state_change_lock);
std::lock_guard state_lock(s_state_change_lock);
// If we're not stepping then this is pointless
if (!IsStepping())
{
@@ -243,19 +240,16 @@ static bool SetStateLocked(State s)

void EnableStepping(bool stepping)
{
std::lock_guard<std::mutex> stepping_lock(s_stepping_lock);
std::unique_lock<std::mutex> state_lock(s_state_change_lock);
std::lock_guard stepping_lock(s_stepping_lock);
std::unique_lock state_lock(s_state_change_lock);

if (stepping)
{
SetStateLocked(State::Stepping);

while (s_state_cpu_thread_active)
{
std::cv_status status =
s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::milliseconds(100));
if (status == std::cv_status::timeout)
Host_YieldToUI();
s_state_cpu_idle_cvar.wait(state_lock);
}

RunAdjacentSystems(false);
@@ -269,7 +263,7 @@ void EnableStepping(bool stepping)

void Break()
{
std::lock_guard<std::mutex> state_lock(s_state_change_lock);
std::lock_guard state_lock(s_state_change_lock);

// If another thread is trying to PauseAndLock then we need to remember this
// for later to ignore the unpause_on_unlock.
@@ -295,18 +289,15 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent)
{
s_stepping_lock.lock();

std::unique_lock<std::mutex> state_lock(s_state_change_lock);
std::unique_lock state_lock(s_state_change_lock);
s_state_paused_and_locked = true;

was_unpaused = s_state == State::Running;
SetStateLocked(State::Stepping);

while (s_state_cpu_thread_active)
{
std::cv_status status =
s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::milliseconds(100));
if (status == std::cv_status::timeout)
Host_YieldToUI();
s_state_cpu_idle_cvar.wait(state_lock);
}

if (control_adjacent)
@@ -331,7 +322,7 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent)
}

{
std::lock_guard<std::mutex> state_lock(s_state_change_lock);
std::lock_guard state_lock(s_state_change_lock);
if (s_state_system_request_stepping)
{
s_state_system_request_stepping = false;
@@ -353,7 +344,7 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent)

void AddCPUThreadJob(std::function<void()> function)
{
std::unique_lock<std::mutex> state_lock(s_state_change_lock);
std::unique_lock state_lock(s_state_change_lock);
s_pending_jobs.push(std::move(function));
}

0 comments on commit 45ba745

Please sign in to comment.
You can’t perform that action at this time.