1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 2005
5 * Machine-dependent time measurement functions
7 * ---------------------------------------------------------------------------*/
9 // Not POSIX, due to use of ru_majflt in getPageFaults()
10 // #include "PosixSource.h"
19 #ifdef HAVE_SYS_TIME_H
20 # include <sys/time.h>
23 #if HAVE_SYS_RESOURCE_H
24 # include <sys/resource.h>
31 #ifdef HAVE_SYS_TIMES_H
32 # include <sys/times.h>
39 #if ! ((defined(HAVE_GETRUSAGE) && !irix_HOST_OS) || defined(HAVE_TIMES))
40 #error No implementation for getProcessCPUTime() available.
43 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_GETRUSAGE) && !irix_HOST_OS
44 // we'll implement getProcessCPUTime() and getProcessElapsedTime()
45 // separately, using getrusage() and gettimeofday() respectively
47 Ticks getProcessCPUTime(void)
50 getrusage(RUSAGE_SELF, &t);
51 return ((Ticks)t.ru_utime.tv_sec * TICKS_PER_SECOND +
52 ((Ticks)t.ru_utime.tv_usec * TICKS_PER_SECOND)/1000000);
55 Ticks getProcessElapsedTime(void)
58 gettimeofday(&tv, (struct timezone *) NULL);
59 return ((Ticks)tv.tv_sec * TICKS_PER_SECOND +
60 ((Ticks)tv.tv_usec * TICKS_PER_SECOND)/1000000);
63 void getProcessTimes(Ticks *user, Ticks *elapsed)
65 *user = getProcessCPUTime();
66 *elapsed = getProcessElapsedTime();
69 #elif defined(HAVE_TIMES)
71 // we'll use the old times() API.
73 Ticks getProcessCPUTime(void)
75 #if !defined(THREADED_RTS) && USE_PAPI
77 if ((usec = PAPI_get_virt_usec()) < 0) {
78 barf("PAPI_get_virt_usec: %lld", usec);
80 return ((usec * TICKS_PER_SECOND) / 1000000);
83 getProcessTimes(&user,&elapsed);
88 Ticks getProcessElapsedTime(void)
91 getProcessTimes(&user,&elapsed);
95 void getProcessTimes(Ticks *user, Ticks *elapsed)
97 static nat ClockFreq = 0;
100 #if defined(HAVE_SYSCONF)
102 ticks = sysconf(_SC_CLK_TCK);
104 sysErrorBelch("sysconf");
105 stg_exit(EXIT_FAILURE);
108 #elif defined(CLK_TCK) /* defined by POSIX */
112 #elif defined(CLOCKS_PER_SEC)
113 ClockFreq = CLOCKS_PER_SEC;
115 errorBelch("can't get clock resolution");
116 stg_exit(EXIT_FAILURE);
121 clock_t r = times(&t);
122 *user = (((Ticks)t.tms_utime * TICKS_PER_SECOND) / ClockFreq);
123 *elapsed = (((Ticks)r * TICKS_PER_SECOND) / ClockFreq);
128 Ticks getThreadCPUTime(void)
132 if ((usec = PAPI_get_virt_usec()) < 0) {
133 barf("PAPI_get_virt_usec: %lld", usec);
135 return ((usec * TICKS_PER_SECOND) / 1000000);
137 #elif !defined(BE_CONSERVATIVE) && defined(HAVE_CLOCK_GETTIME) && defined (_POSIX_THREAD_CPUTIME) && defined(CLOCK_THREAD_CPUTIME_ID) && defined(HAVE_SYSCONF)
138 if (sysconf(_POSIX_THREAD_CPUTIME) != -1) {
139 // clock_gettime() gives us per-thread CPU time. It isn't
140 // reliable on Linux, but it's the best we have.
143 res = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
145 return ((Ticks)ts.tv_sec * TICKS_PER_SECOND +
146 ((Ticks)ts.tv_nsec * TICKS_PER_SECOND) / 1000000000);
150 return getProcessCPUTime();
156 #if !defined(HAVE_GETRUSAGE) || irix_HOST_OS || haiku_HOST_OS
160 getrusage(RUSAGE_SELF, &t);