mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 14:01:25 +12:00
SPU: Fix minor race in sys_spu_thread_receive_event
Check final cpu_state::state value for suspend state because that's the variable the thread waits on.
This commit is contained in:
parent
9a981b5292
commit
a3007e11ca
1 changed files with 21 additions and 10 deletions
|
@ -4778,12 +4778,10 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// Check group status, wait if necessary
|
// Check group status (by actually checking thread status), wait if necessary
|
||||||
for (auto _state = +group->run_state;
|
while (true)
|
||||||
_state >= SPU_THREAD_GROUP_STATUS_WAITING && _state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED;
|
|
||||||
_state = group->run_state)
|
|
||||||
{
|
{
|
||||||
const auto old = state.load();
|
const auto old = +state;
|
||||||
|
|
||||||
if (is_stopped(old))
|
if (is_stopped(old))
|
||||||
{
|
{
|
||||||
|
@ -4791,7 +4789,13 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_ctrl::wait_on(state, old);;
|
if (!is_paused(old))
|
||||||
|
{
|
||||||
|
// The group is not suspended (anymore)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_ctrl::wait_on(state, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader_lock{group->mutex}, queue = get_queue(spuq);
|
reader_lock{group->mutex}, queue = get_queue(spuq);
|
||||||
|
@ -4819,6 +4823,7 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||||
if (group->run_state >= SPU_THREAD_GROUP_STATUS_WAITING && group->run_state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED)
|
if (group->run_state >= SPU_THREAD_GROUP_STATUS_WAITING && group->run_state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED)
|
||||||
{
|
{
|
||||||
// Try again
|
// Try again
|
||||||
|
ensure(state & cpu_flag::suspend);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4989,19 +4994,25 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
for (auto _state = +group->run_state;
|
// Check group status (by actually checking thread status), wait if necessary
|
||||||
_state >= SPU_THREAD_GROUP_STATUS_WAITING && _state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED;
|
while (true)
|
||||||
_state = group->run_state)
|
|
||||||
{
|
{
|
||||||
const auto old = +state;
|
const auto old = +state;
|
||||||
|
|
||||||
if (is_stopped(old))
|
if (is_stopped(old))
|
||||||
{
|
{
|
||||||
ch_out_mbox.set_value(value);
|
ch_out_mbox.set_value(value);
|
||||||
|
state += cpu_flag::again;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_ctrl::wait_on(state, old);;
|
if (!is_paused(old))
|
||||||
|
{
|
||||||
|
// The group is not suspended (anymore)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_ctrl::wait_on(state, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(group->mutex);
|
std::lock_guard lock(group->mutex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue