From: Rusty Russell Date: Wed, 4 Jun 2014 03:43:19 +0000 (+0930) Subject: time: time_mono() helpers. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=95ff2139520130dd98a0503e3c4f441c69a68f5a time: time_mono() helpers. From patch by David Gibson, rewritten on new ccan/time. Signed-off-by: Rusty Russell --- diff --git a/ccan/time/test/run-monotonic.c b/ccan/time/test/run-monotonic.c new file mode 100644 index 00000000..ed70f3db --- /dev/null +++ b/ccan/time/test/run-monotonic.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(void) +{ + struct timemono t1, t2; + struct timerel t3; + + plan_tests(2); + + /* Test time_mono */ + t1 = time_mono(); + t2 = time_mono(); + + ok1(!time_less_(t2.ts, t1.ts)); + + t3.ts.tv_sec = 1; + t3.ts.tv_nsec = 0; + + ok1(time_less(timemono_between(t1, t2), t3)); + + return exit_status(); +} diff --git a/ccan/time/time.c b/ccan/time/time.c index 54cb3f4b..8e7fbffe 100644 --- a/ccan/time/time.c +++ b/ccan/time/time.c @@ -25,6 +25,17 @@ struct timeabs time_now(void) } #endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT */ +struct timemono time_mono(void) +{ + 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 timerel time_divide(struct timerel t, unsigned long div) { struct timerel res; diff --git a/ccan/time/time.h b/ccan/time/time.h index 7bb3547d..46568425 100644 --- a/ccan/time/time.h +++ b/ccan/time/time.h @@ -48,6 +48,28 @@ struct timeabs { struct timespec ts; }; +/** + * struct timemono - a monotonic time. + * @ts: the actual timespec value. + * + * This comes from the monotonic clock (if available), so it's useful + * for measuring intervals as it won't change even if the system clock + * is moved for some reason. + */ +struct timemono { + struct timespec ts; +}; + +/** + * TIME_HAVE_MONOTONIC - defined if we really have a monotonic clock. + * + * Otherwise time_mono() just refers to time_now(). Your code might + * test this if you really need a monotonic clock. + */ +#if (HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT) && defined(CLOCK_MONOTONIC) +#define TIME_HAVE_MONOTONIC 1 +#endif + struct timespec time_check_(struct timespec in, const char *abortstr); /** @@ -99,6 +121,16 @@ struct timeabs timeabs_check(struct timeabs in, const char *abortstr); */ struct timeabs time_now(void); +/** + * time_mono - return the current monotonic time + * + * This value is only really useful for measuring time intervals. + * + * See also: + * time_since() + */ +struct timemono time_mono(void); + static inline bool time_greater_(struct timespec a, struct timespec b) { if (TIME_CHECK(a).tv_sec > TIME_CHECK(b).tv_sec) @@ -272,6 +304,22 @@ static inline struct timerel time_between(struct timeabs recent, struct timeabs return t; } +/** + * timemono_between - time between two monotonic times + * @recent: the larger time. + * @old: the smaller time. + * + * This returns a well formed struct timerel of @recent - @old. + */ +static inline struct timerel timemono_between(struct timemono recent, + struct timemono old) +{ + struct timerel t; + + t.ts = time_sub_(recent.ts, old.ts); + return t; +} + /** * timeabs_sub - subtract a relative time from an absolute time * @abs: the absolute time.