@cryptotaxi247 / netdata / commits / e48b6ac2a

Windows: round sleep to clock resolution to prevent sub-ms early-wake logs (#20887)

Windows: round sleep to clock resolution to prevent sub-ms early-wake logs\n\n- Round requested duration up to (1ms with timeBeginPeriod(1))\n- Use a single call; no EINTR-like loop needed on Windows\n- Avoid sub-millisecond under-sleep that caused "woke up earlier than expected" logs under MSYS2\n- Do not busy-wait; no extra now_realtime_usec() call before sleep

Costa Tsaousis committed Aug 25, 2025 at 17:42 UTC e48b6ac2a854af8fc3b1fdf171c468ecd2f38256
1 file changed +16 -15
src/libnetdata/clocks/clocks.c
+16 -15
@@ -421,23 +421,24 @@ usec_t heartbeat_next(heartbeat_t *hb) {
421 }
422
423 #if defined(OS_WINDOWS)
424 -void sleep_usec_with_now(usec_t usec, usec_t started_ut) {
425 - if (!started_ut)
426 - started_ut = now_realtime_usec();
427 -
428 - usec_t end_ut = started_ut + usec;
429 - usec_t remaining_ut = usec;
430 -
431 - while (remaining_ut >= clock_realtime_resolution) {
432 - DWORD sleep_ms = (DWORD) (remaining_ut / USEC_PER_MS);
433 - Sleep(sleep_ms);
424 +void sleep_usec_with_now(usec_t usec, usec_t started_ut __maybe_unused) {
425 + if (usec == 0)
426 + return;
427 +
428 + // Honor Windows timer granularity by rounding the requested duration
429 + // up to the next multiple of the effective clock resolution.
430 + usec_t res_ut = clock_realtime_resolution ? clock_realtime_resolution : USEC_PER_MS;
431 + usec_t to_sleep_ut = usec;
432 + if (res_ut) {
433 + to_sleep_ut = ((to_sleep_ut + res_ut - 1) / res_ut) * res_ut; // round up
434 + }
435
435 - usec_t now_ut = now_realtime_usec();
436 - if (now_ut >= end_ut)
437 - break;
436 + // Convert microseconds to milliseconds for Sleep(), rounding up
437 + DWORD sleep_ms = (DWORD)((to_sleep_ut + (USEC_PER_MS - 1)) / USEC_PER_MS);
438 + if (sleep_ms == 0)
439 + sleep_ms = 1; // safety: always sleep at least 1ms
440
439 - remaining_ut = end_ut - now_ut;
440 - }
441 + Sleep(sleep_ms);
442 }
443 #else
444 void sleep_usec_with_now(usec_t usec, usec_t started_ut) {