{-# LINE 1 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}
{-# LANGUAGE CPP, CApiFFI, NumDecimals #-}






module System.CPUTime.Posix.ClockGetTime
    ( getCPUTime
    , getCpuTimePrecision
    ) where


{-# LINE 14 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}

import Foreign
import Foreign.C
import System.CPUTime.Utils

getCPUTime :: IO Integer
getCPUTime :: IO Integer
getCPUTime = (((), Integer) -> Integer) -> IO ((), Integer) -> IO Integer
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((), Integer) -> Integer
forall a b. (a, b) -> b
snd (IO ((), Integer) -> IO Integer) -> IO ((), Integer) -> IO Integer
forall a b. (a -> b) -> a -> b
$ (Ptr Timespec -> IO ()) -> IO ((), Integer)
forall a. (Ptr Timespec -> IO a) -> IO (a, Integer)
withTimespec ((Ptr Timespec -> IO ()) -> IO ((), Integer))
-> (Ptr Timespec -> IO ()) -> IO ((), Integer)
forall a b. (a -> b) -> a -> b
$ \Ptr Timespec
ts ->
    String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"clock_gettime"
    (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ CUIntPtr -> Ptr Timespec -> IO CInt
clock_gettime CUIntPtr
cLOCK_PROCESS_CPUTIME_ID Ptr Timespec
ts

getCpuTimePrecision :: IO Integer
getCpuTimePrecision :: IO Integer
getCpuTimePrecision = (((), Integer) -> Integer) -> IO ((), Integer) -> IO Integer
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((), Integer) -> Integer
forall a b. (a, b) -> b
snd (IO ((), Integer) -> IO Integer) -> IO ((), Integer) -> IO Integer
forall a b. (a -> b) -> a -> b
$ (Ptr Timespec -> IO ()) -> IO ((), Integer)
forall a. (Ptr Timespec -> IO a) -> IO (a, Integer)
withTimespec ((Ptr Timespec -> IO ()) -> IO ((), Integer))
-> (Ptr Timespec -> IO ()) -> IO ((), Integer)
forall a b. (a -> b) -> a -> b
$ \Ptr Timespec
ts ->
    String -> IO CInt -> IO ()
forall a. (Eq a, Num a) => String -> IO a -> IO ()
throwErrnoIfMinus1_ String
"clock_getres"
    (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ CUIntPtr -> Ptr Timespec -> IO CInt
clock_getres CUIntPtr
cLOCK_PROCESS_CPUTIME_ID Ptr Timespec
ts

data Timespec

-- | Perform the given action to fill in a @struct timespec@, returning the
-- result of the action and the value of the @timespec@ in picoseconds.
withTimespec :: (Ptr Timespec -> IO a) -> IO (a, Integer)
withTimespec :: forall a. (Ptr Timespec -> IO a) -> IO (a, Integer)
withTimespec Ptr Timespec -> IO a
action =
    Int -> (Ptr Timespec -> IO (a, Integer)) -> IO (a, Integer)
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
16) ((Ptr Timespec -> IO (a, Integer)) -> IO (a, Integer))
-> (Ptr Timespec -> IO (a, Integer)) -> IO (a, Integer)
forall a b. (a -> b) -> a -> b
$ \Ptr Timespec
p_ts -> do
{-# LINE 36 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}
        a
r <- Ptr Timespec -> IO a
action Ptr Timespec
p_ts
        CTime
u_sec  <- ((\Ptr Timespec
hsc_ptr -> Ptr Timespec -> Int -> IO CTime
forall b. Ptr b -> Int -> IO CTime
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Timespec
hsc_ptr Int
0))  Ptr Timespec
p_ts :: IO CTime
{-# LINE 38 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}
        CLong
u_nsec <- ((\Ptr Timespec
hsc_ptr -> Ptr Timespec -> Int -> IO CLong
forall b. Ptr b -> Int -> IO CLong
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Timespec
hsc_ptr Int
8)) Ptr Timespec
p_ts :: IO CLong
{-# LINE 39 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}
        (a, Integer) -> IO (a, Integer)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
r, CTime -> Integer
cTimeToInteger CTime
u_sec Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1e12 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ CLong -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral CLong
u_nsec Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
1e3)

foreign import capi unsafe "time.h clock_getres"  clock_getres  :: CUIntPtr -> Ptr Timespec -> IO CInt
foreign import capi unsafe "time.h clock_gettime" clock_gettime :: CUIntPtr -> Ptr Timespec -> IO CInt


{-# LINE 45 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}
foreign import capi unsafe "time.h value CLOCK_PROCESS_CPUTIME_ID" cLOCK_PROCESS_CPUTIME_ID :: CUIntPtr

{-# LINE 49 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}


{-# LINE 60 "libraries/base/System/CPUTime/Posix/ClockGetTime.hsc" #-}