2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
4 \subsection[getCPUTime.lc]{getCPUTime Runtime Support}
9 #define NON_POSIX_SOURCE /*needed for solaris2 only?*/
12 /* how is this to work given we have not read platform.h yet? */
14 #define _INCLUDE_HPUX_SOURCE
19 #ifdef HAVE_SYS_TYPES_H
20 #include <sys/types.h>
27 #ifdef HAVE_SYS_TIMES_H
28 #include <sys/times.h>
31 #ifdef HAVE_SYS_TIME_H
35 #if defined(HAVE_SYS_RESOURCE_H) && ! irix_TARGET_OS
36 #include <sys/resource.h>
39 #ifdef HAVE_SYS_TIMEB_H
40 #include <sys/timeb.h>
44 #include <sys/syscall.h>
45 #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
46 #define HAVE_GETRUSAGE
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.
70 getCPUTime(StgByteArray cpuStruct)
72 StgInt *cpu=(StgInt *)cpuStruct;
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..)
79 Avoid the problem by resorting to times() instead.
81 #if defined(HAVE_GETRUSAGE) && ! irix_TARGET_OS && ! solaris2_TARGET_OS
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;
91 # if defined(HAVE_TIMES)
94 # define ticks CLK_TCK
97 ticks = sysconf(_SC_CLK_TCK);
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);
110 return (StgByteArray) cpuStruct;