+
+inline void os_get_clock(struct timespec *ts)
+{
+#if defined(__MACH__) && defined(__APPLE__)
+// From http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
+// OS X does not have clock_gettime, use clock_get_time
+ clock_serv_t cclock;
+ mach_timespec_t mts;
+ host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
+ clock_get_time(cclock, &mts);
+ mach_port_deallocate(mach_task_self(), cclock);
+ ts->tv_sec = mts.tv_sec;
+ ts->tv_nsec = mts.tv_nsec;
+#elif defined(CLOCK_MONOTONIC_RAW)
+ clock_gettime(CLOCK_MONOTONIC_RAW, ts);
+#elif defined(_POSIX_MONOTONIC_CLOCK)
+ clock_gettime(CLOCK_MONOTONIC, ts);
+#else
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ TIMEVAL_TO_TIMESPEC(&tv, ts);
+#endif
+}
+
+inline u64 getTimeS()
+{
+ struct timespec ts;
+ os_get_clock(&ts);
+ return ts.tv_sec;
+}
+
+inline u64 getTimeMs()
+{
+ struct timespec ts;
+ os_get_clock(&ts);
+ return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
+}
+
+inline u64 getTimeUs()
+{
+ struct timespec ts;
+ os_get_clock(&ts);
+ return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
+}
+
+inline u64 getTimeNs()
+{
+ struct timespec ts;
+ os_get_clock(&ts);
+ return ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+#endif
+
+inline u64 getTime(TimePrecision prec)
+{
+ switch (prec) {
+ case PRECISION_SECONDS: return getTimeS();
+ case PRECISION_MILLI: return getTimeMs();
+ case PRECISION_MICRO: return getTimeUs();
+ case PRECISION_NANO: return getTimeNs();