SPU: Improved GETLLAR spin detection conditions

This commit is contained in:
elad335 2025-05-13 17:32:12 +03:00 committed by Elad
parent a9b911750f
commit 208c4e2af2
2 changed files with 22 additions and 0 deletions

View file

@ -4781,6 +4781,26 @@ bool spu_thread::process_mfc_cmd()
return true;
}
if (last_getllar != pc || last_getllar_lsa != ch_mfc_cmd.lsa)
{
getllar_busy_waiting_switch = umax;
getllar_spin_count = 0;
return true;
}
// Check if LSA points to an OUT buffer on the stack from a caller - unlikely to be a loop
if (last_getllar_lsa >= SPU_LS_SIZE - 0x10000 && last_getllar_lsa > last_getllar_gpr1)
{
auto cs = dump_callstack_list();
if (!cs.empty() && last_getllar_lsa > cs[0].second)
{
getllar_busy_waiting_switch = umax;
getllar_spin_count = 0;
return true;
}
}
getllar_spin_count = std::min<u32>(getllar_spin_count + 1, u16{umax});
if (getllar_busy_waiting_switch == umax && getllar_spin_count == 4)
@ -4826,6 +4846,7 @@ bool spu_thread::process_mfc_cmd()
last_getllar = pc;
last_getllar_gpr1 = gpr[1]._u32[3];
last_getllar_lsa = ch_mfc_cmd.lsa;
if (getllar_busy_waiting_switch == 1)
{

View file

@ -802,6 +802,7 @@ public:
u32 last_getllar = umax; // LS address of last GETLLAR (if matches current GETLLAR we can let the thread rest)
u32 last_getllar_gpr1 = umax;
u32 last_getllar_addr = umax;
u32 last_getllar_lsa = umax;
u32 getllar_spin_count = 0;
u32 getllar_busy_waiting_switch = umax; // umax means the test needs evaluation, otherwise it's a boolean
u64 getllar_evaluate_time = 0;