CPU: Fix deadlocks by periodically yielding to the UI message pump.
This commit is contained in:
parent
8203ea929b
commit
05a3f927ee
|
@ -160,11 +160,15 @@ void Stop()
|
||||||
std::unique_lock<std::mutex> state_lock(s_state_change_lock);
|
std::unique_lock<std::mutex> state_lock(s_state_change_lock);
|
||||||
s_state = CPU_POWERDOWN;
|
s_state = CPU_POWERDOWN;
|
||||||
s_state_cpu_cvar.notify_one();
|
s_state_cpu_cvar.notify_one();
|
||||||
// FIXME: MsgHandler can cause this to deadlock the GUI Thread. Remove the timeout.
|
|
||||||
bool success = s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::seconds(5),
|
while (s_state_cpu_thread_active)
|
||||||
[] { return !s_state_cpu_thread_active; });
|
{
|
||||||
if (!success)
|
std::cv_status status =
|
||||||
ERROR_LOG(POWERPC, "CPU Thread failed to acknowledge CPU_POWERDOWN. It may be deadlocked.");
|
s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::milliseconds(100));
|
||||||
|
if (status == std::cv_status::timeout)
|
||||||
|
Host_YieldToUI();
|
||||||
|
}
|
||||||
|
|
||||||
RunAdjacentSystems(false);
|
RunAdjacentSystems(false);
|
||||||
FlushStepSyncEventLocked();
|
FlushStepSyncEventLocked();
|
||||||
}
|
}
|
||||||
|
@ -226,12 +230,13 @@ void EnableStepping(bool stepping)
|
||||||
{
|
{
|
||||||
SetStateLocked(CPU_STEPPING);
|
SetStateLocked(CPU_STEPPING);
|
||||||
|
|
||||||
// Wait for the CPU Thread to leave the run loop
|
while (s_state_cpu_thread_active)
|
||||||
// FIXME: MsgHandler can cause this to deadlock the GUI Thread. Remove the timeout.
|
{
|
||||||
bool success = s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::seconds(5),
|
std::cv_status status =
|
||||||
[] { return !s_state_cpu_thread_active; });
|
s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::milliseconds(100));
|
||||||
if (!success)
|
if (status == std::cv_status::timeout)
|
||||||
ERROR_LOG(POWERPC, "Abandoned waiting for CPU Thread! The Core may be deadlocked.");
|
Host_YieldToUI();
|
||||||
|
}
|
||||||
|
|
||||||
RunAdjacentSystems(false);
|
RunAdjacentSystems(false);
|
||||||
}
|
}
|
||||||
|
@ -276,12 +281,13 @@ bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent)
|
||||||
was_unpaused = s_state == CPU_RUNNING;
|
was_unpaused = s_state == CPU_RUNNING;
|
||||||
SetStateLocked(CPU_STEPPING);
|
SetStateLocked(CPU_STEPPING);
|
||||||
|
|
||||||
// FIXME: MsgHandler can cause this to deadlock the GUI Thread. Remove the timeout.
|
while (s_state_cpu_thread_active)
|
||||||
bool success = s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::seconds(10),
|
{
|
||||||
[] { return !s_state_cpu_thread_active; });
|
std::cv_status status =
|
||||||
if (!success)
|
s_state_cpu_idle_cvar.wait_for(state_lock, std::chrono::milliseconds(100));
|
||||||
PanicAlert(
|
if (status == std::cv_status::timeout)
|
||||||
"Abandoned CPU Thread synchronization in CPU::PauseAndLock! We'll probably crash now.");
|
Host_YieldToUI();
|
||||||
|
}
|
||||||
|
|
||||||
if (control_adjacent)
|
if (control_adjacent)
|
||||||
RunAdjacentSystems(false);
|
RunAdjacentSystems(false);
|
||||||
|
|
Loading…
Reference in New Issue