X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftime%2Ftime.c;h=d0542f5654e86f06e69bc40c530ce0c989643e92;hb=80e95491125b762e46fa4295cafb43fe21e15136;hp=a6960335a50c814610ec1548a041644da4f81948;hpb=2a91b14cf2eea39b32d17a0ab14dd7243f36b79f;p=ccan diff --git a/ccan/time/time.c b/ccan/time/time.c index a6960335..d0542f56 100644 --- a/ccan/time/time.c +++ b/ccan/time/time.c @@ -3,95 +3,47 @@ #include #include -#ifdef DEBUG -#include -#define TIME_CHECK(t) time_check((t), __FILE__ ":" stringify(__LINE__)) -#else -#define TIME_CHECK(t) (t) -#endif - -#if !HAVE_CLOCK_GETTIME && !HAVE_CLOCK_GETTIME_IN_LIBRT +#if !HAVE_CLOCK_GETTIME #include -struct timespec time_now(void) +struct timeabs time_now(void) { struct timeval now; - struct timespec ret; + struct timeabs ret; gettimeofday(&now, NULL); - ret.tv_sec = now.tv_sec; - ret.tv_nsec = now.tv_usec * 1000; - return TIME_CHECK(ret); + ret.ts.tv_sec = now.tv_sec; + ret.ts.tv_nsec = now.tv_usec * 1000; + return TIMEABS_CHECK(ret); } #else #include -struct timespec time_now(void) -{ - struct timespec ret; - clock_gettime(CLOCK_REALTIME, &ret); - return TIME_CHECK(ret); -} -#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT */ - -bool time_greater(struct timespec a, struct timespec b) -{ - if (TIME_CHECK(a).tv_sec > TIME_CHECK(b).tv_sec) - return true; - else if (a.tv_sec < b.tv_sec) - return false; - - return a.tv_nsec > b.tv_nsec; -} - -bool time_less(struct timespec a, struct timespec b) +struct timeabs time_now(void) { - if (TIME_CHECK(a).tv_sec < TIME_CHECK(b).tv_sec) - return true; - else if (a.tv_sec > b.tv_sec) - return false; - - return a.tv_nsec < b.tv_nsec; + struct timeabs ret; + clock_gettime(CLOCK_REALTIME, &ret.ts); + return TIMEABS_CHECK(ret); } +#endif /* HAVE_CLOCK_GETTIME */ -bool time_eq(struct timespec a, struct timespec b) +struct timemono time_mono(void) { - return TIME_CHECK(a).tv_sec == TIME_CHECK(b).tv_sec && a.tv_nsec == b.tv_nsec; + struct timemono ret; +#ifdef TIME_HAVE_MONOTONIC + clock_gettime(CLOCK_MONOTONIC, &ret.ts); +#else /* Best we can do */ + ret.ts = time_now().ts; +#endif /* !HAVE_TIME_MONOTONIC */ + return ret; } -struct timespec time_sub(struct timespec recent, struct timespec old) +struct timerel time_divide(struct timerel t, unsigned long div) { - struct timespec diff; - - diff.tv_sec = TIME_CHECK(recent).tv_sec - TIME_CHECK(old).tv_sec; - if (old.tv_nsec > recent.tv_nsec) { - diff.tv_sec--; - diff.tv_nsec = 1000000000 + recent.tv_nsec - old.tv_nsec; - } else - diff.tv_nsec = recent.tv_nsec - old.tv_nsec; - - return TIME_CHECK(diff); -} - -struct timespec time_add(struct timespec a, struct timespec b) -{ - struct timespec sum; - - sum.tv_sec = TIME_CHECK(a).tv_sec + TIME_CHECK(b).tv_sec; - sum.tv_nsec = a.tv_nsec + b.tv_nsec; - if (sum.tv_nsec >= 1000000000) { - sum.tv_sec++; - sum.tv_nsec -= 1000000000; - } - return TIME_CHECK(sum); -} - -struct timespec time_divide(struct timespec t, unsigned long div) -{ - struct timespec res; + struct timerel res; uint64_t rem, ns; /* Dividing seconds is simple. */ - res.tv_sec = TIME_CHECK(t).tv_sec / div; - rem = t.tv_sec % div; + res.ts.tv_sec = TIMEREL_CHECK(t).ts.tv_sec / div; + rem = t.ts.tv_sec % div; /* If we can't fit remainder * 1,000,000,000 in 64 bits? */ #if 0 /* ilog is great, but we use fp for multiply anyway. */ @@ -104,88 +56,37 @@ struct timespec time_divide(struct timespec t, unsigned long div) #endif if (rem & ~(((uint64_t)1 << 30) - 1)) { /* FIXME: fp is cheating! */ - double nsec = rem * 1000000000.0 + t.tv_nsec; - res.tv_nsec = nsec / div; + double nsec = rem * 1000000000.0 + t.ts.tv_nsec; + res.ts.tv_nsec = nsec / div; } else { - ns = rem * 1000000000 + t.tv_nsec; - res.tv_nsec = ns / div; + ns = rem * 1000000000 + t.ts.tv_nsec; + res.ts.tv_nsec = ns / div; } - return TIME_CHECK(res); + return TIMEREL_CHECK(res); } -struct timespec time_multiply(struct timespec t, unsigned long mult) +struct timerel time_multiply(struct timerel t, unsigned long mult) { - struct timespec res; + struct timerel res; /* Are we going to overflow if we multiply nsec? */ if (mult & ~((1UL << 30) - 1)) { /* FIXME: fp is cheating! */ - double nsec = (double)t.tv_nsec * mult; + double nsec = (double)t.ts.tv_nsec * mult; - res.tv_sec = nsec / 1000000000.0; - res.tv_nsec = nsec - (res.tv_sec * 1000000000.0); + res.ts.tv_sec = nsec / 1000000000.0; + res.ts.tv_nsec = nsec - (res.ts.tv_sec * 1000000000.0); } else { - uint64_t nsec = t.tv_nsec * mult; + uint64_t nsec = t.ts.tv_nsec * mult; - res.tv_nsec = nsec % 1000000000; - res.tv_sec = nsec / 1000000000; + res.ts.tv_nsec = nsec % 1000000000; + res.ts.tv_sec = nsec / 1000000000; } - res.tv_sec += TIME_CHECK(t).tv_sec * mult; - return TIME_CHECK(res); + res.ts.tv_sec += TIMEREL_CHECK(t).ts.tv_sec * mult; + return TIMEREL_CHECK(res); } -uint64_t time_to_msec(struct timespec t) -{ - uint64_t msec; - - msec = TIME_CHECK(t).tv_nsec / 1000000 + (uint64_t)t.tv_sec * 1000; - return msec; -} - -uint64_t time_to_usec(struct timespec t) -{ - uint64_t usec; - - usec = TIME_CHECK(t).tv_nsec / 1000 + (uint64_t)t.tv_sec * 1000000; - return usec; -} - -uint64_t time_to_nsec(struct timespec t) -{ - uint64_t nsec; - - nsec = TIME_CHECK(t).tv_nsec + (uint64_t)t.tv_sec * 1000000000; - return nsec; -} - -struct timespec time_from_msec(uint64_t msec) -{ - struct timespec t; - - t.tv_nsec = (msec % 1000) * 1000000; - t.tv_sec = msec / 1000; - return TIME_CHECK(t); -} - -struct timespec time_from_usec(uint64_t usec) -{ - struct timespec t; - - t.tv_nsec = (usec % 1000000) * 1000; - t.tv_sec = usec / 1000000; - return TIME_CHECK(t); -} - -struct timespec time_from_nsec(uint64_t nsec) -{ - struct timespec t; - - t.tv_nsec = nsec % 1000000000; - t.tv_sec = nsec / 1000000000; - return TIME_CHECK(t); -} - -struct timespec time_check(struct timespec t, const char *abortstr) +struct timespec time_check_(struct timespec t, const char *abortstr) { if (t.tv_sec < 0 || t.tv_nsec >= 1000000000) { if (abortstr) { @@ -211,3 +112,19 @@ struct timespec time_check(struct timespec t, const char *abortstr) } return t; } + +struct timerel timerel_check(struct timerel t, const char *abortstr) +{ + struct timerel ret; + + ret.ts = time_check_(t.ts, abortstr); + return ret; +} + +struct timeabs timeabs_check(struct timeabs t, const char *abortstr) +{ + struct timeabs ret; + + ret.ts = time_check_(t.ts, abortstr); + return ret; +}