{-# LINE 1 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}
{-# LANGUAGE CApiFFI #-}

module Data.Time.Clock.Internal.CTimespec where




{-# LINE 8 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}

import Foreign
import Foreign.C
import System.IO.Unsafe



type ClockID = Int32
{-# LINE 16 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}

data CTimespec = MkCTimespec CTime CLong

instance Storable CTimespec where
    sizeOf :: CTimespec -> Int
sizeOf CTimespec
_ = (Int
16)
{-# LINE 21 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}
    alignment _ = alignment (undefined :: CLong)
    peek :: Ptr CTimespec -> IO CTimespec
peek Ptr CTimespec
p = do
        CTime
s  <- (\Ptr CTimespec
hsc_ptr -> Ptr CTimespec -> Int -> IO CTime
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr CTimespec
hsc_ptr Int
0) Ptr CTimespec
p
{-# LINE 24 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}
        CLong
ns <- (\Ptr CTimespec
hsc_ptr -> Ptr CTimespec -> Int -> IO CLong
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr CTimespec
hsc_ptr Int
8) Ptr CTimespec
p
{-# LINE 25 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}
        CTimespec -> IO CTimespec
forall (m :: * -> *) a. Monad m => a -> m a
return (CTime -> CLong -> CTimespec
MkCTimespec CTime
s CLong
ns)
    poke :: Ptr CTimespec -> CTimespec -> IO ()
poke Ptr CTimespec
p (MkCTimespec CTime
s CLong
ns) = do
        (\Ptr CTimespec
hsc_ptr -> Ptr CTimespec -> Int -> CTime -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr CTimespec
hsc_ptr Int
0) Ptr CTimespec
p CTime
s
{-# LINE 28 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}
        (\Ptr CTimespec
hsc_ptr -> Ptr CTimespec -> Int -> CLong -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr CTimespec
hsc_ptr Int
8) Ptr CTimespec
p CLong
ns
{-# LINE 29 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}

foreign import ccall unsafe "time.h clock_gettime"
    clock_gettime :: ClockID -> Ptr CTimespec -> IO CInt
foreign import ccall unsafe "time.h clock_getres"
    clock_getres :: ClockID -> Ptr CTimespec -> IO CInt

-- | Get the resolution of the given clock.
clockGetRes :: ClockID -> IO (Either Errno CTimespec)
clockGetRes :: ClockID -> IO (Either Errno CTimespec)
clockGetRes ClockID
clockid = (Ptr CTimespec -> IO (Either Errno CTimespec))
-> IO (Either Errno CTimespec)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CTimespec -> IO (Either Errno CTimespec))
 -> IO (Either Errno CTimespec))
-> (Ptr CTimespec -> IO (Either Errno CTimespec))
-> IO (Either Errno CTimespec)
forall a b. (a -> b) -> a -> b
$ \Ptr CTimespec
ptspec -> do
    CInt
rc <- ClockID -> Ptr CTimespec -> IO CInt
clock_getres ClockID
clockid Ptr CTimespec
ptspec
    case CInt
rc of
        CInt
0 -> do
            CTimespec
res <- Ptr CTimespec -> IO CTimespec
forall a. Storable a => Ptr a -> IO a
peek Ptr CTimespec
ptspec
            Either Errno CTimespec -> IO (Either Errno CTimespec)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Errno CTimespec -> IO (Either Errno CTimespec))
-> Either Errno CTimespec -> IO (Either Errno CTimespec)
forall a b. (a -> b) -> a -> b
$ CTimespec -> Either Errno CTimespec
forall a b. b -> Either a b
Right CTimespec
res
        CInt
_ -> do
            Errno
errno <- IO Errno
getErrno
            Either Errno CTimespec -> IO (Either Errno CTimespec)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Errno CTimespec -> IO (Either Errno CTimespec))
-> Either Errno CTimespec -> IO (Either Errno CTimespec)
forall a b. (a -> b) -> a -> b
$ Errno -> Either Errno CTimespec
forall a b. a -> Either a b
Left Errno
errno

-- | Get the current time from the given clock.
clockGetTime :: ClockID -> IO CTimespec
clockGetTime :: ClockID -> IO CTimespec
clockGetTime ClockID
clockid = (Ptr CTimespec -> IO CTimespec) -> IO CTimespec
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca (\Ptr CTimespec
ptspec -> do
    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
$ ClockID -> Ptr CTimespec -> IO CInt
clock_gettime ClockID
clockid Ptr CTimespec
ptspec
    Ptr CTimespec -> IO CTimespec
forall a. Storable a => Ptr a -> IO a
peek Ptr CTimespec
ptspec
    )

foreign import capi unsafe "time.h value CLOCK_REALTIME" clock_REALTIME :: ClockID

clock_TAI :: Maybe ClockID
clock_TAI :: Maybe ClockID
clock_TAI =

{-# LINE 59 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}
    Just 11
{-# LINE 60 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}

{-# LINE 63 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}

realtimeRes :: CTimespec
realtimeRes :: CTimespec
realtimeRes = IO CTimespec -> CTimespec
forall a. IO a -> a
unsafePerformIO (IO CTimespec -> CTimespec) -> IO CTimespec -> CTimespec
forall a b. (a -> b) -> a -> b
$ do
    Either Errno CTimespec
mres <- ClockID -> IO (Either Errno CTimespec)
clockGetRes ClockID
clock_REALTIME
    case Either Errno CTimespec
mres of
        Left Errno
errno -> IOError -> IO CTimespec
forall a. IOError -> IO a
ioError (String -> Errno -> Maybe Handle -> Maybe String -> IOError
errnoToIOError String
"clock_getres" Errno
errno Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing)
        Right CTimespec
res -> CTimespec -> IO CTimespec
forall (m :: * -> *) a. Monad m => a -> m a
return CTimespec
res

clockResolution :: ClockID -> Maybe CTimespec
clockResolution :: ClockID -> Maybe CTimespec
clockResolution ClockID
clockid = IO (Maybe CTimespec) -> Maybe CTimespec
forall a. IO a -> a
unsafePerformIO (IO (Maybe CTimespec) -> Maybe CTimespec)
-> IO (Maybe CTimespec) -> Maybe CTimespec
forall a b. (a -> b) -> a -> b
$ do
    Either Errno CTimespec
mres <- ClockID -> IO (Either Errno CTimespec)
clockGetRes ClockID
clockid
    case Either Errno CTimespec
mres of
        Left Errno
_ -> Maybe CTimespec -> IO (Maybe CTimespec)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe CTimespec
forall a. Maybe a
Nothing
        Right CTimespec
res -> Maybe CTimespec -> IO (Maybe CTimespec)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe CTimespec -> IO (Maybe CTimespec))
-> Maybe CTimespec -> IO (Maybe CTimespec)
forall a b. (a -> b) -> a -> b
$ CTimespec -> Maybe CTimespec
forall a. a -> Maybe a
Just CTimespec
res


{-# LINE 79 "lib/Data/Time/Clock/Internal/CTimespec.hsc" #-}