[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / lib / std / cbits / getCPUTime.lc
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
3 %
4 \subsection[getCPUTime.lc]{getCPUTime Runtime Support}
5
6 \begin{code}
7
8 #ifndef _AIX
9 #define NON_POSIX_SOURCE /*needed for solaris2 only?*/
10 #endif
11
12 /* how is this to work given we have not read platform.h yet? */
13 #ifdef hpux_TARGET_OS
14 #define _INCLUDE_HPUX_SOURCE
15 #endif
16
17 #include "rtsdefs.h"
18
19 #ifdef HAVE_SYS_TYPES_H
20 #include <sys/types.h>
21 #endif
22
23 #ifdef HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26
27 #ifdef HAVE_SYS_TIMES_H
28 #include <sys/times.h>
29 #endif
30
31 #ifdef HAVE_SYS_TIME_H
32 #include <sys/time.h>
33 #endif
34
35 #if defined(HAVE_SYS_RESOURCE_H) && ! irix_TARGET_OS
36 #include <sys/resource.h>
37 #endif
38
39 #ifdef HAVE_SYS_TIMEB_H
40 #include <sys/timeb.h>
41 #endif
42
43 #ifdef hpux_TARGET_OS
44 #include <sys/syscall.h>
45 #define getrusage(a, b)  syscall(SYS_GETRUSAGE, a, b)
46 #define HAVE_GETRUSAGE
47 #endif
48
49 StgInt 
50 clockTicks ()
51 {
52  return (
53 #if defined(CLK_TCK)
54     CLK_TCK
55 #else
56     sysconf(_SC_CLK_TCK)
57 #endif
58     ); 
59 }
60
61 /* 
62  * Our caller wants a pointer to four StgInts,
63  * user seconds, user nanoseconds, system seconds, system nanoseconds.
64  * Yes, the timerval has unsigned components, but nanoseconds take only
65  * 30 bits, and our CPU usage would have to be over 68 years for the 
66  * seconds to overflow 31 bits.
67  */
68
69 StgByteArray
70 getCPUTime(StgByteArray cpuStruct)
71 {
72     StgInt *cpu=(StgInt *)cpuStruct;
73
74 /* getrusage() is right royal pain to deal with when targetting multiple
75    versions of Solaris, since some versions supply it in libc (2.3 and 2.5),
76    while 2.4 has got it in libucb (I wouldn't be too surprised if it was back
77    again in libucb in 2.6..)
78
79    Avoid the problem by resorting to times() instead.
80 */
81 #if defined(HAVE_GETRUSAGE) && ! irix_TARGET_OS && ! solaris2_TARGET_OS
82     struct rusage t;
83
84     getrusage(RUSAGE_SELF, &t);
85     cpu[0] = t.ru_utime.tv_sec;
86     cpu[1] = 1000 * t.ru_utime.tv_usec;
87     cpu[2] = t.ru_stime.tv_sec;
88     cpu[3] = 1000 * t.ru_stime.tv_usec;
89
90 #else
91 # if defined(HAVE_TIMES)
92     struct tms t;
93 #  if defined(CLK_TCK)
94 #   define ticks CLK_TCK
95 #  else
96     long ticks;
97     ticks = sysconf(_SC_CLK_TCK);
98 #  endif
99
100     times(&t);
101     cpu[0] = t.tms_utime / ticks;
102     cpu[1] = (t.tms_utime - cpu[0] * ticks) * (1000000000 / ticks);
103     cpu[2] = t.tms_stime / ticks;
104     cpu[3] = (t.tms_stime - cpu[2] * ticks) * (1000000000 / ticks);
105
106 # else
107     return NULL;
108 # endif
109 #endif
110     return (StgByteArray) cpuStruct;
111 }
112
113 \end{code}
114