X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftime%2Ftime.h;h=70ebdc9a7751ca5be434329421618c58f177c9c7;hp=46568425c7cd44594e3964d3f8435f316d11eed4;hb=615189ae6de685ae6eb5a19b877340d731bba747;hpb=95ff2139520130dd98a0503e3c4f441c69a68f5a diff --git a/ccan/time/time.h b/ccan/time/time.h index 46568425..70ebdc9a 100644 --- a/ccan/time/time.h +++ b/ccan/time/time.h @@ -22,10 +22,13 @@ struct timespec { timerel_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ") #define TIMEABS_CHECK(t) \ timeabs_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ") +#define TIMEMONO_CHECK(t) \ + timemono_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ") #else #define TIME_CHECK(t) (t) #define TIMEREL_CHECK(t) (t) #define TIMEABS_CHECK(t) (t) +#define TIMEMONO_CHECK(t) (t) #endif /** @@ -66,7 +69,7 @@ struct timemono { * 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) +#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC) #define TIME_HAVE_MONOTONIC 1 #endif @@ -95,7 +98,7 @@ struct timerel timerel_check(struct timerel in, const char *abortstr); /** * timeabs_check - check if an absolute time is malformed. - * @in: the relative time to check (returned) + * @in: the absolute time to check (returned) * @abortstr: the string to print to stderr before aborting (if set). * * This can be used to make sure a time isn't negative and doesn't @@ -113,6 +116,26 @@ struct timerel timerel_check(struct timerel in, const char *abortstr); */ struct timeabs timeabs_check(struct timeabs in, const char *abortstr); +/** + * timemono_check - check if a monotonic time is malformed. + * @in: the monotonic time to check (returned) + * @abortstr: the string to print to stderr before aborting (if set). + * + * This can be used to make sure a time isn't negative and doesn't + * have a tv_nsec >= 1000000000. If it is, and @abortstr is non-NULL, + * that will be printed and abort() is called. Otherwise, if + * @abortstr is NULL then the returned timemono will be normalized and + * tv_sec set to 0 if it was negative. + * + * Note that if ccan/time is compiled with DEBUG, then it will call this + * for all passed and returned times. + * + * Example: + * printf("Now is %lu seconds since mono start\n", + * (long)timemono_check(time_mono(), "time_mono failed?").ts.tv_sec); + */ +struct timemono timemono_check(struct timemono in, const char *abortstr); + /** * time_now - return the current time * @@ -127,7 +150,7 @@ struct timeabs time_now(void); * This value is only really useful for measuring time intervals. * * See also: - * time_since() + * timemono_since() */ struct timemono time_mono(void); @@ -231,6 +254,32 @@ static inline bool timeabs_eq(struct timeabs a, struct timeabs b) && a.ts.tv_nsec == b.ts.tv_nsec; } +/** + * timemono_eq - is a equal to b? + * @a: one monotonic time. + * @b: another monotonic time. + * + * Example: + * #include + * #include + * + * // Can we fork in under a nanosecond? + * static bool fast_fork(void) + * { + * struct timemono start = time_mono(); + * if (fork() != 0) { + * exit(0); + * } + * wait(NULL); + * return timemono_eq(start, time_mono()); + * } + */ +static inline bool timemono_eq(struct timemono a, struct timemono b) +{ + return TIMEMONO_CHECK(a).ts.tv_sec == TIMEMONO_CHECK(b).ts.tv_sec + && a.ts.tv_nsec == b.ts.tv_nsec; +} + /** * timerel_eq - is a equal to b? * @a: one relative time. @@ -249,7 +298,7 @@ static inline bool timeabs_eq(struct timeabs a, struct timeabs b) * exit(0); * } * wait(NULL); - * diff = time_between(start, time_now()); + * diff = time_between(time_now(), start); * return timerel_eq(diff, zero); * } */ @@ -320,6 +369,17 @@ static inline struct timerel timemono_between(struct timemono recent, return t; } +/** + * timemono_since - elapsed monotonic time since @old + * @old: a monotonic time from the past. + */ +static inline struct timerel timemono_since(struct timemono old) +{ + struct timemono now = time_mono(); + + return timemono_between(now, TIMEMONO_CHECK(old)); +} + /** * timeabs_sub - subtract a relative time from an absolute time * @abs: the absolute time. @@ -377,6 +437,28 @@ static inline struct timeabs timeabs_add(struct timeabs a, struct timerel b) return t; } +/** + * timemono_add - add a relative to a monotonic time + * @a: the monotonic time. + * @b: a relative time. + * + * The times must not overflow, or the results are undefined. + * + * Example: + * // We do one every second. + * static struct timemono next_timem(void) + * { + * return timemono_add(time_mono(), time_from_msec(1000)); + * } + */ +static inline struct timemono timemono_add(struct timemono a, struct timerel b) +{ + struct timemono t; + + t.ts = time_add_(a.ts, b.ts); + return t; +} + /** * timerel_add - add two relative times * @a: one relative time.