Savestates: Fix saving sys_event_queue_destroy

This commit is contained in:
Eladash 2022-07-07 05:03:16 +03:00 committed by Ivan
parent 0c7ecdc954
commit f0c71ae2ae
3 changed files with 28 additions and 15 deletions

View File

@ -1330,7 +1330,6 @@ static u32 spu_rdch(spu_thread* _spu, u32 ch)
if (result < 0 || _spu->state & cpu_flag::again)
{
_spu->state += cpu_flag::again;
spu_runtime::g_escape(_spu);
}
@ -2269,7 +2268,6 @@ static void spu_wrch_mfc(spu_thread* _spu)
{
if (!_spu->process_mfc_cmd() || _spu->state & cpu_flag::again)
{
_spu->state += cpu_flag::again;
spu_runtime::g_escape(_spu);
}

View File

@ -5588,7 +5588,6 @@ public:
if (result < 0 || _spu->state & cpu_flag::again)
{
_spu->state += cpu_flag::again;
spu_runtime::g_escape(_spu);
}
@ -5882,7 +5881,6 @@ public:
{
if (!_spu->set_ch_value(ch, value) || _spu->state & cpu_flag::again)
{
_spu->state += cpu_flag::again;
spu_runtime::g_escape(_spu);
}
@ -5906,7 +5904,6 @@ public:
{
if (!_spu->process_mfc_cmd() || _spu->state & cpu_flag::again)
{
_spu->state += cpu_flag::again;
spu_runtime::g_escape(_spu);
}

View File

@ -235,21 +235,17 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
std::vector<lv2_event> events;
std::unique_lock<shared_mutex> qlock;
const auto queue = idm::withdraw<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) -> CellError
{
std::lock_guard lock(queue.mutex);
qlock.lock(queue.mutex);
if (!mode && !queue.sq.empty())
{
return CELL_EBUSY;
}
if (queue.sq.empty())
{
// Optimization
mode = 0;
}
if (!queue.events.empty())
{
// Copy events for logging, does not empty
@ -257,6 +253,23 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
}
lv2_obj::on_id_destroy(queue, queue.key);
if (queue.sq.empty())
{
qlock.unlock();
}
else
{
for (auto cpu : queue.sq)
{
if (cpu->state & cpu_flag::again)
{
ppu.state += cpu_flag::again;
return CELL_EAGAIN;
}
}
}
return {};
});
@ -265,6 +278,11 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
return CELL_ESRCH;
}
if (ppu.state & cpu_flag::again)
{
return {};
}
if (queue.ret)
{
return queue.ret;
@ -272,12 +290,10 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
std::string lost_data;
if (mode == SYS_EVENT_QUEUE_DESTROY_FORCE)
if (qlock.owns_lock())
{
std::deque<cpu_thread*> sq;
std::lock_guard lock(queue->mutex);
sq = std::move(queue->sq);
if (sys_event.warning)
@ -309,6 +325,8 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
resume_spu_thread_group_from_waiting(static_cast<spu_thread&>(*cpu));
}
}
qlock.unlock();
}
if (sys_event.warning)