From 10dece1c804a2c86144f25951e360e47efa038e1 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Thu, 26 Sep 2024 20:24:24 +0300 Subject: [PATCH] SPU: Improve SPURS Task limit algorithm --- rpcs3/Emu/Cell/SPUThread.cpp | 69 ++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index ca50c5dcd2..e01e198478 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -4894,46 +4894,42 @@ bool spu_thread::process_mfc_cmd() // Avoid logging useless commands if there is no reservation const bool dump = g_cfg.core.mfc_debug && raddr; - const bool is_spurs_task_wait = pc == 0x11e4 && group->max_run != group->max_num && spurs_addr != 0u - 0x80 && !spurs_waited; + const bool is_spurs_task_wait = pc == 0x11e4 && spurs_addr == raddr && group->max_run != group->max_num && !spurs_waited; if (is_spurs_task_wait) { - const u32 prev_running = group->spurs_running; - // Wait for other threads to complete their tasks (temporarily) - if (!is_stopped()) + const u32 max_run = group->max_run; + + u32 prev_running = group->spurs_running; + + if (prev_running > max_run) { - const u32 max_run = group->max_run; + const u64 before = get_system_time(); + u64 current = before; - u32 prev_running = group->spurs_running; - - if (prev_running > max_run) + while (true) { - const u64 before = get_system_time(); - - spurs_waited = true; - - while (true) + if (is_stopped()) { - thread_ctrl::wait_on(group->spurs_running, prev_running, 10000); + break; + } - if (is_stopped()) - { - break; - } + thread_ctrl::wait_on(group->spurs_running, prev_running, 20000 - (current - before)); - prev_running = group->spurs_running; + prev_running = group->spurs_running; - if (prev_running <= max_run) - { - break; - } + if (prev_running <= max_run) + { + break; + } - if (get_system_time() - before >= 4000) - { - // Timed-out - break; - } + current = get_system_time(); + + if (current - before >= 18000u) + { + // Timed-out + break; } } } @@ -5539,7 +5535,7 @@ s64 spu_thread::get_ch_value(u32 ch) case SPU_RdEventStat: { - const bool is_spurs_task_wait = pc == 0x11a8 && group->max_run != group->max_num && spurs_addr == raddr && !spurs_waited; + const bool is_spurs_task_wait = pc == 0x11a8 && spurs_addr == raddr && group->max_run != group->max_num && !spurs_waited; if (is_spurs_task_wait) { @@ -5556,7 +5552,7 @@ s64 spu_thread::get_ch_value(u32 ch) if (prev_running == group->max_run) { - group->spurs_running.notify_all(); + group->spurs_running.notify_one(); } } @@ -5573,9 +5569,9 @@ s64 spu_thread::get_ch_value(u32 ch) { const u32 max_run = group->max_run; - u32 prev_running = group->spurs_running.fetch_op([max = max_run](u32& x) + u32 prev_running = group->spurs_running.fetch_op([max_run](u32& x) { - if (x < max) + if (x < max_run) { x++; return true; @@ -5587,18 +5583,19 @@ s64 spu_thread::get_ch_value(u32 ch) if (prev_running >= max_run) { const u64 before = get_system_time(); + u64 current = before; spurs_waited = true; while (true) { - thread_ctrl::wait_on(group->spurs_running, prev_running, 10000); - if (is_stopped()) { break; } + thread_ctrl::wait_on(group->spurs_running, prev_running, 20000 - (current - before)); + prev_running = group->spurs_running.fetch_op([max_run](u32& x) { if (x < max_run) @@ -5615,7 +5612,9 @@ s64 spu_thread::get_ch_value(u32 ch) break; } - if (get_system_time() - before >= 4000) + current = get_system_time(); + + if (current - before >= 18000u) { // Timed-out group->spurs_running++;