diff --git a/src/common/threads.cpp b/src/common/threads.cpp index c83bf9488..c0b4bbe82 100644 --- a/src/common/threads.cpp +++ b/src/common/threads.cpp @@ -28,7 +28,8 @@ #ifdef KYTY_WIN_CS #include // IWYU pragma: keep // IWYU pragma: no_include -constexpr DWORD KYTY_CS_SPIN_COUNT = 4000; +constexpr DWORD KYTY_CS_SPIN_COUNT = 4000; +constexpr uint64_t KYTY_SLEEP_SPIN_LIMIT_100NS = 500; // 50 us #ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION #define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 @@ -39,7 +40,10 @@ static void SleepHighResolution100ns(uint64_t units_100ns) { return; } - if (units_100ns <= 10000) { + // Keep spinning only where a kernel transition is + // likely to cost more than the requested delay; ordinary millisecond sleeps use the + // per-thread high-resolution waitable timer below. + if (units_100ns <= KYTY_SLEEP_SPIN_LIMIT_100NS) { LARGE_INTEGER frequency {}; LARGE_INTEGER start {}; if (QueryPerformanceFrequency(&frequency) != 0 && QueryPerformanceCounter(&start) != 0 && diff --git a/src/graphics/presentation/videoOut.cpp b/src/graphics/presentation/videoOut.cpp index eaa0fae24..cf0d4f280 100644 --- a/src/graphics/presentation/videoOut.cpp +++ b/src/graphics/presentation/videoOut.cpp @@ -788,14 +788,10 @@ void VideoOutDriver::Impl::PresentThread(std::stop_token token) { while (!token.stop_requested()) { const auto sleep_begin = Common::Timer::QueryPerformanceCounter(); if (total_wait > 0) { - const auto sleep_end = sleep_begin + static_cast(total_wait); - auto now = sleep_begin; - while (!token.stop_requested() && now < sleep_end) { - const auto remaining_us = (sleep_end - now) * 1000000u / frequency; - Common::Thread::SleepMicro( - static_cast(std::clamp(remaining_us, 1, 1000))); - now = Common::Timer::QueryPerformanceCounter(); - } + const auto remaining_us = + (static_cast(total_wait) * 1000000u + frequency - 1) / frequency; + Common::Thread::SleepMicro(static_cast( + std::clamp(remaining_us, 1, std::numeric_limits::max()))); } if (token.stop_requested()) { break; diff --git a/src/graphics/presentation/window/window.cpp b/src/graphics/presentation/window/window.cpp index 5fc94b8ae..fcffa0dc8 100644 --- a/src/graphics/presentation/window/window.cpp +++ b/src/graphics/presentation/window/window.cpp @@ -752,26 +752,18 @@ void WindowContext::Run() { #if defined(__APPLE__) DrainMainThreadTasks(); #endif - if (SDL_PollEvent(&loop.event) != 0) { - ProcessEvent(timer.GetTimeS()); - continue; - } - if (loop.paused.load(std::memory_order_acquire)) { if (!timer.IsPaused()) { timer.Pause(); } - if (SDL_WaitEvent(&loop.event) == 0) { - EXIT("%s\n", SDL_GetError()); - } - ProcessEvent(timer.GetTimeS()); - continue; - } - - if (timer.IsPaused()) { + } else if (timer.IsPaused()) { timer.Resume(); } - Common::Thread::SleepMicro(1000); + + if (SDL_WaitEvent(&loop.event) == 0) { + EXIT("%s\n", SDL_GetError()); + } + ProcessEvent(timer.GetTimeS()); } }