diff options
| author | 2022-08-01 23:34:34 -0400 | |
|---|---|---|
| committer | 2022-08-02 01:01:54 -0400 | |
| commit | 606cdb17d3b8f3b4898c1f0a87691058074ad11a (patch) | |
| tree | 5ca1a2beadc9c9b856ec04cd89cf12fc94f16853 | |
| parent | Add missing looping event schedule signal (diff) | |
| download | yuzu-606cdb17d3b8f3b4898c1f0a87691058074ad11a.tar.gz yuzu-606cdb17d3b8f3b4898c1f0a87691058074ad11a.tar.xz yuzu-606cdb17d3b8f3b4898c1f0a87691058074ad11a.zip | |
core_timing: Sleep in discrete intervals, yield during spin
Diffstat (limited to '')
| -rw-r--r-- | src/core/core_timing.cpp | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index a75bfea60..8d1ee3b51 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -281,20 +281,21 @@ void CoreTiming::ThreadLoop() { | |||
| 281 | paused_set = false; | 281 | paused_set = false; |
| 282 | const auto next_time = Advance(); | 282 | const auto next_time = Advance(); |
| 283 | if (next_time) { | 283 | if (next_time) { |
| 284 | // There are more events left in the queue, sleep until the next event. | 284 | // There are more events left in the queue, wait until the next event. |
| 285 | const auto diff_ns{*next_time - GetGlobalTimeNs().count()}; | 285 | const auto wait_time = *next_time - GetGlobalTimeNs().count(); |
| 286 | if (diff_ns > 0) { | 286 | if (wait_time > 0) { |
| 287 | // Only try to sleep if the remaining time is >= 1ms. Take off 500 microseconds | 287 | // Assume a timer resolution of 1ms. |
| 288 | // from the target time to account for possible over-sleeping, and spin the | 288 | static constexpr s64 TimerResolutionNS = 1000000; |
| 289 | // remaining. | 289 | |
| 290 | const auto sleep_time_ns{diff_ns - 500LL * 1'000LL}; | 290 | // Sleep in discrete intervals of the timer resolution, and spin the rest. |
| 291 | const auto sleep_time_ms{sleep_time_ns / 1'000'000LL}; | 291 | const auto sleep_time = wait_time - (wait_time % TimerResolutionNS); |
| 292 | if (sleep_time_ms >= 1) { | 292 | if (sleep_time > 0) { |
| 293 | event.WaitFor(std::chrono::nanoseconds(sleep_time_ns)); | 293 | event.WaitFor(std::chrono::nanoseconds(sleep_time)); |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | const auto end_time{std::chrono::nanoseconds(*next_time)}; | 296 | while (!paused && !event.IsSet() && GetGlobalTimeNs().count() < *next_time) { |
| 297 | while (!paused && !event.IsSet() && GetGlobalTimeNs() < end_time) { | 297 | // Yield to reduce thread starvation. |
| 298 | std::this_thread::yield(); | ||
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | if (event.IsSet()) { | 301 | if (event.IsSet()) { |