[project @ 1999-10-05 09:02:30 by simonmar]
[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 PrelIOBase
24 import PrelST
25 #endif
26 import IO               ( ioError )
27 import PrelNum ( Num(..), Integral(..) )        -- To get fromInt/toInt
28 import Ratio
29
30 \end{code}
31
32 Computation @getCPUTime@ returns the number of picoseconds CPU time
33 used by the current program.  The precision of this result is
34 implementation-dependent.
35
36 The @cpuTimePrecision@ constant is the smallest measurable difference
37 in CPU time that the implementation can record, and is given as an
38 integral number of picoseconds.
39
40 \begin{code}
41 #ifdef __HUGS__
42
43 getCPUTime :: IO Integer
44 getCPUTime = do
45     marr <- primNewByteArray (sizeof_int * 4)
46     rc   <- getCPUTime marr
47     if rc /= 0 then do
48         x0 <- primReadIntArray marr 0
49         x1 <- primReadIntArray marr 1
50         x2 <- primReadIntArray marr 2
51         x3 <- primReadIntArray marr 3
52         return ((fromIntegral x0 * 1000000000 + fromIntegral  x1 + 
53                  fromIntegral x2 * 1000000000 + fromIntegral  x3)
54                * 1000)
55       else
56         ioError (IOError Nothing UnsupportedOperation 
57                          "getCPUTime"
58                          "can't get CPU time")
59
60 #else
61
62 getCPUTime :: IO Integer
63 getCPUTime =
64     stToIO (newIntArray ((0::Int),3))   >>= \ marr ->
65     stToIO (unsafeFreezeByteArray marr) >>= \ barr@(ByteArray _ _ frozen#) ->
66     primGetCPUTime barr                 >>= \ rc ->
67     if rc /= 0 then
68         return ((fromIntegral (I# (indexIntArray# frozen# 0#)) * 1000000000 + 
69                  fromIntegral (I# (indexIntArray# frozen# 1#)) + 
70                  fromIntegral (I# (indexIntArray# frozen# 2#)) * 1000000000 + 
71                  fromIntegral (I# (indexIntArray# frozen# 3#))) * 1000)
72     else
73         ioError (IOError Nothing UnsupportedOperation 
74                          "getCPUTime"
75                          "can't get CPU time")
76
77 #endif
78
79 cpuTimePrecision :: Integer
80 cpuTimePrecision = round ((1000000000000::Integer) % 
81                           fromInt (unsafePerformIO clockTicks))
82 \end{code}
83
84 \begin{code}
85 sizeof_int :: Int
86 sizeof_int = 4
87
88 foreign import "libHS_cbits" "getCPUTime" primGetCPUTime :: ByteArray Int -> IO Int
89 foreign import "libHS_cbits" "clockTicks" clockTicks :: IO Int
90
91 \end{code}
92
93
94