mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 14:31:24 +12:00
RawSPU: fix race condition in RunCntl stop request
This commit is contained in:
parent
ef6854ca46
commit
c11074a128
3 changed files with 31 additions and 5 deletions
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
inline void try_start(spu_thread& spu)
|
inline void try_start(spu_thread& spu)
|
||||||
{
|
{
|
||||||
|
std::shared_lock lock(spu.run_ctrl_mtx);
|
||||||
|
|
||||||
if (spu.status_npc.fetch_op([](typename spu_thread::status_npc_sync_var& value)
|
if (spu.status_npc.fetch_op([](typename spu_thread::status_npc_sync_var& value)
|
||||||
{
|
{
|
||||||
if (value.status & SPU_STATUS_RUNNING)
|
if (value.status & SPU_STATUS_RUNNING)
|
||||||
|
@ -246,8 +248,24 @@ bool spu_thread::write_reg(const u32 addr, const u32 value)
|
||||||
}
|
}
|
||||||
else if (value == SPU_RUNCNTL_STOP_REQUEST)
|
else if (value == SPU_RUNCNTL_STOP_REQUEST)
|
||||||
{
|
{
|
||||||
// TODO: Wait for the SPU to stop?
|
if (get_current_cpu_thread() == this)
|
||||||
state += cpu_flag::stop;
|
{
|
||||||
|
// TODO
|
||||||
|
state += cpu_flag::stop;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::scoped_lock lock(run_ctrl_mtx);
|
||||||
|
|
||||||
|
if (status_npc.load().status & SPU_STATUS_RUNNING)
|
||||||
|
{
|
||||||
|
state += cpu_flag::stop;
|
||||||
|
|
||||||
|
for (status_npc_sync_var old; (old = status_npc).status & SPU_STATUS_RUNNING;)
|
||||||
|
{
|
||||||
|
status_npc.wait(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1096,19 +1096,22 @@ void spu_thread::cpu_stop()
|
||||||
{
|
{
|
||||||
if (!group && offset >= RAW_SPU_BASE_ADDR)
|
if (!group && offset >= RAW_SPU_BASE_ADDR)
|
||||||
{
|
{
|
||||||
status_npc.fetch_op([this](status_npc_sync_var& state)
|
if (status_npc.fetch_op([this](status_npc_sync_var& state)
|
||||||
{
|
{
|
||||||
if (state.status & SPU_STATUS_RUNNING)
|
if (state.status & SPU_STATUS_RUNNING)
|
||||||
{
|
{
|
||||||
// Save next PC and current SPU Interrupt Status
|
// Save next PC and current SPU Interrupt Status
|
||||||
// Used only by RunCtrl stop requests
|
// Used only by RunCtrl stop requests
|
||||||
state.status &= ~SPU_STATUS_RUNNING;
|
state.status &= ~SPU_STATUS_RUNNING;
|
||||||
state.npc = pc | +interrupts_enabled;
|
state.npc = pc | +interrupts_enabled;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
}).second)
|
||||||
|
{
|
||||||
|
status_npc.notify_one();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (group && is_stopped())
|
else if (group && is_stopped())
|
||||||
{
|
{
|
||||||
|
@ -2842,6 +2845,8 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||||
state.npc = (pc + 4) | +interrupts_enabled;
|
state.npc = (pc + 4) | +interrupts_enabled;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
status_npc.notify_one();
|
||||||
|
|
||||||
int_ctrl[2].set(SPU_INT2_STAT_SPU_STOP_AND_SIGNAL_INT);
|
int_ctrl[2].set(SPU_INT2_STAT_SPU_STOP_AND_SIGNAL_INT);
|
||||||
check_state();
|
check_state();
|
||||||
return true;
|
return true;
|
||||||
|
@ -3196,6 +3201,8 @@ void spu_thread::halt()
|
||||||
state.npc = pc | +interrupts_enabled;
|
state.npc = pc | +interrupts_enabled;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
status_npc.notify_one();
|
||||||
|
|
||||||
int_ctrl[2].set(SPU_INT2_STAT_SPU_HALT_OR_STEP_INT);
|
int_ctrl[2].set(SPU_INT2_STAT_SPU_HALT_OR_STEP_INT);
|
||||||
|
|
||||||
spu_runtime::g_escape(this);
|
spu_runtime::g_escape(this);
|
||||||
|
|
|
@ -580,6 +580,7 @@ public:
|
||||||
u32 ch_dec_value; // written decrementer value
|
u32 ch_dec_value; // written decrementer value
|
||||||
|
|
||||||
atomic_t<u32> run_ctrl; // SPU Run Control register (only provided to get latest data written)
|
atomic_t<u32> run_ctrl; // SPU Run Control register (only provided to get latest data written)
|
||||||
|
shared_mutex run_ctrl_mtx;
|
||||||
|
|
||||||
struct alignas(8) status_npc_sync_var
|
struct alignas(8) status_npc_sync_var
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue