summaryrefslogtreecommitdiff
path: root/rts/posix/GetTime.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-09-13 13:38:18 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-09-13 13:38:18 +0000
commit5e195173cd1921e838eb977f649ef178dff00415 (patch)
treef74fb4521b4952c3041567de6f192d2a7fa77e94 /rts/posix/GetTime.c
parentabe2139ead3ec4aac34fee740eff89f1c50ccb56 (diff)
downloadhaskell-5e195173cd1921e838eb977f649ef178dff00415.tar.gz
Use clock_gettime (if available) to measure the process CPU time
This is much more accurate than getrusage, which was giving misleading results when trying to time very quick operations like a minor GC.
Diffstat (limited to 'rts/posix/GetTime.c')
-rw-r--r--rts/posix/GetTime.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c
index 939eef177e..39465cb664 100644
--- a/rts/posix/GetTime.c
+++ b/rts/posix/GetTime.c
@@ -46,10 +46,32 @@
Ticks getProcessCPUTime(void)
{
- struct rusage t;
- getrusage(RUSAGE_SELF, &t);
- return ((Ticks)t.ru_utime.tv_sec * TICKS_PER_SECOND +
- ((Ticks)t.ru_utime.tv_usec * TICKS_PER_SECOND)/1000000);
+#if !defined(BE_CONSERVATIVE) && defined(HAVE_CLOCK_GETTIME) && defined (_SC_CPUTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) && defined(HAVE_SYSCONF)
+ static int checked_sysconf = 0;
+ static int sysconf_result = 0;
+
+ if (!checked_sysconf) {
+ sysconf_result = sysconf(_SC_CPUTIME);
+ checked_sysconf = 1;
+ }
+ if (sysconf_result != -1) {
+ struct timespec ts;
+ int res;
+ res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
+ if (res == 0) {
+ return ((Ticks)ts.tv_sec * TICKS_PER_SECOND +
+ ((Ticks)ts.tv_nsec * TICKS_PER_SECOND) / 1000000000);
+ }
+ }
+#endif
+
+ // fallback to getrusage
+ {
+ struct rusage t;
+ getrusage(RUSAGE_SELF, &t);
+ return ((Ticks)t.ru_utime.tv_sec * TICKS_PER_SECOND +
+ ((Ticks)t.ru_utime.tv_usec * TICKS_PER_SECOND)/1000000);
+ }
}
Ticks getProcessElapsedTime(void)