Use clock_gettime (if available) to measure the process CPU time
authorSimon Marlow <marlowsd@gmail.com>
Mon, 13 Sep 2010 13:38:18 +0000 (13:38 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Mon, 13 Sep 2010 13:38:18 +0000 (13:38 +0000)
This is much more accurate than getrusage, which was giving misleading
results when trying to time very quick operations like a minor GC.

rts/posix/GetTime.c

index 939eef1..39465cb 100644 (file)
 
 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)