From 426a3f8468f650bbd75d4bf60019861bf7cf79e3 Mon Sep 17 00:00:00 2001
From: TQ Hirsch <thequux@upstandinghackers.com>
Date: Thu, 13 Mar 2014 17:48:39 +0000
Subject: [PATCH] Ported to NetBSD (1/2): Replaced Linux-specific timer call

CLOCK_THREAD_CPUTIME_ID is a linux-specific timer. On NetBSD, the best
way to get timer information appears to be getrusage, which happens to
be fairly cross-platform.
---
 src/benchmark.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/benchmark.c b/src/benchmark.c
index a3f292e..632d7db 100644
--- a/src/benchmark.c
+++ b/src/benchmark.c
@@ -10,7 +10,13 @@
 #include <mach/mach.h>
 #endif
 
+#ifdef __NetBSD__
+#include <sys/resource.h>
+#endif
+
 void h_benchmark_clock_gettime(struct timespec *ts) {
+  if (ts == NULL)
+    return;
 #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
   /* 
    * This returns real time, not CPU time. See http://stackoverflow.com/a/6725161
@@ -23,6 +29,18 @@ void h_benchmark_clock_gettime(struct timespec *ts) {
   mach_port_deallocate(mach_task_self(), cclock);
   ts->tv_sec = mts.tv_sec;
   ts->tv_nsec = mts.tv_nsec;
+#elif defined(__NetBSD__)
+  // NetBSD doesn't have CLOCK_THREAD_CPUTIME_ID. We'll use getrusage instead
+  struct rusage rusage;
+  getrusage(RUSAGE_SELF, &rusage);
+  ts->tv_nsec = (rusage.ru_utime.tv_usec + rusage.ru_stime.tv_usec) * 1000;
+  // not going to overflow; can be at most 2e9-2
+  ts->tv_sec = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_sec;
+  if (ts->tv_nsec >= 1000000000) {
+    ts->tv_nsec -=   1000000000; // subtract a second
+    ts->tv_sec += 1; // add it back.
+  }
+  assert (ts->tv_nsec <= 1000000000);
 #else
   clock_gettime(CLOCK_THREAD_CPUTIME_ID, ts);
 #endif
-- 
GitLab