X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftimer%2Ftimer.h;h=5c40a3bbc1c9979251ad5c2b76ca6a0443c5926a;hb=f08b8139fc7370224c59bc3178b887810b98592b;hp=7b5d199470c49e829aa19c0363eaa715c6324fee;hpb=606cca7b0ed5236d1df1c4436ca79db6e3fd5321;p=ccan diff --git a/ccan/timer/timer.h b/ccan/timer/timer.h index 7b5d1994..5c40a3bb 100644 --- a/ccan/timer/timer.h +++ b/ccan/timer/timer.h @@ -5,10 +5,15 @@ #include #include +#ifndef TIMER_GRANULARITY /* We divide all nsec values by 1000, reducing it to usec granularity. */ #define TIMER_GRANULARITY 1000 -/* This gives 16 pointers per level, up to 13 levels deep. */ -#define TIMER_LEVEL_BITS 4 +#endif + +#ifndef TIMER_LEVEL_BITS +/* This gives 32 pointers per level, up to 13 levels deep. */ +#define TIMER_LEVEL_BITS 5 +#endif struct timers; struct timer; @@ -20,69 +25,124 @@ struct timer; * * This sets up a timers struct: any timers added before @start will be * set to expire immediately. + * + * Example: + * struct timers timeouts; + * + * timers_init(&timeouts, time_mono()); */ -void timers_init(struct timers *timers, struct timespec start); +void timers_init(struct timers *timers, struct timemono start); /** * timers_cleanup - free allocations within timers struct. * @timers: the struct timers * * This frees any timer layers allocated during use. + * + * Example: + * timers_cleanup(&timeouts); */ void timers_cleanup(struct timers *timers); /** - * timer_add - insert a timer. + * timer_init - initialize a timer. + * @timer: the timer to initialize + * + * Example: + * struct timer t; + * + * timer_init(&t); + */ +void timer_init(struct timer *t); + +/** + * timer_addrel - insert a relative timer. * @timers: the struct timers - * @timer: the (uninitialized) timer to add - * @when: when @timer expires. + * @timer: the (initialized or timer_del'd) timer to add + * @rel: when @timer expires (relative). + * + * This efficiently adds @timer to @timers, to expire @rel (rounded to + * TIMER_GRANULARITY nanoseconds) after the current time. This + * is a convenient wrapper around timer_addmono(). + * + * Example: + * // Timeout in 100ms. + * timer_addrel(&timeouts, &t, time_from_msec(100)); + */ +void timer_addrel(struct timers *timers, struct timer *timer, struct timerel rel); + +/** + * timer_addmono - insert an absolute timer. + * @timers: the struct timers + * @timer: the (initialized or timer_del'd) timer to add + * @when: when @timer expires (absolute). * * This efficiently adds @timer to @timers, to expire @when (rounded to * TIMER_GRANULARITY nanoseconds). + * + * Note that if @when is before time_mono(), then it will be set to expire + * immediately. + * + * Example: + * // Timeout in 100ms. + * timer_addmono(&timeouts, &t, timemono_add(time_mono(), time_from_msec(100))); */ -void timer_add(struct timers *timers, struct timer *timer, - struct timespec when); +void timer_addmono(struct timers *timers, struct timer *timer, + struct timemono when); /** - * timer_del - remove an unexpired timer. + * timer_del - remove a timer. * @timers: the struct timers - * @timer: the timer previously added with timer_add() + * @timer: the timer * - * This efficiently removes @timer from @timers. + * This efficiently removes @timer from @timers, if timer_add() was + * called. It can be called multiple times without bad effect, and + * can be called any time after timer_init(). + * + * Example: + * timer_del(&timeouts, &t); */ void timer_del(struct timers *timers, struct timer *timer); /** * timer_earliest - find out the first time when a timer will expire * @timers: the struct timers - * @first: the time, only set if there is a timer. + * @first: the expiry time, only set if there is a timer. * * This returns false, and doesn't alter @first if there are no * timers. Otherwise, it sets @first to the expiry time of the first * timer (rounded to TIMER_GRANULARITY nanoseconds), and returns true. + * + * Example: + * struct timemono next = { { (time_t)-1ULL, -1UL } }; + * timer_earliest(&timeouts, &next); */ -bool timer_earliest(const struct timers *timers, struct timespec *first); +bool timer_earliest(struct timers *timers, struct timemono *first); /** - * timer_expire - update timers structure and remove expired timers. + * timers_expire - update timers structure and remove one expire timer. * @timers: the struct timers * @expire: the current time - * @list: the list for expired timers. * - * @list will be initialized to the empty list, then all timers added - * with a @when arg less than or equal to @expire will be added to it in - * expiry order (within TIMER_GRANULARITY nanosecond precision). + * A timers added with a @when arg less than or equal to @expire will be + * returned (within TIMER_GRANULARITY nanosecond precision). If + * there are no timers due to expire, NULL is returned. * - * After this, @expire is considered the current time, and adding any - * timers with @when before this value will be silently changed to - * adding them with immediate expiration. + * After this returns NULL, @expire is considered the current time, + * and adding any timers with @when before this value will be silently + * changed to adding them with immediate expiration. * * You should not move @expire backwards, though it need not move * forwards. + * + * Example: + * struct timer *expired; + * + * while ((expired = timers_expire(&timeouts, time_mono())) != NULL) + * printf("Timer expired!\n"); + * */ -void timers_expire(struct timers *timers, - struct timespec expire, - struct list_head *list); +struct timer *timers_expire(struct timers *timers, struct timemono expire); /** * timers_check - check timer structure for consistency @@ -96,6 +156,9 @@ void timers_expire(struct timers *timers, * * Returns the timers struct if it is consistent, NULL if not (it can * never return NULL if @abortstr is set). + * + * Example: + * timers_check(&timeouts, "After timer_expire"); */ struct timers *timers_check(const struct timers *t, const char *abortstr); @@ -122,7 +185,12 @@ void timers_dump(const struct timers *timers, FILE *fp); struct timers { /* Far in the future. */ struct list_head far; + /* Current time. */ uint64_t base; + /* Overall first value. */ + uint64_t first; + /* First value in each level (plus 1 for far list) */ + uint64_t firsts[(64 + TIMER_LEVEL_BITS-1) / TIMER_LEVEL_BITS + 1]; struct timer_level *level[(64 + TIMER_LEVEL_BITS-1) / TIMER_LEVEL_BITS]; };