+
+/* like gettimeofday, except with nanoseconds */
+inline
+int gettimespecofday(struct timespec *ts) {
+ int retval = 0;
+#ifdef __MACH__
+ 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;
+#else /* __MACH__ */
+ retval = clock_gettime(CLOCK_REALTIME, ts);
+#endif /* __MACH__ */
+
+ return retval;
+}
+
+inline
+int timespec_add(struct timespec *result, const struct timespec *x) {
+ result->tv_sec += x->tv_sec;
+ result->tv_nsec += x->tv_nsec;
+
+ result->tv_sec += result->tv_nsec / 1000000000;
+ result->tv_nsec %= 1000000000;
+
+ return 0;
+}
+
+inline
+int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y) {
+ if (x->tv_nsec < y->tv_nsec) {
+ int z = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
+ y->tv_nsec -= 1000000000 * z;
+ y->tv_sec += z;
+ }
+ if (x->tv_nsec - y->tv_nsec > 1000000000) {
+ int z = (x->tv_nsec - y->tv_nsec) / 1000000000;
+ y->tv_nsec += 1000000000 * z;
+ y->tv_sec -= z;
+ }
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_nsec = x->tv_nsec - y->tv_nsec;
+
+ return x->tv_sec < y->tv_sec;
+}
+
+int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
+ /* Perform the carry for the later subtraction by updating y. */
+ if (x->tv_usec < y->tv_usec) {
+ int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+ y->tv_usec -= 1000000 * nsec;
+ y->tv_sec += nsec;
+ }
+ if (x->tv_usec - y->tv_usec > 1000000) {
+ int nsec = (x->tv_usec - y->tv_usec) / 1000000;
+ y->tv_usec += 1000000 * nsec;
+ y->tv_sec -= nsec;
+ }
+
+ /* Compute the time remaining to wait.
+ tv_usec is certainly positive. */
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_usec = x->tv_usec - y->tv_usec;
+
+ /* Return 1 if result is negative. */
+ return x->tv_sec < y->tv_sec;
+}