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.
This commit is contained in:
51
src/Ryujinx.Common/PreciseSleep/SleepEvent.cs
Normal file
51
src/Ryujinx.Common/PreciseSleep/SleepEvent.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Common.PreciseSleep
|
||||
{
|
||||
/// <summary>
|
||||
/// A cross-platform precise sleep event that has millisecond granularity.
|
||||
/// </summary>
|
||||
internal class SleepEvent : IPreciseSleepEvent
|
||||
{
|
||||
private readonly AutoResetEvent _waitEvent = new(false);
|
||||
|
||||
public long AdjustTimePoint(long timePoint, long timeoutNs)
|
||||
{
|
||||
// No adjustment
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
public bool SleepUntil(long timePoint)
|
||||
{
|
||||
long now = PerformanceCounter.ElapsedTicks;
|
||||
long ms = Math.Min((timePoint - now) / PerformanceCounter.TicksPerMillisecond, int.MaxValue);
|
||||
|
||||
if (ms > 0)
|
||||
{
|
||||
_waitEvent.WaitOne((int)ms);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Sleep()
|
||||
{
|
||||
_waitEvent.WaitOne();
|
||||
}
|
||||
|
||||
public void Signal()
|
||||
{
|
||||
_waitEvent.Set();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
_waitEvent.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user