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