Savestates/sys_spu: Minor fix in saving sys_spu_thread_receive_event

This commit is contained in:
Eladash 2022-07-09 17:35:02 +03:00 committed by Ivan
parent 2cead6f328
commit befd7ceb89
3 changed files with 27 additions and 25 deletions

View File

@ -4811,6 +4811,7 @@ bool spu_thread::stop_and_signal(u32 code)
{
queue->sq.emplace_back(this);
group->run_state = SPU_THREAD_GROUP_STATUS_WAITING;
group->waiter_spu_index = index;
for (auto& thread : group->threads)
{

View File

@ -228,19 +228,35 @@ lv2_spu_group::lv2_spu_group(utils::serial& ar) noexcept
*ep = idm::get_unlocked<lv2_obj, lv2_event_queue>(ar.operator u32());
}
u32 waiter_spu_index = -1;
switch (run_state)
{
// Commented stuff are handled by different means currently
//case SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED:
//case SPU_THREAD_GROUP_STATUS_INITIALIZED:
//case SPU_THREAD_GROUP_STATUS_READY:
//case SPU_THREAD_GROUP_STATUS_WAITING:
case SPU_THREAD_GROUP_STATUS_WAITING:
{
run_state = SPU_THREAD_GROUP_STATUS_RUNNING;
ar(waiter_spu_index);
[[fallthrough]];
}
case SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED:
{
if (run_state == SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED)
{
run_state = SPU_THREAD_GROUP_STATUS_SUSPENDED;
}
[[fallthrough]];
}
case SPU_THREAD_GROUP_STATUS_SUSPENDED:
{
// Suspend all SPU threads
// Suspend all SPU threads except a thread that waits on sys_spu_thread_receive_event
for (const auto& thread : threads)
{
if (thread)
if (thread && thread->index != waiter_spu_index)
{
thread->state += cpu_flag::suspend;
}
@ -263,28 +279,7 @@ void lv2_spu_group::save(utils::serial& ar)
{
USING_SERIALIZATION_VERSION(spu);
spu_group_status _run_state = run_state;
switch (_run_state)
{
// Commented stuff are handled by different means currently
//case SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED:
//case SPU_THREAD_GROUP_STATUS_INITIALIZED:
//case SPU_THREAD_GROUP_STATUS_READY:
// Waiting SPU should recover this
case SPU_THREAD_GROUP_STATUS_WAITING: _run_state = SPU_THREAD_GROUP_STATUS_RUNNING; break;
case SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED: _run_state = SPU_THREAD_GROUP_STATUS_SUSPENDED; break;
//case SPU_THREAD_GROUP_STATUS_RUNNING:
//case SPU_THREAD_GROUP_STATUS_STOPPED:
//case SPU_THREAD_GROUP_STATUS_UNKNOWN:
default:
{
break;
}
}
ar(name, max_num, mem_size, type, ct->id, has_scheduler_context, max_run, init, prio, _run_state, exit_status);
ar(name, max_num, mem_size, type, ct->id, has_scheduler_context, max_run, init, prio, run_state, exit_status);
for (const auto& thread : threads)
{
@ -305,6 +300,11 @@ void lv2_spu_group::save(utils::serial& ar)
{
ar(lv2_obj::check(*ep) ? (*ep)->id : 0);
}
if (run_state == SPU_THREAD_GROUP_STATUS_WAITING)
{
ar(waiter_spu_index);
}
}
lv2_spu_image::lv2_spu_image(utils::serial& ar)

View File

@ -290,6 +290,7 @@ struct lv2_spu_group
atomic_t<u32> join_state; // flags used to detect exit cause and signal
atomic_t<u32> running = 0; // Number of running threads
atomic_t<u64> stop_count = 0;
u32 waiter_spu_index = -1; // Index of SPU executing a waiting syscall
class ppu_thread* waiter = nullptr;
bool set_terminate = false;