2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: getCPUTime.c,v 1.4 1999/03/01 09:04:07 sof 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 #ifndef mingw32_TARGET_OS
29 # ifdef HAVE_SYS_TIMES_H
30 # include <sys/times.h>
34 #ifdef HAVE_SYS_TIME_H
38 #if !defined(mingw32_TARGET_OS) && !defined(irix_TARGET_OS)
39 # if defined(HAVE_SYS_RESOURCE_H)
40 # include <sys/resource.h>
44 #ifdef HAVE_SYS_TIMEB_H
45 #include <sys/timeb.h>
49 #include <sys/syscall.h>
50 #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
51 #define HAVE_GETRUSAGE
67 * Our caller wants a pointer to four StgInts,
68 * user seconds, user nanoseconds, system seconds, system nanoseconds.
69 * Yes, the timerval has unsigned components, but nanoseconds take only
70 * 30 bits, and our CPU usage would have to be over 68 years for the
71 * seconds to overflow 31 bits.
75 getCPUTime(StgByteArray cpuStruct)
77 StgInt *cpu=(StgInt *)cpuStruct;
79 /* getrusage() is right royal pain to deal with when targetting multiple
80 versions of Solaris, since some versions supply it in libc (2.3 and 2.5),
81 while 2.4 has got it in libucb (I wouldn't be too surprised if it was back
82 again in libucb in 2.6..)
84 Avoid the problem by resorting to times() instead.
86 #if defined(HAVE_GETRUSAGE) && ! irix_TARGET_OS && ! solaris2_TARGET_OS
89 getrusage(RUSAGE_SELF, &t);
90 cpu[0] = t.ru_utime.tv_sec;
91 cpu[1] = 1000 * t.ru_utime.tv_usec;
92 cpu[2] = t.ru_stime.tv_sec;
93 cpu[3] = 1000 * t.ru_stime.tv_usec;
96 # if defined(HAVE_TIMES)
99 # define ticks CLK_TCK
102 ticks = sysconf(_SC_CLK_TCK);
106 cpu[0] = t.tms_utime / ticks;
107 cpu[1] = (t.tms_utime - cpu[0] * ticks) * (1000000000 / ticks);
108 cpu[2] = t.tms_stime / ticks;
109 cpu[3] = (t.tms_stime - cpu[2] * ticks) * (1000000000 / ticks);
115 return (StgByteArray) cpuStruct;