1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Do not allow to unpause after fatal error occured in emulation

* Plus fix #10590
This commit is contained in:
Eladash 2021-09-07 19:42:08 +03:00 committed by Megamouse
parent 69faf14a79
commit bd66dfedc9
5 changed files with 26 additions and 9 deletions

View File

@ -1580,7 +1580,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
} }
} }
Emu.Pause(); Emu.Pause(true);
if (!g_tls_access_violation_recovered) if (!g_tls_access_violation_recovered)
{ {

View File

@ -9489,7 +9489,6 @@ struct spu_llvm_worker
else else
{ {
spu_log.fatal("[0x%05x] Compilation failed.", func.entry_point); spu_log.fatal("[0x%05x] Compilation failed.", func.entry_point);
Emu.Pause();
return; return;
} }

View File

@ -1404,17 +1404,27 @@ void Emulator::Run(bool start_playtime)
} }
} }
bool Emulator::Pause() bool Emulator::Pause(bool freeze_emulation)
{ {
const u64 start = get_system_time(); const u64 start = get_system_time();
const system_state pause_state = freeze_emulation ? system_state::frozen : system_state::paused;
// Try to pause // Try to pause
if (!m_state.compare_and_swap_test(system_state::running, system_state::paused)) if (!m_state.compare_and_swap_test(system_state::running, pause_state))
{ {
if (!m_state.compare_and_swap_test(system_state::ready, system_state::paused)) if (!freeze_emulation)
{ {
return false; return false;
} }
if (!m_state.compare_and_swap_test(system_state::ready, pause_state))
{
if (!m_state.compare_and_swap_test(system_state::paused, pause_state))
{
return false;
}
}
} }
// Signal profilers to print results (if enabled) // Signal profilers to print results (if enabled)
@ -1424,7 +1434,14 @@ bool Emulator::Pause()
static atomic_t<u32> pause_mark = 0; static atomic_t<u32> pause_mark = 0;
sys_log.success("Emulation is being paused... (mark=%u)", pause_mark++); if (freeze_emulation)
{
sys_log.warning("Emulation has been frozen! You can either use debugger tools to inspect current emulation state or terminate it.");
}
else
{
sys_log.success("Emulation is being paused... (mark=%u)", pause_mark++);
}
// Update pause start time // Update pause start time
if (m_pause_start_time.exchange(start)) if (m_pause_start_time.exchange(start))

View File

@ -26,6 +26,7 @@ enum class system_state : u32
running, running,
stopped, stopped,
paused, paused,
frozen, // paused but cannot resume
ready, ready,
}; };
@ -221,7 +222,7 @@ public:
game_boot_result Load(const std::string& title_id = "", bool add_only = false, bool force_global_config = false, bool is_disc_patch = false); game_boot_result Load(const std::string& title_id = "", bool add_only = false, bool force_global_config = false, bool is_disc_patch = false);
void Run(bool start_playtime); void Run(bool start_playtime);
bool Pause(); bool Pause(bool freeze_emulation = false);
void Resume(); void Resume();
void Stop(bool restart = false); void Stop(bool restart = false);
void Restart() { Stop(true); } void Restart() { Stop(true); }
@ -232,7 +233,7 @@ public:
bool IsPaused() const { return m_state >= system_state::paused; } // ready is also considered paused by this function bool IsPaused() const { return m_state >= system_state::paused; } // ready is also considered paused by this function
bool IsStopped() const { return m_state == system_state::stopped; } bool IsStopped() const { return m_state == system_state::stopped; }
bool IsReady() const { return m_state == system_state::ready; } bool IsReady() const { return m_state == system_state::ready; }
auto GetStatus() const { return m_state.load(); } auto GetStatus() const { system_state state = m_state; return state == system_state::frozen ? system_state::paused : state; }
bool HasGui() const { return m_has_gui; } bool HasGui() const { return m_has_gui; }
void SetHasGui(bool has_gui) { m_has_gui = has_gui; } void SetHasGui(bool has_gui) { m_has_gui = has_gui; }

View File

@ -221,7 +221,7 @@ struct fatal_error_listener final : logs::listener
} }
#endif #endif
// Pause emulation if fatal error encountered // Pause emulation if fatal error encountered
Emu.Pause(); Emu.Pause(true);
} }
} }
}; };