posix-timer 0.0.3 → 0.1
raw patch · 3 files changed
+296/−232 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- System.Posix.Timer: Clock :: Int32 -> Clock
- System.Posix.Timer: clockSleep :: Clock -> TimeSpec -> IO TimeSpec
- System.Posix.Timer: clockSleepAbs :: Clock -> TimeSpec -> IO ()
- System.Posix.Timer: data TimeSpec
- System.Posix.Timer: getClockResolution :: Clock -> IO TimeSpec
- System.Posix.Timer: getClockTime :: Clock -> IO TimeSpec
- System.Posix.Timer: getProcClock :: ProcessID -> IO Clock
- System.Posix.Timer: instance Bounded TimeSpec
- System.Posix.Timer: instance Eq Clock
- System.Posix.Timer: instance Eq TimeSpec
- System.Posix.Timer: instance Num TimeSpec
- System.Posix.Timer: instance Ord Clock
- System.Posix.Timer: instance Ord TimeSpec
- System.Posix.Timer: instance Real TimeSpec
- System.Posix.Timer: instance Show Clock
- System.Posix.Timer: instance Show TimeSpec
- System.Posix.Timer: instance Storable Clock
- System.Posix.Timer: instance Storable TimeSpec
- System.Posix.Timer: mkTimeSpec :: CTime -> CULong -> TimeSpec
- System.Posix.Timer: monotonicClock :: Clock
- System.Posix.Timer: newtype Clock
- System.Posix.Timer: processTimeClock :: Clock
- System.Posix.Timer: realtimeClock :: Clock
- System.Posix.Timer: setClockTime :: Clock -> TimeSpec -> IO ()
- System.Posix.Timer: threadTimeClock :: Clock
- System.Posix.Timer: timeSpecNanoseconds :: TimeSpec -> CULong
- System.Posix.Timer: timeSpecSeconds :: TimeSpec -> CTime
- System.Posix.Timer: timeSpecToInt64 :: TimeSpec -> Int64
- System.Posix.Timer: timeSpecToNum :: Num a => TimeSpec -> a
- System.Posix.Timer: timeSpecV :: TimeSpec -> (CTime, CULong)
+ System.Posix.Clock: Clock :: Int32 -> Clock
+ System.Posix.Clock: clockSleep :: Clock -> TimeSpec -> IO TimeSpec
+ System.Posix.Clock: clockSleepAbs :: Clock -> TimeSpec -> IO ()
+ System.Posix.Clock: data TimeSpec
+ System.Posix.Clock: getClockResolution :: Clock -> IO TimeSpec
+ System.Posix.Clock: getClockTime :: Clock -> IO TimeSpec
+ System.Posix.Clock: getProcessClock :: ProcessID -> IO Clock
+ System.Posix.Clock: instance Bounded TimeSpec
+ System.Posix.Clock: instance Enum TimeSpec
+ System.Posix.Clock: instance Eq Clock
+ System.Posix.Clock: instance Eq TimeSpec
+ System.Posix.Clock: instance Integral TimeSpec
+ System.Posix.Clock: instance Num TimeSpec
+ System.Posix.Clock: instance Ord Clock
+ System.Posix.Clock: instance Ord TimeSpec
+ System.Posix.Clock: instance Real TimeSpec
+ System.Posix.Clock: instance Show Clock
+ System.Posix.Clock: instance Show TimeSpec
+ System.Posix.Clock: instance Storable Clock
+ System.Posix.Clock: instance Storable TimeSpec
+ System.Posix.Clock: mkTimeSpec :: CTime -> CULong -> TimeSpec
+ System.Posix.Clock: monotonicClock :: Clock
+ System.Posix.Clock: newtype Clock
+ System.Posix.Clock: processTimeClock :: Clock
+ System.Posix.Clock: realtimeClock :: Clock
+ System.Posix.Clock: setClockTime :: Clock -> TimeSpec -> IO ()
+ System.Posix.Clock: threadTimeClock :: Clock
+ System.Posix.Clock: timeSpecNanos :: TimeSpec -> CULong
+ System.Posix.Clock: timeSpecSeconds :: TimeSpec -> CTime
+ System.Posix.Clock: timeSpecToInt64 :: TimeSpec -> Int64
+ System.Posix.Clock: timeSpecV :: TimeSpec -> (CTime, CULong)
Files
- posix-timer.cabal +6/−1
- src/System/Posix/Clock.hsc +248/−0
- src/System/Posix/Timer.hsc +42/−231
posix-timer.cabal view
@@ -1,5 +1,5 @@ Name: posix-timer-Version: 0.0.3+Version: 0.1 Category: System Stability: experimental Synopsis: Bindings to POSIX clock and timer functions.@@ -17,11 +17,16 @@ Extra-Source-Files: include/posix-timer.macros.h +Source-Repository head+ Type: git+ Location: https://github.com/mvv/posix-timer.git+ Library Build-Depends: base < 5, unix Hs-Source-Dirs: src Include-Dirs: include GHC-Options: -Wall Exposed-Modules:+ System.Posix.Clock System.Posix.Timer
+ src/System/Posix/Clock.hsc view
@@ -0,0 +1,248 @@+{-# LANGUAGE UnicodeSyntax #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- | POSIX clocks.+module System.Posix.Clock (+ TimeSpec,+ timeSpecSeconds,+ timeSpecNanos,+ mkTimeSpec,+ timeSpecV,+ timeSpecToInt64,++ Clock(..),+ monotonicClock,+ realtimeClock,+ processTimeClock,+ threadTimeClock,++ getProcessClock,+ getClockResolution,+ getClockTime,+ setClockTime,+ clockSleep,+ clockSleepAbs,+ ) where++import Data.Int+import Data.Word+import Data.Ratio (numerator)+import Data.List (unfoldr)+import Control.Applicative ((<$>), (<*>))+import Foreign.Ptr (Ptr, nullPtr)+import Foreign.Storable (Storable(..))+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Utils (with)+import Foreign.C.Types (CInt, CULong, CTime)+import Foreign.C.Error (getErrno, eINTR, throwErrno, throwErrnoIfMinus1_)+import System.Posix.Types (ProcessID)+import Unsafe.Coerce (unsafeCoerce)++#include <time.h>+#include <HsBaseConfig.h>+#include <posix-timer.macros.h>++#let alignment t = "%lu", (unsigned long) offsetof (struct { char x__; t (y__); }, y__)++nsPerSecond ∷ Num α ⇒ α+nsPerSecond = 1000000000+{-# INLINE nsPerSecond #-}++minSecsInInt, minNsInInt ∷ Int+(minSecsInInt, minNsInInt) = (minBound ∷ Int) `divMod` nsPerSecond++maxSecsInInt, maxNsInInt ∷ Int+(maxSecsInInt, maxNsInInt) = (maxBound ∷ Int) `divMod` nsPerSecond++-- | Mirrors /struct timespec/.+data TimeSpec = TimeSpec { timeSpecSeconds ∷ CTime+ , timeSpecNanos ∷ CULong+ } deriving (Eq, Show)++-- | Create a 'TimeSpec' from amounts of seconds and nanoseconds.+mkTimeSpec ∷ CTime → CULong → TimeSpec+mkTimeSpec s ns | ns < nsPerSecond = TimeSpec s ns+ | otherwise = TimeSpec (s + fromIntegral q) r+ where (q, r) = ns `quotRem` nsPerSecond ++-- | Convert a 'TimeSpec' to a pair of its components.+-- Useful as a view pattern.+timeSpecV ∷ TimeSpec → (CTime, CULong)+timeSpecV (TimeSpec s ns) = (s, ns)+{-# INLINE timeSpecV #-}++instance Ord TimeSpec where+ (TimeSpec s1 ns1) `compare` (TimeSpec s2 ns2) = + case s1 `compare` s2 of+ EQ → ns1 `compare` ns2+ x → x++instance Bounded TimeSpec where+ minBound = TimeSpec (fromIntegral (minBound ∷ #{itype time_t})) 0+ maxBound = TimeSpec (fromIntegral (maxBound ∷ #{itype time_t}))+ (nsPerSecond - 1)++instance Num TimeSpec where+ (TimeSpec s1 ns1) * (TimeSpec s2 ns2) =+ mkTimeSpec (s1 * s2 * nsPerSecond ++ s1 * (fromIntegral ns2) + s2 * (fromIntegral ns1) ++ (fromIntegral q)) $ fromIntegral r+ where (q, r) = ((fromIntegral ns1 ∷ Word64) *+ (fromIntegral ns2 ∷ Word64)) `quotRem` nsPerSecond+ (TimeSpec s1 ns1) + (TimeSpec s2 ns2) = mkTimeSpec (s1 + s2) (ns1 + ns2)+ (TimeSpec s1 ns1) - (TimeSpec s2 ns2) =+ if ns1 < ns2 then TimeSpec (s1 - s2 - 1) (nsPerSecond - ns2 + ns1)+ else TimeSpec (s1 - s2) (ns1 - ns2)+ negate (TimeSpec s ns) = mkTimeSpec ((-s) - 1) (nsPerSecond - ns)+ abs ts@(TimeSpec s _) = if s >= 0 then ts else negate ts+ signum (TimeSpec s ns) | s < 0 = TimeSpec (-1) (nsPerSecond - 1)+ | otherwise = TimeSpec 0 $ signum ns+ fromInteger i = TimeSpec (fromInteger s) (fromInteger ns)+ where (s, ns) = i `divMod` nsPerSecond++instance Real TimeSpec where+ toRational (TimeSpec s ns) = toRational s * nsPerSecond + toRational ns++instance Enum TimeSpec where+ succ (TimeSpec s ns) | ns == nsPerSecond - 1 = TimeSpec (succ s) 0+ | otherwise = TimeSpec s (succ ns)+ pred (TimeSpec s ns) | ns == 0 = TimeSpec (pred s) (nsPerSecond - 1)+ | otherwise = TimeSpec s (ns - 1)+ toEnum i = TimeSpec (fromIntegral s) (fromIntegral ns)+ where (s, ns) = i `divMod` nsPerSecond+ fromEnum (TimeSpec s ns) =+ if s' < minSecs || (s' == minSecs && ns < minNs) ||+ s' > maxSecs || (s' == maxSecs && ns > maxNs)+ then error "TimeSpec.fromEnum"+ else fromIntegral s' * nsPerSecond + fromIntegral ns+ where s', minSecs, maxSecs ∷ #{itype time_t}+ s' = unsafeCoerce s+ minSecs = fromIntegral minSecsInInt+ maxSecs = fromIntegral maxSecsInInt+ minNs, maxNs ∷ CULong+ minNs = fromIntegral minNsInInt+ maxNs = fromIntegral maxNsInInt+ enumFrom x = enumFromTo x maxBound+ enumFromThen x y = enumFromThenTo x y bound+ where bound | y >= x = maxBound+ | otherwise = minBound+ enumFromTo x y+ | y >= x = unfoldr (\z → if z == y then Nothing else Just (z, z + 1)) x+ | otherwise = unfoldr (\z → if z == y then Nothing else Just (z, z - 1)) x+ enumFromThenTo x n y+ | d >= 0 =+ if y < x+ then []+ else unfoldr (\z → if z > y then Nothing else Just (z, z + d)) x+ | otherwise =+ if y > x+ then []+ else unfoldr (\z → if z < y then Nothing else Just (z, z - d)) x+ where d = n - x++instance Integral TimeSpec where+ toInteger (TimeSpec s ns) = (numerator $ toRational s) * nsPerSecond ++ toInteger ns+ -- TODO: Make it faster when the arguments are small enough+ quotRem tsN tsD = (fromInteger q, fromInteger r)+ where (q, r) = quotRem (toInteger tsN) (toInteger tsD)++timeSpecToInt64 ∷ TimeSpec → Int64+timeSpecToInt64 (TimeSpec s ns) =+#if HTYPE_TIME_T == Int64+ (unsafeCoerce s ∷ Int64) * nsPerSecond ++#elif HTYPE_TIME_T == Int32+ (fromIntegral (unsafeCoerce s ∷ Int32) ∷ Int64) * nsPerSecond ++#else+# error FIXME: timeSpecToInt64: unexpected HTYPE_TIME_T value+#endif+ fromIntegral ns+{-# INLINE timeSpecToInt64 #-}++{-# RULES+"fromIntegral/TimeSpec->Int64" fromIntegral = timeSpecToInt64+"fromIntegral/TimeSpec->Word64" fromIntegral = fromIntegral . timeSpecToInt64+ #-}++instance Storable TimeSpec where+ alignment _ = #{alignment struct timespec}+ sizeOf _ = #{size struct timespec}+ peek p = TimeSpec <$> #{peek struct timespec, tv_sec} p+ <*> #{peek struct timespec, tv_nsec} p+ poke p (TimeSpec seconds nanoseconds) = do+ #{poke struct timespec, tv_sec} p seconds+ #{poke struct timespec, tv_nsec} p nanoseconds++-- | Mirrors /clockid_t/.+newtype Clock = Clock #{itype clockid_t} deriving (Eq, Ord, Show, Storable)++#{enum Clock, Clock+ , monotonicClock = CLOCK_MONOTONIC+ , realtimeClock = CLOCK_REALTIME+ , processTimeClock = CLOCK_PROCESS_CPUTIME_ID+ , threadTimeClock = CLOCK_THREAD_CPUTIME_ID+ }++-- | Get the CPU-time clock of the given process.+-- See /clock_getcpuclockid(3)/.+getProcessClock ∷ ProcessID → IO Clock+getProcessClock pid =+ alloca $ \p → do+ throwErrnoIfMinus1_ "getProcClock" $ c_clock_getcpuclockid pid p+ peek p++-- | Get the clock resolution. See /clock_getres(3)/.+getClockResolution ∷ Clock → IO TimeSpec+getClockResolution clock =+ alloca $ \p → do+ throwErrnoIfMinus1_ "getClockResolution" $ c_clock_getres clock p+ peek p++-- | Get the clock time. See /clock_gettime(3)/.+getClockTime ∷ Clock → IO TimeSpec+getClockTime clock =+ alloca $ \p → do+ throwErrnoIfMinus1_ "getClockTime" $ c_clock_gettime clock p+ peek p++-- | Set the clock time. See /clock_settime(3)/.+setClockTime ∷ Clock → TimeSpec → IO ()+setClockTime clock ts =+ with ts $ throwErrnoIfMinus1_ "setClockTime" . c_clock_settime clock++-- | Sleep for the specified duration. When interrupted by a signal, returns+-- the amount of time left to sleep. See /clock_nanosleep(3)/.+clockSleep ∷ Clock → TimeSpec → IO TimeSpec+clockSleep clock ts =+ with ts $ \pTs →+ alloca $ \pLeft → do + result ← c_clock_nanosleep clock 0 pTs pLeft+ if result == 0+ then return 0+ else do+ errno ← getErrno+ if errno == eINTR+ then peek pLeft+ else throwErrno "clockSleep"++-- | Sleep until the clock time reaches the specified value.+-- See /clock_nanosleep(3)/.+clockSleepAbs ∷ Clock → TimeSpec → IO ()+clockSleepAbs clock ts =+ with ts $ \p →+ throwErrnoIfMinus1_ "clockSleepAbs" $+ c_clock_nanosleep clock #{const TIMER_ABSTIME} p nullPtr++foreign import ccall unsafe "clock_getcpuclockid"+ c_clock_getcpuclockid ∷ ProcessID → Ptr Clock → IO CInt+foreign import ccall unsafe "clock_getres"+ c_clock_getres ∷ Clock → Ptr TimeSpec → IO CInt+foreign import ccall unsafe "clock_gettime"+ c_clock_gettime ∷ Clock → Ptr TimeSpec → IO CInt+foreign import ccall unsafe "clock_settime"+ c_clock_settime ∷ Clock → Ptr TimeSpec → IO CInt+foreign import ccall unsafe "clock_nanosleep"+ c_clock_nanosleep ∷ Clock → CInt → Ptr TimeSpec → Ptr TimeSpec → IO CInt+
src/System/Posix/Timer.hsc view
@@ -1,32 +1,11 @@-{-# LANGUAGE CPP, ForeignFunctionInterface #-}+{-# LANGUAGE UnicodeSyntax #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} --- | POSIX clocks and timers.+-- | POSIX timers. module System.Posix.Timer (- -- * Clocks- Clock(..),- monotonicClock,- realtimeClock,- processTimeClock,- threadTimeClock,-- getProcClock,- getClockResolution,- getClockTime,- setClockTime,- clockSleep,- clockSleepAbs,-- -- * Timers- TimeSpec,- timeSpecSeconds,- timeSpecNanoseconds,- mkTimeSpec,- timeSpecV,- timeSpecToNum,- timeSpecToInt64, ITimerSpec(..),- Timer, createTimer, configureTimer,@@ -35,140 +14,33 @@ destroyTimer ) where -import Data.Int import Data.Word-import Data.Ratio (numerator)+import Control.Applicative ((<$>), (<*>)) import Foreign.Storable (Storable(..)) import Foreign.Ptr (Ptr, WordPtr, nullPtr, castPtr) import Foreign.Marshal.Alloc (alloca, allocaBytes) import Foreign.Marshal.Utils (with)-import Foreign.C.Types (CInt, CULong, CTime)-import Foreign.C.Error (getErrno, eINTR, throwErrno, throwErrnoIfMinus1,- throwErrnoIfMinus1_)-import System.Posix.Types (ProcessID)+import Foreign.C.Types (CInt)+import Foreign.C.Error (throwErrnoIfMinus1, throwErrnoIfMinus1_) import System.Posix.Signals (Signal)-import Unsafe.Coerce (unsafeCoerce)+import System.Posix.Clock (TimeSpec, Clock) #include <time.h> #include <signal.h>-#include <HsBaseConfig.h> #include <posix-timer.macros.h> -nsPerSecond :: Num a => a-nsPerSecond = 1000000000-{-# INLINE nsPerSecond #-}---- | Mirrors /clockid_t/.-newtype Clock = Clock #{itype clockid_t} deriving (Eq, Ord, Show, Storable)--#{enum Clock, Clock- , monotonicClock = CLOCK_MONOTONIC- , realtimeClock = CLOCK_REALTIME- , processTimeClock = CLOCK_PROCESS_CPUTIME_ID- , threadTimeClock = CLOCK_THREAD_CPUTIME_ID- }---- | Mirrors /struct timespec/.-data TimeSpec = TimeSpec { timeSpecSeconds :: CTime- , timeSpecNanoseconds :: CULong- } deriving (Eq, Show)---- | Create a 'TimeSpec' from amounts of seconds and nanoseconds.-mkTimeSpec :: CTime -> CULong -> TimeSpec-mkTimeSpec seconds nanoseconds =- case nanoseconds of- ns | ns >= nsPerSecond ->- TimeSpec (seconds + (fromIntegral q)) r- where (q, r) = ns `quotRem` nsPerSecond - _ -> TimeSpec seconds nanoseconds---- | Convert a 'TimeSpec' to a pair of its components.--- Useful as a view pattern.-timeSpecV :: TimeSpec -> (CTime, CULong)-timeSpecV (TimeSpec s ns) = (s, ns)-{-# INLINE timeSpecV #-}---- | The total amount of time a 'TimeSpec' represents,--- in nanoseconds.-timeSpecToNum :: Num a => TimeSpec -> a-timeSpecToNum = fromInteger . numerator . toRational-{-# RULES-"timeSpecToNum/Int64" timeSpecToNum = timeSpecToInt64-"timeSpecToNum/Word64" timeSpecToNum = \x -> fromIntegral (timeSpecToInt64 x)- #-}---- | Specialized version of 'timeSpecToNum'.-timeSpecToInt64 :: TimeSpec -> Int64-timeSpecToInt64 (TimeSpec s ns) =- let ns64 = fromIntegral ns in-#if HTYPE_TIME_T == Int64- (unsafeCoerce s :: Int64) * nsPerSecond +-#elif HTYPE_TIME_T == Int32- (fromIntegral (unsafeCoerce s :: Int32) :: Int64) * nsPerSecond +-#else-# error FIXME: timeSpecToInt64: unexpected HTYPE_TIME_T-#endif- if s >= 0 then ns64 else -ns64--instance Ord TimeSpec where- (TimeSpec s1 ns1) `compare` (TimeSpec s2 ns2) = - case s1 `compare` s2 of- EQ -> ns1 `compare` ns2- x -> x--instance Bounded TimeSpec where- minBound = TimeSpec (fromIntegral (minBound :: #{itype clock_t})) 0- maxBound = TimeSpec (fromIntegral (maxBound :: #{itype clock_t}))- (nsPerSecond - 1)--instance Num TimeSpec where- (TimeSpec s1 ns1) * (TimeSpec s2 ns2) =- mkTimeSpec (s1 * s2 * nsPerSecond +- s1 * (fromIntegral ns2) + s2 * (fromIntegral ns1) +- (fromIntegral q)) $ fromIntegral r- where (q, r) = ((fromIntegral ns1 :: Word64) *- (fromIntegral ns2 :: Word64)) `quotRem` nsPerSecond- (TimeSpec s1 ns1) + (TimeSpec s2 ns2) = mkTimeSpec (s1 + s2) (ns1 + ns2)- (TimeSpec s1 ns1) - (TimeSpec s2 ns2) =- if ns1 < ns2 then TimeSpec (s1 - s2 - 1) (nsPerSecond - ns2 + ns1)- else TimeSpec (s1 - s2) (ns1 - ns2)- negate (TimeSpec s ns) = mkTimeSpec ((-s) - 1) (nsPerSecond - ns)- abs ts@(TimeSpec s _) = if s >= 0 then ts else negate ts- signum (TimeSpec s _) =- TimeSpec 0 (if s < 0 then -1 else (if s == 0 then 0 else nsPerSecond -1))- fromInteger i = TimeSpec (fromInteger s) (fromInteger ns)- where (s, ns) = i `divMod` nsPerSecond--instance Real TimeSpec where- toRational (TimeSpec s ns) =- let rns = toRational ns in- toRational s * nsPerSecond + if s >= 0 then rns else -rns- #let alignment t = "%lu", (unsigned long) offsetof (struct { char x__; t (y__); }, y__) -instance Storable TimeSpec where- alignment _ = #{alignment struct timespec}- sizeOf _ = #{size struct timespec}- peek p = do- seconds <- #{peek struct timespec, tv_sec} p- nanoseconds <- #{peek struct timespec, tv_nsec} p- return $ TimeSpec seconds nanoseconds- poke p (TimeSpec seconds nanoseconds) = do- #{poke struct timespec, tv_sec} p seconds- #{poke struct timespec, tv_nsec} p nanoseconds- -- | Mirrors /struct itimerspec/.-data ITimerSpec = ITimerSpec { iTimerSpecInterval :: !TimeSpec- , iTimerSpecValue :: !TimeSpec+data ITimerSpec = ITimerSpec { iTimerSpecInterval ∷ !TimeSpec+ , iTimerSpecValue ∷ !TimeSpec } deriving (Eq, Show) instance Storable ITimerSpec where alignment _ = #{alignment struct itimerspec}- sizeOf _ = #{size struct itimerspec}- peek p = do- interval <- #{peek struct itimerspec, it_interval} p- value <- #{peek struct itimerspec, it_value} p- return $ ITimerSpec interval value+ sizeOf _ = #{size struct itimerspec}+ peek p = ITimerSpec <$> #{peek struct itimerspec, it_interval} p+ <*> #{peek struct itimerspec, it_value} p poke p (ITimerSpec interval value) = do #{poke struct itimerspec, it_interval} p interval #{poke struct itimerspec, it_value} p value@@ -176,130 +48,69 @@ -- | Mirrors /timer_t/. newtype Timer = Timer #{itype timer_t} deriving (Eq, Ord, Show, Storable) --- | Get the CPU-time clock of the given process.--- See /clock_getcpuclockid(3)/.-getProcClock :: ProcessID -> IO Clock-getProcClock pid = do- alloca $ \p -> do- throwErrnoIfMinus1_ "getProcClock" $ c_clock_getcpuclockid pid p- peek p---- | Get the clock resolution. See /clock_getres(3)/.-getClockResolution :: Clock -> IO TimeSpec-getClockResolution clock = do- alloca $ \p -> do- throwErrnoIfMinus1_ "getClockResolution" $ c_clock_getres clock p- peek p---- | Get the clock time. See /clock_gettime(3)/.-getClockTime :: Clock -> IO TimeSpec-getClockTime clock = do- alloca $ \p -> do- throwErrnoIfMinus1_ "getClockTime" $ c_clock_gettime clock p- peek p---- | Set the clock time. See /clock_settime(3)/.-setClockTime :: Clock -> TimeSpec -> IO ()-setClockTime clock ts =- with ts $ throwErrnoIfMinus1_ "setClockTime" . c_clock_settime clock---- | Sleep for the specified duration. When interrupted by a signal, returns--- the amount of time left to sleep. See /clock_nanosleep(3)/.-clockSleep :: Clock -> TimeSpec -> IO TimeSpec-clockSleep clock ts =- with ts $ \pTs ->- alloca $ \pLeft -> do - result <- c_clock_nanosleep clock 0 pTs pLeft- if result == 0- then return 0- else do- errno <- getErrno- if errno == eINTR- then peek pLeft- else throwErrno "clockSleep"---- | Sleep until the clock time reaches the specified value.--- See /clock_nanosleep(3)/.-clockSleepAbs :: Clock -> TimeSpec -> IO ()-clockSleepAbs clock ts =- with ts $ \p ->- throwErrnoIfMinus1_ "clockSleepAbs" $- c_clock_nanosleep clock #{const TIMER_ABSTIME} p nullPtr- -- | Create a timer. See /timer_create(3)/.-createTimer :: Clock- -> Maybe (Signal, WordPtr) -- ^ Optional signal to raise on timer+createTimer ∷ Clock+ → Maybe (Signal, WordPtr) -- ^ Optional signal to raise on timer -- expirations and value of -- /siginfo.si_value/.- -> IO Timer+ → IO Timer createTimer clock sigEvent = do- alloca $ \pTimer -> do+ alloca $ \pTimer → do throwErrnoIfMinus1_ "createTimer" $ case sigEvent of- Just (signal, ud) -> do- allocaBytes #{size struct sigevent} $ \pEv -> do+ Just (signal, ud) → do+ allocaBytes #{size struct sigevent} $ \pEv → do #{poke struct sigevent, sigev_notify} pEv- (#{const SIGEV_SIGNAL} :: CInt)+ (#{const SIGEV_SIGNAL} ∷ CInt) #{poke struct sigevent, sigev_signo} pEv signal #{poke struct sigevent, sigev_value} pEv ud- c_timer_create clock (castPtr $ (pEv :: Ptr Word8)) pTimer- Nothing ->+ c_timer_create clock (castPtr $ (pEv ∷ Ptr Word8)) pTimer+ Nothing → c_timer_create clock nullPtr pTimer peek pTimer -- | Setup the timer. See /timer_settime(3)/.-configureTimer :: Timer- -> Bool -- ^ Whether the expiration time is absolute.- -> TimeSpec -- ^ Expiration time. Zero value disarms the timer.- -> TimeSpec -- ^ Interval between subsequent expirations.- -> IO (TimeSpec, TimeSpec)+configureTimer ∷ Timer+ → Bool -- ^ Whether the expiration time is absolute.+ → TimeSpec -- ^ Expiration time. Zero value disarms the timer.+ → TimeSpec -- ^ Interval between subsequent expirations.+ → IO (TimeSpec, TimeSpec) configureTimer timer absolute value interval =- with (ITimerSpec interval value) $ \pNew ->- alloca $ \pOld -> do+ with (ITimerSpec interval value) $ \pNew →+ alloca $ \pOld → do throwErrnoIfMinus1_ "configureTimer" $ c_timer_settime timer (if absolute then #{const TIMER_ABSTIME} else 0) pNew pOld- (ITimerSpec oldInterval oldValue) <- peek pOld+ ITimerSpec oldInterval oldValue ← peek pOld return (oldValue, oldInterval) -- | Get the amount of time left until the next expiration and the interval -- between the subsequent expirations. See /timer_gettime(3)/.-timerTimeLeft :: Timer -> IO (TimeSpec, TimeSpec)-timerTimeLeft timer = do- alloca $ \p -> do+timerTimeLeft ∷ Timer → IO (TimeSpec, TimeSpec)+timerTimeLeft timer =+ alloca $ \p → do throwErrnoIfMinus1_ "timerTimeLeft" $ c_timer_gettime timer p- (ITimerSpec interval value) <- peek p+ ITimerSpec interval value ← peek p return (value, interval) -- | Get the timer overrun count. See /timer_getoverrun(3)/.-timerOverrunCnt :: Timer -> IO CInt+timerOverrunCnt ∷ Timer → IO CInt timerOverrunCnt timer = throwErrnoIfMinus1 "timerOverrunCnt" $ c_timer_getoverrun timer -- | Destroy the timer. See /timer_delete(3)/.-destroyTimer :: Timer -> IO ()+destroyTimer ∷ Timer → IO () destroyTimer timer = throwErrnoIfMinus1_ "deleteTimer" $ c_timer_delete timer -foreign import ccall unsafe "clock_getcpuclockid"- c_clock_getcpuclockid :: ProcessID -> Ptr Clock -> IO CInt-foreign import ccall unsafe "clock_getres"- c_clock_getres :: Clock -> Ptr TimeSpec -> IO CInt-foreign import ccall unsafe "clock_gettime"- c_clock_gettime :: Clock -> Ptr TimeSpec -> IO CInt-foreign import ccall unsafe "clock_settime"- c_clock_settime :: Clock -> Ptr TimeSpec -> IO CInt-foreign import ccall unsafe "clock_nanosleep"- c_clock_nanosleep :: Clock -> CInt -> Ptr TimeSpec -> Ptr TimeSpec -> IO CInt- foreign import ccall unsafe "timer_create"- c_timer_create :: Clock -> Ptr () -> Ptr Timer -> IO CInt+ c_timer_create ∷ Clock → Ptr () → Ptr Timer → IO CInt foreign import ccall unsafe "timer_settime"- c_timer_settime ::- Timer -> CInt -> Ptr ITimerSpec -> Ptr ITimerSpec -> IO CInt+ c_timer_settime ∷+ Timer → CInt → Ptr ITimerSpec → Ptr ITimerSpec → IO CInt foreign import ccall unsafe "timer_gettime"- c_timer_gettime :: Timer -> Ptr ITimerSpec -> IO CInt+ c_timer_gettime ∷ Timer → Ptr ITimerSpec → IO CInt foreign import ccall unsafe "timer_getoverrun"- c_timer_getoverrun :: Timer -> IO CInt+ c_timer_getoverrun ∷ Timer → IO CInt foreign import ccall unsafe "timer_delete"- c_timer_delete :: Timer -> IO CInt+ c_timer_delete ∷ Timer → IO CInt