From e0850d5cfc4105abed3dff404a5c744c756bb049 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Fri, 13 Feb 2026 17:59:23 -0600 Subject: [PATCH] Kernel.Equeue: Only reset trigger state on events that clear. (#4032) * Don't clear events that don't need clearing Unless the event has the clear flag, it will be returned multiple times after triggering. * Fix event flags As older code suggests, the PS4 kernel does append the clear flag to various event types internally. This is visible when observing the returned event data from sceKernelWaitEqueue (or kevent, if you're feeling ambitious) Add flag is also removed from events internally. --- src/core/libraries/kernel/equeue.cpp | 12 ++++++++---- src/core/libraries/kernel/equeue.h | 5 +---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index 2190f2533..72e38b265 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -32,6 +32,14 @@ bool EqueueInternal::AddEvent(EqueueEvent& event) { event.timer_interval = std::chrono::microseconds(event.event.data - offset); } + // Remove add flag from event + event.event.flags &= ~SceKernelEvent::Flags::Add; + + // Clear flag is appended to most event types internally. + if (event.event.filter != SceKernelEvent::Filter::User) { + event.event.flags |= SceKernelEvent::Flags::Clear; + } + const auto& it = std::ranges::find(m_events, event); if (it != m_events.cend()) { *it = std::move(event); @@ -165,10 +173,6 @@ int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) { for (auto it = m_events.begin(); it != m_events.end();) { if (it->IsTriggered()) { ev[count++] = it->event; - - // Event should not trigger again - it->ResetTriggerState(); - if (it->event.flags & SceKernelEvent::Flags::Clear) { it->Clear(); } diff --git a/src/core/libraries/kernel/equeue.h b/src/core/libraries/kernel/equeue.h index e933f80d1..332aa15c2 100644 --- a/src/core/libraries/kernel/equeue.h +++ b/src/core/libraries/kernel/equeue.h @@ -84,11 +84,8 @@ struct EqueueEvent { std::chrono::microseconds timer_interval; std::unique_ptr timer; - void ResetTriggerState() { - is_triggered = false; - } - void Clear() { + is_triggered = false; event.fflags = 0; event.data = 0; }