{-# LANGUAGE CPP #-} {-# LANGUAGE JavaScriptFFI #-} {-# OPTIONS_HADDOCK hide #-} -- for doctests module Chronos.Internal.CTimespec ( #ifndef mingw32_HOST_OS getPosixNanoseconds #ifndef ghcjs_HOST_OS , CTimespec(..) #endif #endif ) where import Foreign import Foreign.C #if defined(ghcjs_HOST_OS) foreign import javascript unsafe "Date.now()" currentSeconds :: IO Double getPosixNanoseconds :: IO Int64 getPosixNanoseconds = do x <- currentSeconds pure $ fromIntegral $ 1000000 * (round x) #elif defined(mingw32_HOST_OS) #else data CTimespec = CTimespec { ctimespecSeconds :: {-# UNPACK #-} !CTime , ctimespecNanoseconds :: {-# UNPACK #-} !CLong } instance Storable CTimespec where sizeOf _ = (16) alignment _ = alignment (undefined :: CLong) peek p = do s <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p ns <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p return (CTimespec s ns) poke p (CTimespec s ns) = do (\hsc_ptr -> pokeByteOff hsc_ptr 0) p s (\hsc_ptr -> pokeByteOff hsc_ptr 8) p ns #ifdef darwin_HOST_OS foreign import ccall unsafe "cbits/hs-time.c clock_gettime" clock_gettime :: Int32 -> Ptr CTimespec -> IO CInt #else foreign import ccall unsafe "time.h clock_gettime" clock_gettime :: Int32 -> Ptr CTimespec -> IO CInt #endif -- | Get the current POSIX time from the system clock. getPosixNanoseconds :: IO Int64 getPosixNanoseconds = do CTimespec (CTime s) (CLong ns) <- alloca $ \ptspec -> do throwErrnoIfMinus1_ "clock_gettime" $ clock_gettime 0 ptspec peek ptspec -- On most 64-bit platforms, the uses of fromIntegral here end up -- being i64->i64, but on 32-bit platforms, they are i32->i64. return ((fromIntegral s * 1000000000) + fromIntegral ns) #endif