From e9bd03fc4b21c4cb06e79403c83a35c29a19c7cd Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 3 Jul 2024 18:44:38 -0400 Subject: [PATCH] use Boottime clock on linux Better to advance while suspended, that way a stale content retention lock will expire while suspended. The fallback the Monotonic to support older kernels assumes that there are not systems where Boottime sometimes succeeds and sometimes fails. If that ever happened, the clock would probably not monotonically advance as it read from different clocks on different calls! I don't see any indication in clock_gettime(2) errono list that it can fail intermittently so probably this is ok. --- Utility/MonotonicClock.hs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Utility/MonotonicClock.hs b/Utility/MonotonicClock.hs index af5c20cd94..1af10187e3 100644 --- a/Utility/MonotonicClock.hs +++ b/Utility/MonotonicClock.hs @@ -14,11 +14,23 @@ import qualified System.Clock as Clock #else import qualified System.Posix.Clock as Clock #endif +#ifdef linux_HOST_OS +import Utility.Exception +#endif newtype MonotonicTimestamp = MonotonicTimestamp Integer deriving (Show, Eq, Ord) +-- On linux, this uses a clock that advances while the system is suspended, +-- except for on very old kernels (eg 2.6.32). +-- On other systems, that is not available, and the monotonic clock will +-- not advance while suspended. currentMonotonicTimestamp :: IO MonotonicTimestamp currentMonotonicTimestamp = - (MonotonicTimestamp . fromIntegral . Clock.sec) - <$> Clock.getTime Clock.Monotonic + (MonotonicTimestamp . fromIntegral . Clock.sec) <$> +#ifdef linux_HOST_OS + (tryNonAsync (Clock.getTime Clock.Boottime) + >>= either (const $ Clock.getTime Clock.Monotonic) return) +#else + Clock.getTime Clock.Monotonic +#endif -- 2.30.2