From 93a0d503841349a7cd41cc8d4e5df6136cf99dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2026 11:36:22 -0600 Subject: [PATCH] CoreTiming: An event due before the slice ends shortens it Each slice is sized to end at the next queued event, but scheduling a sooner one didn't touch it, so the new event waited for the old slice to run out. An alarm set by a thread that kept running went off 175-440us late. GE enqueues worked around this with hleCoreTimingForceCheck(); now every caller gets it. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/CoreTiming.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index df8ab549d7..2acd71c90a 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include #include #include @@ -289,6 +290,15 @@ void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata) ne->type = event_type; ne->time = GetTicks(currentMIPS) + cyclesIntoFuture; AddEventToQueue(ne); + + // The slice was sized to end at the next event. If this one is due sooner, end it there, or it + // fires late: an alarm set by a thread that keeps running went off hundreds of us late + // (pspautotests threads/scheduling/alarmcosts). + if (cyclesIntoFuture < currentMIPS->downcount) { + const int diff = (int)std::max(cyclesIntoFuture, 0) - currentMIPS->downcount; + slicelength += diff; + currentMIPS->downcount += diff; + } } // Returns cycles left in timer.