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

Fix properly RSX replay thread stop bug

This commit is contained in:
Eladash 2023-06-19 10:49:59 +03:00 committed by Megamouse
parent aff871f127
commit 4f5348c7d4
3 changed files with 23 additions and 15 deletions

View File

@ -48,6 +48,17 @@ static void set_rsx_dmactl(rsx::thread* render, u64 get_put)
// Unconditional set
while (!render->new_get_put.compare_and_swap_test(u64{umax}, get_put))
{
// Wait for the first store to complete (or be aborted)
if (auto cpu = cpu_thread::get_current())
{
if (cpu->state & cpu_flag::exit)
{
// Retry
cpu->state += cpu_flag::again;
return;
}
}
utils::pause();
}
@ -60,12 +71,13 @@ static void set_rsx_dmactl(rsx::thread* render, u64 get_put)
// Wait for the first store to complete (or be aborted)
while (render->new_get_put != usz{umax})
{
if (Emu.IsStopped())
if (cpu->state & cpu_flag::exit)
{
if (render->new_get_put.compare_and_swap_test(get_put, umax))
{
// Retry
cpu->state += cpu_flag::again;
return;
}
}

View File

@ -173,7 +173,7 @@ namespace rsx
auto fifo_stops = alloc_write_fifo(context_id);
while (!Emu.IsStopped())
while (thread_ctrl::state() != thread_state::aborting)
{
// Load registers while the RSX is still idle
method_registers = frame->reg_state;
@ -191,7 +191,7 @@ namespace rsx
while (Emu.IsPaused())
thread_ctrl::wait_for(10'000);
if (Emu.IsStopped())
if (thread_ctrl::state() == thread_state::aborting)
break;
// Loop and hunt down our next state change that needs to be done
@ -199,11 +199,12 @@ namespace rsx
continue;
// wait until rsx idle and at our first 'stop' to apply state
while (!Emu.IsStopped() && !render->is_fifo_idle() && (render->ctrl->get != fifo_stops[stopIdx]))
while (thread_ctrl::state() != thread_state::aborting && !render->is_fifo_idle() && (render->ctrl->get != fifo_stops[stopIdx]))
{
while (Emu.IsPaused())
if (Emu.IsPaused())
thread_ctrl::wait_for(10'000);
std::this_thread::yield();
else
std::this_thread::yield();
}
stopIdx++;
@ -221,10 +222,12 @@ namespace rsx
u32 end = fifo_stops.back();
render->ctrl->put = end;
while (!render->is_fifo_idle() && !Emu.IsStopped())
while (!render->is_fifo_idle() && thread_ctrl::state() != thread_state::aborting)
{
while (Emu.IsPaused())
if (Emu.IsPaused())
thread_ctrl::wait_for(10'000);
else
std::this_thread::yield();
}
// Check if the captured application used syscall instead of a gcm command to flip

View File

@ -2570,13 +2570,6 @@ std::shared_ptr<utils::serial> Emulator::Kill(bool allow_autoexit, bool savestat
// Signal threads
// Stop the replay thread "game" first
if (auto thr = g_fxo->try_get<named_thread<rsx::rsx_replay_thread>>())
{
sys_log.notice("Stopping RSX replay thread...");
*thr = thread_state::finished;
}
if (auto rsx = g_fxo->try_get<rsx::thread>())
{
*static_cast<cpu_thread*>(rsx) = thread_state::aborting;