mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 07:21:25 +12:00
SPU: Fix spu_thread::cpu_stop() missed executions (#8656)
This commit is contained in:
parent
ebf832214e
commit
82068cf802
6 changed files with 23 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue