54691bfe69eb1fe0a9ec0433bcec8056ddab1c4d
[ghc-hetmet.git] / ghc / lib / std / CPUTime.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1995-1997
3 %
4 \section[CPUTime]{Haskell 1.4 CPU Time Library}
5
6 \begin{code}
7 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
8
9 module CPUTime 
10         (
11          getCPUTime,       -- :: IO Integer
12          cpuTimePrecision  -- :: Integer
13         ) where
14
15 #ifdef __HUGS__
16 import PreludeBuiltin
17 #else
18 import PrelBase
19 import PrelArr          ( ByteArray(..), newIntArray, unsafeFreezeByteArray )
20 import PrelMaybe
21 import PrelNum
22 import PrelNumExtra
23 import PrelAddr
24 import PrelIOBase
25 import PrelST
26 #endif
27 import IO               ( ioError )
28 import PrelNum ( Num(..), Integral(..) )        -- To get fromInt/toInt
29 import Ratio
30
31 \end{code}
32
33 Computation @getCPUTime@ returns the number of picoseconds CPU time
34 used by the current program.  The precision of this result is
35 implementation-dependent.
36
37 The @cpuTimePrecision@ constant is the smallest measurable difference
38 in CPU time that the implementation can record, and is given as an
39 integral number of picoseconds.
40
41 \begin{code}
42 #ifdef __HUGS__
43
44 getCPUTime :: IO Integer
45 getCPUTime = do
46     marr <- primNewByteArray (sizeof_int * 4)
47     ptr  <- getCPUTime marr
48     if (ptr /= nullAddr) then do
49         x0 <- primReadIntArray marr 0
50         x1 <- primReadIntArray marr 1
51         x2 <- primReadIntArray marr 2
52         x3 <- primReadIntArray marr 3
53         return ((fromIntegral x0 * 1000000000 + fromIntegral  x1 + 
54                  fromIntegral x2 * 1000000000 + fromIntegral  x3)
55                * 1000)
56       else
57         ioError (IOError Nothing UnsupportedOperation 
58                          "getCPUTime"
59                          "can't get CPU time")
60
61 #else
62
63 getCPUTime :: IO Integer
64 getCPUTime = 
65     stToIO (newIntArray ((0::Int),3))   >>= \ marr ->
66     stToIO (unsafeFreezeByteArray marr) >>= \ barr@(ByteArray _ frozen#) ->
67     primGetCPUTime barr                 >>= \ ptr ->
68     if (ptr::Addr) /= nullAddr then
69         return ((fromIntegral (I# (indexIntArray# frozen# 0#)) * 1000000000 + 
70                  fromIntegral (I# (indexIntArray# frozen# 1#)) + 
71                  fromIntegral (I# (indexIntArray# frozen# 2#)) * 1000000000 + 
72                  fromIntegral (I# (indexIntArray# frozen# 3#))) * 1000)
73     else
74         ioError (IOError Nothing UnsupportedOperation 
75                          "getCPUTime"
76                          "can't get CPU time")
77
78 #endif
79
80 cpuTimePrecision :: Integer
81 cpuTimePrecision = round ((1000000000000::Integer) % 
82                           fromInt (unsafePerformIO clockTicks))
83 \end{code}
84
85 \begin{code}
86 sizeof_int :: Int
87 sizeof_int = 4
88
89 foreign import "libHS_cbits" "getCPUTime" primGetCPUTime :: ByteArray Int -> IO Addr
90 foreign import "libHS_cbits" "clockTicks" clockTicks :: IO Int
91
92 \end{code}
93
94
95