{-# LINE 1 "libraries\base\.\System\CPUTime.hsc" #-} {-# LANGUAGE Trustworthy #-} {-# LINE 2 "libraries\base\.\System\CPUTime.hsc" #-} {-# LANGUAGE CPP, NondecreasingIndentation, ForeignFunctionInterface, CApiFFI #-} ----------------------------------------------------------------------------- -- | -- 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. -- ----------------------------------------------------------------------------- {-# LINE 19 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 20 "libraries\base\.\System\CPUTime.hsc" #-} module System.CPUTime ( getCPUTime, -- :: IO Integer cpuTimePrecision -- :: Integer ) where import Prelude import Data.Ratio {-# LINE 34 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 38 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 40 "libraries\base\.\System\CPUTime.hsc" #-} import Foreign.Safe import Foreign.C {-# LINE 45 "libraries\base\.\System\CPUTime.hsc" #-} -- For _SC_CLK_TCK {-# LINE 48 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 49 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 50 "libraries\base\.\System\CPUTime.hsc" #-} -- For struct rusage {-# LINE 57 "libraries\base\.\System\CPUTime.hsc" #-} -- For FILETIME etc. on Windows {-# LINE 60 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 61 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 62 "libraries\base\.\System\CPUTime.hsc" #-} -- for CLK_TCK {-# LINE 65 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 66 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 67 "libraries\base\.\System\CPUTime.hsc" #-} -- for struct tms {-# LINE 72 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 74 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 81 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 83 "libraries\base\.\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 133 "libraries\base\.\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 136 "libraries\base\.\System\CPUTime.hsc" #-} allocaBytes (8) $ \ p_exitTime -> do {-# LINE 137 "libraries\base\.\System\CPUTime.hsc" #-} allocaBytes (8) $ \ p_kernelTime -> do {-# LINE 138 "libraries\base\.\System\CPUTime.hsc" #-} allocaBytes (8) $ \ p_userTime -> do {-# LINE 139 "libraries\base\.\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 150 "libraries\base\.\System\CPUTime.hsc" #-} low <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ft :: IO Word32 {-# LINE 151 "libraries\base\.\System\CPUTime.hsc" #-} -- Convert 100-ns units to picosecs (10^-12) -- => multiply by 10^5. return (((fromIntegral high) * (2^(32::Int)) + (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 165 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 166 "libraries\base\.\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 172 "libraries\base\.\System\CPUTime.hsc" #-} cpuTimePrecision :: Integer cpuTimePrecision = round ((1000000000000::Integer) % fromIntegral (clockTicks)) {-# LINE 175 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 177 "libraries\base\.\System\CPUTime.hsc" #-} clockTicks :: Int clockTicks = {-# LINE 180 "libraries\base\.\System\CPUTime.hsc" #-} (1000) {-# LINE 181 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 185 "libraries\base\.\System\CPUTime.hsc" #-} {-# LINE 186 "libraries\base\.\System\CPUTime.hsc" #-}