summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorEmery Hemingway <ehmry@posteo.net>2018-11-26 17:00:17 +0100
committerAndreas Rumpf <rumpf_a@web.de>2018-11-26 17:00:17 +0100
commited8b4befbf3161c887f7b882ac6858708b67a503 (patch)
treea2f6c408d8bbf7d422b5185e5d20ebfa0b51d2da /lib/pure
parentac56d3b0ede8d3bf42be6a8c014288baeab1907d (diff)
downloadNim-ed8b4befbf3161c887f7b882ac6858708b67a503.tar.gz
times: use clock_gettime for cpuTime with POSIX (#9793)
The POSIX 'clock()' procedure returns process CPU time in an
implementation specific unit, which for historical reasons can be as
large as ~7ms in the case of FreeBSD. Use 'clock_gettime' for higher
accuracy.
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/times.nim16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index fd1a6acc5..71934a466 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -158,7 +158,9 @@ when defined(posix):
 
   type CTime = posix.Time
 
-  var CLOCK_REALTIME {.importc: "CLOCK_REALTIME", header: "<time.h>".}: Clockid
+  var
+    realTimeClockId {.importc: "CLOCK_REALTIME", header: "<time.h>".}: Clockid
+    cpuClockId {.importc: "CLOCK_THREAD_CPUTIME_ID", header: "<time.h>".}: Clockid
 
   proc gettimeofday(tp: var Timeval, unused: pointer = nil) {.
     importc: "gettimeofday", header: "<sys/time.h>".}
@@ -1065,7 +1067,7 @@ proc getTime*(): Time {.tags: [TimeEffect], benign.} =
     result = initTime(a.tv_sec.int64, convert(Microseconds, Nanoseconds, a.tv_usec.int))
   elif defined(posix):
     var ts: Timespec
-    discard clock_gettime(CLOCK_REALTIME, ts)
+    discard clock_gettime(realTimeClockId, ts)
     result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
   elif defined(windows):
     var f: FILETIME
@@ -2337,7 +2339,15 @@ when not defined(JS):
           fib.add(fib[^1] + fib[^2])
         echo "CPU time [s] ", cpuTime() - t0
         echo "Fib is [s] ", fib
-      result = toFloat(int(getClock())) / toFloat(clocksPerSec)
+      when defined(posix):
+        # 'clocksPerSec' is a compile-time constant, possibly a
+        # rather awful one, so use clock_gettime instead
+        var ts: Timespec
+        discard clock_gettime(cpuClockId, ts)
+        result = toFloat(ts.tv_sec.int) +
+          toFloat(ts.tv_nsec.int) / 1_000_000_000
+      else:
+        result = toFloat(int(getClock())) / toFloat(clocksPerSec)
 
     proc epochTime*(): float {.rtl, extern: "nt$1", tags: [TimeEffect].} =
       ## gets time after the UNIX epoch (1970) in seconds. It is a float