mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
Wait for SPU event to be received in sys_spu_thread_group_exit
Also use atomic check for group->run_state outside the mutex, explicitly forbid group termination while we are waiting for an event to be received.
This commit is contained in:
parent
a9c18964b6
commit
7da8ba5c15
@ -2798,7 +2798,9 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||
queue.reset();
|
||||
|
||||
// Check group status, wait if necessary
|
||||
while (group->run_state >= SPU_THREAD_GROUP_STATUS_WAITING && group->run_state <= SPU_THREAD_GROUP_STATUS_SUSPENDED)
|
||||
for (auto _state = +group->run_state;
|
||||
_state >= SPU_THREAD_GROUP_STATUS_WAITING && _state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED;
|
||||
_state = group->run_state)
|
||||
{
|
||||
if (is_stopped())
|
||||
{
|
||||
@ -2876,11 +2878,14 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (is_stopped())
|
||||
if (state & (cpu_flag::exit + cpu_flag::dbg_global_stop))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// The thread group cannot be stopped while waiting for an event
|
||||
verify(HERE), !(state & cpu_flag::stop);
|
||||
|
||||
if (!state.test_and_reset(cpu_flag::signal))
|
||||
{
|
||||
thread_ctrl::wait();
|
||||
@ -3001,19 +3006,42 @@ bool spu_thread::stop_and_signal(u32 code)
|
||||
|
||||
spu_log.trace("sys_spu_thread_group_exit(status=0x%x)", value);
|
||||
|
||||
std::lock_guard lock(group->mutex);
|
||||
|
||||
for (auto& thread : group->threads)
|
||||
while (true)
|
||||
{
|
||||
if (thread && thread.get() != this)
|
||||
for (auto _state = +group->run_state;
|
||||
_state >= SPU_THREAD_GROUP_STATUS_WAITING && _state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED;
|
||||
_state = group->run_state)
|
||||
{
|
||||
thread->state += cpu_flag::stop;
|
||||
thread_ctrl::notify(*thread);
|
||||
}
|
||||
}
|
||||
if (is_stopped())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
group->exit_status = value;
|
||||
group->join_state = SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT;
|
||||
thread_ctrl::wait();
|
||||
}
|
||||
|
||||
std::lock_guard lock(group->mutex);
|
||||
|
||||
if (auto _state = +group->run_state;
|
||||
_state >= SPU_THREAD_GROUP_STATUS_WAITING && _state <= SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED)
|
||||
{
|
||||
// We can't exit while we are waiting on an SPU event
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto& thread : group->threads)
|
||||
{
|
||||
if (thread && thread.get() != this)
|
||||
{
|
||||
thread->state += cpu_flag::stop;
|
||||
thread_ctrl::notify(*thread);
|
||||
}
|
||||
}
|
||||
|
||||
group->exit_status = value;
|
||||
group->join_state = SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT;
|
||||
break;
|
||||
}
|
||||
|
||||
state += cpu_flag::stop;
|
||||
check_state();
|
||||
|
Loading…
Reference in New Issue
Block a user