From 1be668e68a1937f2af239e2707ab914286018892 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Thu, 30 Nov 2023 10:39:42 -0800 Subject: HLE: Add OS-specific precise sleep methods to reduce spinwaiting (#5948) * feat: add nanosleep for linux and macos * Add Windows 0.5ms sleep - Imprecise waits for longer waits with clock alignment - 1/4 the spin time on vsync timer * Remove old experiment * Fix event leak * Tweaking for MacOS * Linux tweaks, nanosleep vsync improvement * Fix overbias * Cleanup * Fix realignment * Add some docs and some cleanup NanosleepPool needs more, Nanosleep has some benchmark code that needs removed. * Rename "Microsleep" to "PreciseSleep" Might have been confused with "microseconds", which no measurement is performed in. * Remove nanosleep measurement * Remove unused debug logging * Nanosleep Pool Documentation * More cleanup * Whitespace * Formatting * Address Feedback * Allow SleepUntilTimePoint to take EventWaitHandle * Remove `_chrono` stopwatch in SurfaceFlinger * Move spinwaiting logic to PreciseSleepHelper Technically, these achieve different things, but having them here makes them easier to reuse or tune. --- .../PreciseSleep/IPreciseSleepEvent.cs | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/Ryujinx.Common/PreciseSleep/IPreciseSleepEvent.cs (limited to 'src/Ryujinx.Common/PreciseSleep/IPreciseSleepEvent.cs') diff --git a/src/Ryujinx.Common/PreciseSleep/IPreciseSleepEvent.cs b/src/Ryujinx.Common/PreciseSleep/IPreciseSleepEvent.cs new file mode 100644 index 00000000..26b5ab68 --- /dev/null +++ b/src/Ryujinx.Common/PreciseSleep/IPreciseSleepEvent.cs @@ -0,0 +1,38 @@ +using System; + +namespace Ryujinx.Common.PreciseSleep +{ + /// + /// An event which works similarly to an AutoResetEvent, but is backed by a + /// more precise timer that allows waits of less than a millisecond. + /// + public interface IPreciseSleepEvent : IDisposable + { + /// + /// Adjust a timepoint to better fit the host clock. + /// When no adjustment is made, the input timepoint will be returned. + /// + /// Timepoint to adjust + /// Requested timeout in nanoseconds + /// Adjusted timepoint + long AdjustTimePoint(long timePoint, long timeoutNs); + + /// + /// Sleep until a timepoint, or a signal is received. + /// Given no signal, may wake considerably before, or slightly after the timeout. + /// + /// Timepoint to sleep until + /// True if signalled or waited, false if a wait could not be performed + bool SleepUntil(long timePoint); + + /// + /// Sleep until a signal is received. + /// + void Sleep(); + + /// + /// Signal the event, waking any sleeping thread or the next attempted sleep. + /// + void Signal(); + } +} -- cgit v1.2.3