summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Morph2022-08-01 23:34:34 -0400
committerGravatar Morph2022-08-02 01:01:54 -0400
commit606cdb17d3b8f3b4898c1f0a87691058074ad11a (patch)
tree5ca1a2beadc9c9b856ec04cd89cf12fc94f16853
parentAdd missing looping event schedule signal (diff)
downloadyuzu-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.cpp25
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()) {