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

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

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

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

    {-# LINE 16 "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 38 "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 40 "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 41 "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
    foreign import capi unsafe "time.h value CLOCK_PROCESS_CPUTIME_ID" cLOCK_PROCESS_CPUTIME_ID :: CUIntPtr

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