From d85001dddcd30d97aa3e30969c95b80640b63256 Mon Sep 17 00:00:00 2001 From: Fire Cube Date: Mon, 12 May 2025 20:43:16 +0200 Subject: [PATCH] now should be good - fix implementation based on homebrew tests - demote log to debug - make squidbus happy (hopefully) --- src/core/libraries/kernel/equeue.cpp | 48 +++++++++++++++------------- src/core/libraries/kernel/equeue.h | 6 ++-- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index 50823c38a..d3aee8952 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -152,6 +152,16 @@ int EqueueInternal::WaitForSmallTimer(SceKernelEvent* ev, int num, u32 micros) { return count; } +bool EqueueInternal::EventExists(u64 id, s16 filter) { + std::scoped_lock lock{m_mutex}; + + const auto& it = std::ranges::find_if(m_events, [id, filter](auto& ev) { + return ev.event.ident == id && ev.event.filter == filter; + }); + + return it != m_events.cend(); +} + extern boost::asio::io_context io_context; extern void KernelSignalRequest(); @@ -300,28 +310,21 @@ int PS4_SYSV_ABI sceKernelDeleteHRTimerEvent(SceKernelEqueue eq, int id) { } } -extern boost::asio::io_context io_context; - -static bool EventExists(SceKernelEqueue eq, u64 id, s16 filter) { - std::scoped_lock lock{eq->m_mutex}; - - const auto& it = std::ranges::find_if(eq->m_events, [id, filter](auto& ev) { - return ev.event.ident == id && ev.event.filter == filter; - }); - - return it != eq->m_events.cend(); -} - static void TimerCallback(const boost::system::error_code& error, SceKernelEqueue eq, SceKernelEvent kevent, SceKernelUseconds interval_ms) { - if (EventExists(eq, kevent.ident, kevent.filter)) { + if (error) { + LOG_ERROR(Kernel_Event, "Timer callback error: {}", error.message()); + return; + } + + if (eq->EventExists(kevent.ident, kevent.filter)) { eq->TriggerEvent(kevent.ident, SceKernelEvent::Filter::Timer, kevent.udata); if (!(kevent.flags & SceKernelEvent::Flags::OneShot)) { - auto timer = std::make_unique( + auto timer = std::make_shared( io_context, std::chrono::milliseconds(interval_ms)); - timer->async_wait([eq, kevent, interval_ms](const boost::system::error_code& ec) { + timer->async_wait([eq, kevent, interval_ms, timer](const boost::system::error_code& ec) { TimerCallback(ec, eq, kevent, interval_ms); }); } @@ -344,16 +347,19 @@ int PS4_SYSV_ABI sceKernelAddTimerEvent(SceKernelEqueue eq, int id, SceKernelUse event.event.data = interval_ms; event.event.udata = udata; event.time_added = std::chrono::steady_clock::now(); - LOG_INFO(Kernel_Event, - "Added timing event: queue name={}, queue id={}, ms-intevall={}, func pointer={:x}", + LOG_DEBUG(Kernel_Event, + "Added timing event: queue name={}, queue id={}, ms-intevall={}, pointer={:x}", eq->GetName(), event.event.ident, interval_ms, reinterpret_cast(udata)); - event.timer = std::make_unique( + auto timer = std::make_shared( io_context, std::chrono::milliseconds(interval_ms)); - event.timer->async_wait( - [eq, event_data = event.event, interval_ms](const boost::system::error_code& ec) { + KernelSignalRequest(); + std::thread([]() { io_context.run(); }).detach(); + + timer->async_wait( + [eq, event_data = event.event, interval_ms, timer](const boost::system::error_code& ec) { TimerCallback(ec, eq, event_data, interval_ms); }); @@ -361,8 +367,6 @@ int PS4_SYSV_ABI sceKernelAddTimerEvent(SceKernelEqueue eq, int id, SceKernelUse return ORBIS_KERNEL_ERROR_ENOMEM; } - KernelSignalRequest(); - return ORBIS_OK; } diff --git a/src/core/libraries/kernel/equeue.h b/src/core/libraries/kernel/equeue.h index e5847717a..777511f37 100644 --- a/src/core/libraries/kernel/equeue.h +++ b/src/core/libraries/kernel/equeue.h @@ -152,12 +152,12 @@ public: int WaitForSmallTimer(SceKernelEvent* ev, int num, u32 micros); - std::mutex m_mutex; - std::vector m_events; + bool EventExists(u64 id, s16 filter); private: + std::mutex m_mutex; + std::vector m_events; std::string m_name; - EqueueEvent small_timer_event{}; std::condition_variable m_cond; };