2024-07-03 21:54:01 +00:00
|
|
|
{- Monotonic clocks
|
|
|
|
-
|
|
|
|
- Copyright 2024 Joey Hess <id@joeyh.name>
|
|
|
|
-
|
|
|
|
- License: BSD-2-clause
|
|
|
|
-}
|
|
|
|
|
2024-07-04 17:42:09 +00:00
|
|
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
2024-07-03 21:54:01 +00:00
|
|
|
{-# LANGUAGE CPP #-}
|
|
|
|
|
|
|
|
module Utility.MonotonicClock where
|
|
|
|
|
|
|
|
#if MIN_VERSION_clock(0,3,0)
|
|
|
|
import qualified System.Clock as Clock
|
|
|
|
#else
|
|
|
|
import qualified System.Posix.Clock as Clock
|
|
|
|
#endif
|
2024-07-03 22:44:38 +00:00
|
|
|
#ifdef linux_HOST_OS
|
|
|
|
import Utility.Exception
|
|
|
|
#endif
|
2024-07-03 21:54:01 +00:00
|
|
|
|
|
|
|
newtype MonotonicTimestamp = MonotonicTimestamp Integer
|
2024-07-04 17:42:09 +00:00
|
|
|
deriving (Show, Eq, Ord, Num)
|
2024-07-03 21:54:01 +00:00
|
|
|
|
2024-07-03 22:44:38 +00:00
|
|
|
-- 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.
|
2024-07-03 21:54:01 +00:00
|
|
|
currentMonotonicTimestamp :: IO MonotonicTimestamp
|
|
|
|
currentMonotonicTimestamp =
|
2024-07-03 22:44:38 +00:00
|
|
|
(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
|