X-Git-Url: https://unix4lyfe.org/gitweb/darkstat-debian/blobdiff_plain/53d9d497ad0dcb0c37efb23a5468762355db6512..HEAD:/now.c diff --git a/now.c b/now.c index f0751a8..b1a43cb 100644 --- a/now.c +++ b/now.c @@ -1,5 +1,5 @@ /* darkstat 3 - * copyright (c) 2012 Emil Mikulic. + * copyright (c) 2012-2014 Emil Mikulic. * * now.c: a cache of the current time. * @@ -17,57 +17,58 @@ */ #include "err.h" #include "now.h" +#include "str.h" #include #include #include -#ifdef __MACH__ +#if defined(__MACH__) && !defined(__gnu_hurd__) /* Fake up clock_gettime() on OS X. */ -# include -# include -# include -# include - -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 +# include +# include +# include + + 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; } @@ -80,6 +81,17 @@ static int before(const struct timespec *a, const struct timespec *b) { 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) { @@ -87,12 +99,7 @@ static void clock_update(const clockid_t clk_id, 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)); } @@ -113,14 +120,14 @@ void now_update(void) { 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) { @@ -133,20 +140,24 @@ static int64_t ts_diff(const struct timespec * const a, 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: */