% % (c) The GRASP/AQUA Project, Glasgow University, 1995 % \subsection[getCPUTime.lc]{getCPUTime Runtime Support} \begin{code} #ifndef _AIX #define NON_POSIX_SOURCE /*needed for solaris2 only?*/ #endif /* how is this to work given we have not read platform.h yet? */ #ifdef hpux_TARGET_OS #define _INCLUDE_HPUX_SOURCE #endif #include "rtsdefs.h" #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_TIMES_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #if defined(HAVE_SYS_RESOURCE_H) && ! irix_TARGET_OS #include #endif #ifdef HAVE_SYS_TIMEB_H #include #endif #ifdef hpux_TARGET_OS #include #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b) #define HAVE_GETRUSAGE #endif StgInt clockTicks () { return ( #if defined(CLK_TCK) CLK_TCK #else sysconf(_SC_CLK_TCK) #endif ); } /* * Our caller wants a pointer to four StgInts, * user seconds, user nanoseconds, system seconds, system nanoseconds. * Yes, the timerval has unsigned components, but nanoseconds take only * 30 bits, and our CPU usage would have to be over 68 years for the * seconds to overflow 31 bits. */ StgByteArray getCPUTime(StgByteArray cpuStruct) { StgInt *cpu=(StgInt *)cpuStruct; /* getrusage() is right royal pain to deal with when targetting multiple versions of Solaris, since some versions supply it in libc (2.3 and 2.5), while 2.4 has got it in libucb (I wouldn't be too surprised if it was back again in libucb in 2.6..) Avoid the problem by resorting to times() instead. */ #if defined(HAVE_GETRUSAGE) && ! irix_TARGET_OS && ! solaris2_TARGET_OS struct rusage t; getrusage(RUSAGE_SELF, &t); cpu[0] = t.ru_utime.tv_sec; cpu[1] = 1000 * t.ru_utime.tv_usec; cpu[2] = t.ru_stime.tv_sec; cpu[3] = 1000 * t.ru_stime.tv_usec; #else # if defined(HAVE_TIMES) struct tms t; # if defined(CLK_TCK) # define ticks CLK_TCK # else long ticks; ticks = sysconf(_SC_CLK_TCK); # endif times(&t); cpu[0] = t.tms_utime / ticks; cpu[1] = (t.tms_utime - cpu[0] * ticks) * (1000000000 / ticks); cpu[2] = t.tms_stime / ticks; cpu[3] = (t.tms_stime - cpu[2] * ticks) * (1000000000 / ticks); # else return NULL; # endif #endif return (StgByteArray) cpuStruct; } \end{code}