    {-# INCLUDE "HsBase.h" #-}
    {-# LINE 1 "System\CPUTime.hsc" #-}
    -----------------------------------------------------------------------------
    {-# LINE 2 "System\CPUTime.hsc" #-}
    -- |
    -- Module      :  System.CPUTime
    -- Copyright   :  (c) The University of Glasgow 2001
    -- License     :  BSD-style (see the file libraries/base/LICENSE)
    --
    -- Maintainer  :  libraries@haskell.org
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- The standard CPUTime library.
    --
    -----------------------------------------------------------------------------

    module System.CPUTime
    	(
             getCPUTime,       -- :: IO Integer
    	 cpuTimePrecision  -- :: Integer
            ) where

    import Prelude

    import Data.Ratio

    {-# LINE 28 "System\CPUTime.hsc" #-}

    {-# LINE 32 "System\CPUTime.hsc" #-}

    {-# LINE 34 "System\CPUTime.hsc" #-}
    import Foreign
    import Foreign.C

    {-# LINE 38 "System\CPUTime.hsc" #-}

    {-# LINE 39 "System\CPUTime.hsc" #-}

    {-# LINE 41 "System\CPUTime.hsc" #-}
    -- -----------------------------------------------------------------------------
    -- |Computation 'getCPUTime' returns the number of picoseconds CPU time
    -- used by the current program.  The precision of this result is
    -- implementation-dependent.

    getCPUTime :: IO Integer
    getCPUTime = do

    {-# LINE 95 "System\CPUTime.hsc" #-}
         -- NOTE: GetProcessTimes() is only supported on NT-based OSes.
         -- The counts reported by GetProcessTimes() are in 100-ns (10^-7) units.
        allocaBytes (8) $ \ p_creationTime -> do
    {-# LINE 98 "System\CPUTime.hsc" #-}
        allocaBytes (8) $ \ p_exitTime -> do
    {-# LINE 99 "System\CPUTime.hsc" #-}
        allocaBytes (8) $ \ p_kernelTime -> do
    {-# LINE 100 "System\CPUTime.hsc" #-}
        allocaBytes (8) $ \ p_userTime -> do
    {-# LINE 101 "System\CPUTime.hsc" #-}
        pid <- getCurrentProcess
        ok <- getProcessTimes pid p_creationTime p_exitTime p_kernelTime p_userTime
        if toBool ok then do
          ut <- ft2psecs p_userTime
          kt <- ft2psecs p_kernelTime
          return (ut + kt)
         else return 0
      where
    	ft2psecs :: Ptr FILETIME -> IO Integer
            ft2psecs ft = do
              high <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) ft :: IO Word32
    {-# LINE 112 "System\CPUTime.hsc" #-}
              low  <- ((\hsc_ptr -> peekByteOff hsc_ptr 0))  ft :: IO Word32
    {-# LINE 113 "System\CPUTime.hsc" #-}
    	    -- Convert 100-ns units to picosecs (10^-12)
    	    -- => multiply by 10^5.
              return (((fromIntegral high) * (2^32) + (fromIntegral low)) * 100000)

        -- ToDo: pin down elapsed times to just the OS thread(s) that
        -- are evaluating/managing Haskell code.

    type FILETIME = ()
    type HANDLE = ()
    -- need proper Haskell names (initial lower-case character)
    foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE)
    foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt

    {-# LINE 127 "System\CPUTime.hsc" #-}

    {-# LINE 128 "System\CPUTime.hsc" #-}

    -- |The 'cpuTimePrecision' constant is the smallest measurable difference
    -- in CPU time that the implementation can record, and is given as an
    -- integral number of picoseconds.

    {-# LINE 134 "System\CPUTime.hsc" #-}
    cpuTimePrecision :: Integer
    cpuTimePrecision = round ((1000000000000::Integer) % fromIntegral (clockTicks))

    {-# LINE 137 "System\CPUTime.hsc" #-}

    {-# LINE 139 "System\CPUTime.hsc" #-}
    clockTicks :: Int
    clockTicks =

    {-# LINE 142 "System\CPUTime.hsc" #-}
        (1000)
    {-# LINE 143 "System\CPUTime.hsc" #-}

    {-# LINE 147 "System\CPUTime.hsc" #-}

    {-# LINE 148 "System\CPUTime.hsc" #-}