SPU: Fix spu_thread::cpu_stop() missed executions (#8656)

This commit is contained in:
Eladash 2020-07-30 12:07:18 +03:00 committed by GitHub
parent ebf832214e
commit 82068cf802
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 12 deletions

View file

@ -433,11 +433,21 @@ void cpu_thread::operator()()
if (!(state & cpu_flag::stop)) if (!(state & cpu_flag::stop))
{ {
cpu_task(); cpu_task();
state -= cpu_flag::ret;
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
{
cpu_return();
}
continue; continue;
} }
thread_ctrl::wait(); thread_ctrl::wait();
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
{
cpu_return();
}
} }
// Complete cleanup gracefully // Complete cleanup gracefully

View file

@ -120,6 +120,9 @@ public:
// Callback for vm::temporary_unlock // Callback for vm::temporary_unlock
virtual void cpu_unmem() {} virtual void cpu_unmem() {}
// Callback for cpu_flag::ret
virtual void cpu_return() {}
// Thread locker // Thread locker
class suspend_all class suspend_all
{ {

View file

@ -262,7 +262,7 @@ bool spu_thread::write_reg(const u32 addr, const u32 value)
if (get_current_cpu_thread() == this) if (get_current_cpu_thread() == this)
{ {
// TODO // TODO
state += cpu_flag::stop; state += cpu_flag::stop + cpu_flag::ret;
return true; return true;
} }
@ -270,7 +270,7 @@ bool spu_thread::write_reg(const u32 addr, const u32 value)
if (status_npc.load().status & SPU_STATUS_RUNNING) if (status_npc.load().status & SPU_STATUS_RUNNING)
{ {
state += cpu_flag::stop; state += cpu_flag::stop + cpu_flag::ret;
for (status_npc_sync_var old; (old = status_npc).status & SPU_STATUS_RUNNING;) for (status_npc_sync_var old; (old = status_npc).status & SPU_STATUS_RUNNING;)
{ {

View file

@ -1006,7 +1006,7 @@ void spu_thread::cpu_init()
gpr[1]._u32[3] = 0x3FFF0; // initial stack frame pointer gpr[1]._u32[3] = 0x3FFF0; // initial stack frame pointer
} }
void spu_thread::cpu_stop() void spu_thread::cpu_return()
{ {
if (get_type() >= spu_type::raw) if (get_type() >= spu_type::raw)
{ {
@ -1150,8 +1150,6 @@ void spu_thread::cpu_task()
spu_runtime::g_interpreter(*this, _ptr<u8>(0), nullptr); spu_runtime::g_interpreter(*this, _ptr<u8>(0), nullptr);
} }
} }
cpu_stop();
} }
void spu_thread::cpu_mem() void spu_thread::cpu_mem()
@ -2959,7 +2957,7 @@ bool spu_thread::stop_and_signal(u32 code)
if (get_type() >= spu_type::raw) if (get_type() >= spu_type::raw)
{ {
// Save next PC and current SPU Interrupt Status // Save next PC and current SPU Interrupt Status
state += cpu_flag::stop + cpu_flag::wait; state += cpu_flag::stop + cpu_flag::wait + cpu_flag::ret;
set_status_npc(); set_status_npc();
status_npc.notify_one(); status_npc.notify_one();
@ -3306,7 +3304,7 @@ bool spu_thread::stop_and_signal(u32 code)
{ {
if (thread && thread.get() != this) if (thread && thread.get() != this)
{ {
thread->state += cpu_flag::stop; thread->state += cpu_flag::stop + cpu_flag::ret;
thread_ctrl::raw_notify(*thread); thread_ctrl::raw_notify(*thread);
} }
} }
@ -3317,7 +3315,7 @@ bool spu_thread::stop_and_signal(u32 code)
break; break;
} }
state += cpu_flag::stop; state += cpu_flag::stop + cpu_flag::ret;
check_state(); check_state();
return true; return true;
} }
@ -3337,7 +3335,7 @@ bool spu_thread::stop_and_signal(u32 code)
spu_log.trace("sys_spu_thread_exit(status=0x%x)", value); spu_log.trace("sys_spu_thread_exit(status=0x%x)", value);
last_exit_status.release(value); last_exit_status.release(value);
set_status_npc(); set_status_npc();
state += cpu_flag::stop; state += cpu_flag::stop + cpu_flag::ret;
check_state(); check_state();
return true; return true;
} }

View file

@ -621,9 +621,9 @@ public:
virtual void cpu_task() override final; virtual void cpu_task() override final;
virtual void cpu_mem() override; virtual void cpu_mem() override;
virtual void cpu_unmem() override; virtual void cpu_unmem() override;
virtual void cpu_return() override;
virtual ~spu_thread() override; virtual ~spu_thread() override;
void cpu_init(); void cpu_init();
void cpu_stop();
static const u32 id_base = 0x02000000; // TODO (used to determine thread type) static const u32 id_base = 0x02000000; // TODO (used to determine thread type)
static const u32 id_step = 1; static const u32 id_step = 1;

View file

@ -1003,7 +1003,7 @@ error_code sys_spu_thread_group_terminate(ppu_thread& ppu, u32 id, s32 value)
{ {
if (thread) if (thread)
{ {
thread->state += cpu_flag::stop; thread->state += cpu_flag::stop + cpu_flag::ret;
} }
} }