From 0a668ba1fec51eb1563d91a6387bb61ea687cb17 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sun, 9 Jul 2023 21:17:32 +0200 Subject: [PATCH] Use clock BOOTTIME for thread::sleep on linux Thread::sleep uses nanosleep. Nanosleep uses the MONOTONIC clock. That clock does not take suspend time into account. Since kernel commit d6ed449 the MONOTONIC clock behaves the same as the BOOTTIME clock. The BOOTTIME clock does count time spend suspended. Commit d6ed449 was merged somewhere between v4.14 and v4.19. Rust supports kernels before and after that. This commit changes sleep to use the BOOTTIME clock on linux targes. This makes sleep behave consistently on linux regardless of kernel version. --- library/std/src/sys/unix/thread.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 893f8b8df3f54..b1d4f3514d72c 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -233,7 +233,14 @@ impl Thread { }; secs -= ts.tv_sec as u64; let ts_ptr = &mut ts as *mut _; - if libc::nanosleep(ts_ptr, ts_ptr) == -1 { + // Since linux kernel d6ed449 (v >~ 4.19) the MONOTONIC clock + // used by nanosleep behaves like the BOOTTIME clock. + // Ensures sleep behaves the same on linux regardless of kernel. + #[cfg(target_os = "linux")] + let ret = libc::clock_nanosleep(libc::CLOCK_BOOTTIME, 0, ts_ptr, ts_ptr); + #[cfg(not(target_os = "linux"))] + let ret = libc::nanosleep(ts_ptr, ts_ptr); + if ret == -1 { assert_eq!(os::errno(), libc::EINTR); secs += ts.tv_sec as u64; nsecs = ts.tv_nsec;