2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: getCPUTime.c,v 1.3 1998/12/02 13:27:36 simonm Exp $
6 * getCPUTime Runtime Support
10 #define NON_POSIX_SOURCE /*needed for solaris2 only?*/
13 /* how is this to work given we have not read platform.h yet? */
15 #define _INCLUDE_HPUX_SOURCE
20 #ifdef HAVE_SYS_TYPES_H
21 #include <sys/types.h>
28 #ifdef HAVE_SYS_TIMES_H
29 #include <sys/times.h>
32 #ifdef HAVE_SYS_TIME_H
36 #if defined(HAVE_SYS_RESOURCE_H) && ! irix_TARGET_OS
37 #include <sys/resource.h>
40 #ifdef HAVE_SYS_TIMEB_H
41 #include <sys/timeb.h>
45 #include <sys/syscall.h>
46 #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
47 #define HAVE_GETRUSAGE
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.
71 getCPUTime(StgByteArray cpuStruct)
73 StgInt *cpu=(StgInt *)cpuStruct;
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..)
80 Avoid the problem by resorting to times() instead.
82 #if defined(HAVE_GETRUSAGE) && ! irix_TARGET_OS && ! solaris2_TARGET_OS
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;
92 # if defined(HAVE_TIMES)
95 # define ticks CLK_TCK
98 ticks = sysconf(_SC_CLK_TCK);
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);
111 return (StgByteArray) cpuStruct;