/* darkstat 3
- * copyright (c) 2012 Emil Mikulic.
+ * copyright (c) 2012-2014 Emil Mikulic.
*
* now.c: a cache of the current time.
*
*/
#include "err.h"
#include "now.h"
+#include "str.h"
#include <assert.h>
#include <string.h>
#include <time.h>
-#ifdef __MACH__
+#if defined(__MACH__) && !defined(__gnu_hurd__)
/* Fake up clock_gettime() on OS X. */
-# include <sys/time.h>
-# include <inttypes.h>
-# include <mach/mach.h>
-# include <mach/mach_time.h>
-
-typedef int clockid_t;
-#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
-
-static uint64_t mono_first = 0;
-
-int clock_gettime(clockid_t clk_id, struct timespec *tp) {
- if (clk_id == CLOCK_REALTIME) {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- tp->tv_sec = tv.tv_sec;
- tp->tv_nsec = tv.tv_usec * 1000;
- return 0;
- }
- if (clk_id == CLOCK_MONOTONIC) {
- uint64_t t = mach_absolute_time();
- mach_timebase_info_data_t timebase;
- mach_timebase_info(&timebase);
- if (!mono_first) {
- mono_first = t;
+# include <sys/time.h>
+# include <inttypes.h>
+# include <mach/mach.h>
+# include <mach/mach_time.h>
+
+ typedef int clockid_t;
+# define CLOCK_REALTIME 0
+# define CLOCK_MONOTONIC 1
+
+ static uint64_t mono_first = 0;
+
+ int clock_gettime(clockid_t clk_id, struct timespec *tp) {
+ if (clk_id == CLOCK_REALTIME) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ tp->tv_sec = tv.tv_sec;
+ tp->tv_nsec = tv.tv_usec * 1000;
+ return 0;
+ }
+ if (clk_id == CLOCK_MONOTONIC) {
+ uint64_t t = mach_absolute_time();
+ mach_timebase_info_data_t timebase;
+ mach_timebase_info(&timebase);
+ if (!mono_first) {
+ mono_first = t;
+ }
+ uint64_t tdiff = (t - mono_first) * timebase.numer / timebase.denom;
+ tp->tv_sec = tdiff / 1000000000;
+ tp->tv_nsec = tdiff % 1000000000;
+ return 0;
}
- uint64_t tdiff = (t - mono_first) * timebase.numer / timebase.denom;
- tp->tv_sec = tdiff / 1000000000;
- tp->tv_nsec = tdiff % 1000000000;
- return 0;
+ return -1;
}
- return -1;
-}
#endif /* __MACH__ */
static struct timespec clock_real, clock_mono;
static int now_initialized = 0;
-long now_real(void) {
+time_t now_real(void) {
assert(now_initialized);
return clock_real.tv_sec;
}
-long now_mono(void) {
+time_t now_mono(void) {
assert(now_initialized);
return clock_mono.tv_sec;
}
return 0;
}
+static void warn_backwards(const char *name,
+ const struct timespec * const t0,
+ const struct timespec * const t1) {
+ verbosef("%s clock went backwards from %lld.%09lld to %lld.%09lld",
+ name,
+ (lld)t0->tv_sec,
+ (lld)t0->tv_nsec,
+ (lld)t1->tv_sec,
+ (lld)t1->tv_nsec);
+}
+
static void clock_update(const clockid_t clk_id,
struct timespec *dest,
const char *name) {
clock_gettime(clk_id, &t);
if (now_initialized && before(&t, dest)) {
- verbosef("%s clock went backwards from %ld.%09ld to %ld.%09ld",
- name,
- (long)dest->tv_sec,
- (long)dest->tv_nsec,
- (long)t.tv_sec,
- (long)t.tv_nsec);
+ warn_backwards(name, &t, dest);
}
memcpy(dest, &t, sizeof(t));
}
all_clocks_update();
}
-long mono_to_real(const long t) {
+time_t mono_to_real(const int64_t t) {
assert(now_initialized);
- return t - clock_mono.tv_sec + clock_real.tv_sec;
+ return (time_t)(t - (int64_t)clock_mono.tv_sec + (int64_t)clock_real.tv_sec);
}
-long real_to_mono(const long t) {
+int64_t real_to_mono(const time_t t) {
assert(now_initialized);
- return t - clock_real.tv_sec + clock_mono.tv_sec;
+ return (int64_t)(t - clock_real.tv_sec + clock_mono.tv_sec);
}
void timer_start(struct timespec *t) {
a->tv_nsec - b->tv_nsec;
}
-void timer_stop(const struct timespec * const t,
+void timer_stop(const struct timespec * const t0,
const int64_t nsec,
const char *warning) {
- struct timespec t2;
+ struct timespec t1;
int64_t diff;
- clock_gettime(CLOCK_MONOTONIC, &t2);
- diff = ts_diff(&t2, t);
- assert(diff > 0);
- if (diff > nsec)
+ clock_gettime(CLOCK_MONOTONIC, &t1);
+ if (before(&t1, t0)) {
+ warn_backwards("monotonic timer", t0, &t1);
+ return;
+ }
+ diff = ts_diff(&t1, t0);
+ if (diff > nsec) {
warnx("%s (took %lld nsec, over threshold of %lld nsec)",
warning,
- (long long)diff,
- (long long)nsec);
+ (lld)diff,
+ (lld)nsec);
+ }
}
/* vim:set ts=3 sw=3 tw=80 et: */