Ryujinx/src/Ryujinx.Common/PreciseSleep/IPreciseSleepEvent.cs
riperiperi 1be668e68a
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.
2023-11-30 15:39:42 -03:00

38 lines
1.4 KiB
C#

using System;
namespace Ryujinx.Common.PreciseSleep
{
/// <summary>
/// An event which works similarly to an AutoResetEvent, but is backed by a
/// more precise timer that allows waits of less than a millisecond.
/// </summary>
public interface IPreciseSleepEvent : IDisposable
{
/// <summary>
/// Adjust a timepoint to better fit the host clock.
/// When no adjustment is made, the input timepoint will be returned.
/// </summary>
/// <param name="timePoint">Timepoint to adjust</param>
/// <param name="timeoutNs">Requested timeout in nanoseconds</param>
/// <returns>Adjusted timepoint</returns>
long AdjustTimePoint(long timePoint, long timeoutNs);
/// <summary>
/// Sleep until a timepoint, or a signal is received.
/// Given no signal, may wake considerably before, or slightly after the timeout.
/// </summary>
/// <param name="timePoint">Timepoint to sleep until</param>
/// <returns>True if signalled or waited, false if a wait could not be performed</returns>
bool SleepUntil(long timePoint);
/// <summary>
/// Sleep until a signal is received.
/// </summary>
void Sleep();
/// <summary>
/// Signal the event, waking any sleeping thread or the next attempted sleep.
/// </summary>
void Signal();
}
}