Kernel.Equeue: Only reset trigger state on events that clear. (#4032)
Some checks failed
Build and Release / reuse (push) Has been cancelled
Build and Release / clang-format (push) Has been cancelled
Build and Release / get-info (push) Has been cancelled
Build and Release / windows-sdl (push) Has been cancelled
Build and Release / macos-sdl (push) Has been cancelled
Build and Release / linux-sdl (push) Has been cancelled
Build and Release / linux-sdl-gcc (push) Has been cancelled
Build and Release / pre-release (push) Has been cancelled

* 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.
This commit is contained in:
Stephen Miller 2026-02-13 17:59:23 -06:00 committed by GitHub
parent d189b0cc29
commit e0850d5cfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 8 deletions

View File

@ -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();
}

View File

@ -84,11 +84,8 @@ struct EqueueEvent {
std::chrono::microseconds timer_interval;
std::unique_ptr<boost::asio::steady_timer> timer;
void ResetTriggerState() {
is_triggered = false;
}
void Clear() {
is_triggered = false;
event.fflags = 0;
event.data = 0;
}