diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-09-13 13:38:18 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-09-13 13:38:18 +0000 |
commit | 5e195173cd1921e838eb977f649ef178dff00415 (patch) | |
tree | f74fb4521b4952c3041567de6f192d2a7fa77e94 /rts | |
parent | abe2139ead3ec4aac34fee740eff89f1c50ccb56 (diff) | |
download | haskell-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')
-rw-r--r-- | rts/posix/GetTime.c | 30 |
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) |