    {-# LANGUAGE CPP #-}
    module Foundation.Time.Bindings
        ( measuringNanoSeconds
        , getMonotonicTime
        ) where

    import Basement.Imports
    import Basement.Types.OffsetSize
    import Basement.Types.Ptr
    import Foundation.System.Bindings.Time
    import Foundation.Time.Types
    import Foundation.Foreign.Alloc
    import Foreign.Storable

    measuringNanoSeconds :: IO a -> IO (a, NanoSeconds)
    measuringNanoSeconds :: forall a. IO a -> IO (a, NanoSeconds)
    measuringNanoSeconds IO a
    f =
        CountOf Word8
    -> (Ptr CTimeSpec -> IO (a, NanoSeconds)) -> IO (a, NanoSeconds)
    forall a b. CountOf Word8 -> (Ptr a -> IO b) -> IO b
    allocaBytes (CSize -> CountOf Word8
    sizeOfCSize CSize
    size_CTimeSpec) ((Ptr CTimeSpec -> IO (a, NanoSeconds)) -> IO (a, NanoSeconds))
    -> (Ptr CTimeSpec -> IO (a, NanoSeconds)) -> IO (a, NanoSeconds)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CTimeSpec
    t1 ->
        CountOf Word8
    -> (Ptr CTimeSpec -> IO (a, NanoSeconds)) -> IO (a, NanoSeconds)
    forall a b. CountOf Word8 -> (Ptr a -> IO b) -> IO b
    allocaBytes (CSize -> CountOf Word8
    sizeOfCSize CSize
    size_CTimeSpec) ((Ptr CTimeSpec -> IO (a, NanoSeconds)) -> IO (a, NanoSeconds))
    -> (Ptr CTimeSpec -> IO (a, NanoSeconds)) -> IO (a, NanoSeconds)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CTimeSpec
    t2 -> do
            CInt
    _err1 <- CInt -> Ptr CTimeSpec -> IO CInt
    sysTimeClockGetTime CInt
    sysTime_CLOCK_MONOTONIC Ptr CTimeSpec
    t1
            a
    r <- IO a
    f
            CInt
    _err2 <- CInt -> Ptr CTimeSpec -> IO CInt
    sysTimeClockGetTime CInt
    sysTime_CLOCK_MONOTONIC Ptr CTimeSpec
    t2
            (a, NanoSeconds) -> IO (a, NanoSeconds)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    r, Word64 -> NanoSeconds
    NanoSeconds Word64
    0)

    getMonotonicTime :: IO (Seconds, NanoSeconds)
    getMonotonicTime :: IO (Seconds, NanoSeconds)
    getMonotonicTime =
        CountOf Word8
    -> (Ptr CTimeSpec -> IO (Seconds, NanoSeconds))
    -> IO (Seconds, NanoSeconds)
    forall a b. CountOf Word8 -> (Ptr a -> IO b) -> IO b
    allocaBytes (CSize -> CountOf Word8
    sizeOfCSize CSize
    size_CTimeSpec) ((Ptr CTimeSpec -> IO (Seconds, NanoSeconds))
     -> IO (Seconds, NanoSeconds))
    -> (Ptr CTimeSpec -> IO (Seconds, NanoSeconds))
    -> IO (Seconds, NanoSeconds)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CTimeSpec
    tspec -> do
            CInt
    _err1 <- CInt -> Ptr CTimeSpec -> IO CInt
    sysTimeClockGetTime CInt
    sysTime_CLOCK_MONOTONIC Ptr CTimeSpec
    tspec
            Seconds
    s  <- Word64 -> Seconds
    Seconds     (Word64 -> Seconds) -> IO Word64 -> IO Seconds
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr CTimeSpec -> Ptr Word64
    forall a b. Ptr a -> Ptr b
    castPtr (Ptr CTimeSpec
    tspec Ptr CTimeSpec -> Offset Word8 -> Ptr CTimeSpec
    forall a. Ptr a -> Offset Word8 -> Ptr a
    `ptrPlus` Offset Word8
    ofs_CTimeSpec_Seconds))
            NanoSeconds
    ns <- Word64 -> NanoSeconds
    NanoSeconds (Word64 -> NanoSeconds) -> IO Word64 -> IO NanoSeconds
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr CTimeSpec -> Ptr Word64
    forall a b. Ptr a -> Ptr b
    castPtr (Ptr CTimeSpec
    tspec Ptr CTimeSpec -> Offset Word8 -> Ptr CTimeSpec
    forall a. Ptr a -> Offset Word8 -> Ptr a
    `ptrPlus` Offset Word8
    ofs_CTimeSpec_NanoSeconds))
            (Seconds, NanoSeconds) -> IO (Seconds, NanoSeconds)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Seconds
    s,NanoSeconds
    ns)