{-# LINE 1 "libraries/base/./GHC/Event/Clock.hsc" #-}
{-# LANGUAGE Trustworthy #-}
{-# LINE 2 "libraries/base/./GHC/Event/Clock.hsc" #-}
{-# LANGUAGE NoImplicitPrelude, BangPatterns, ForeignFunctionInterface, CApiFFI #-}

module GHC.Event.Clock (getCurrentTime) where


{-# LINE 7 "libraries/base/./GHC/Event/Clock.hsc" #-}

import Foreign (Ptr, Storable(..), nullPtr, with)
import Foreign.C.Error (throwErrnoIfMinus1_)
import Foreign.C.Types
import GHC.Base
import GHC.Err
import GHC.Num
import GHC.Real

-- TODO: Implement this for Windows.

-- | Return the current time, in seconds since Jan. 1, 1970.
getCurrentTime :: IO Double
getCurrentTime = do
    tv <- with (CTimeval 0 0) $ \tvptr -> do
        throwErrnoIfMinus1_ "gettimeofday" (gettimeofday tvptr nullPtr)
        peek tvptr
    let !t = realToFrac (sec tv) + realToFrac (usec tv) / 1000000.0
    return t

------------------------------------------------------------------------
-- FFI binding

data CTimeval = CTimeval
    { sec  :: {-# UNPACK #-} !CTime
    , usec :: {-# UNPACK #-} !CSUSeconds
    }

instance Storable CTimeval where
    sizeOf _ = (16)
{-# LINE 37 "libraries/base/./GHC/Event/Clock.hsc" #-}
    alignment _ = alignment (undefined :: CLong)

    peek ptr = do
        sec' <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
{-# LINE 41 "libraries/base/./GHC/Event/Clock.hsc" #-}
        usec' <- (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
{-# LINE 42 "libraries/base/./GHC/Event/Clock.hsc" #-}
        return $ CTimeval sec' usec'

    poke ptr tv = do
        (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (sec tv)
{-# LINE 46 "libraries/base/./GHC/Event/Clock.hsc" #-}
        (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr (usec tv)
{-# LINE 47 "libraries/base/./GHC/Event/Clock.hsc" #-}

foreign import capi unsafe "HsBase.h gettimeofday" gettimeofday
    :: Ptr CTimeval -> Ptr () -> IO CInt