timer: clean up hook allocator API
[ccan] / ccan / timer / timer.h
1 /* LGPL (v2.1 or any later version) - see LICENSE file for details */
2 #ifndef CCAN_TIMER_H
3 #define CCAN_TIMER_H
4 #include <ccan/time/time.h>
5 #include <ccan/list/list.h>
6 #include <stdint.h>
7
8 #ifndef TIMER_GRANULARITY
9 /* We divide all nsec values by 1000, reducing it to usec granularity. */
10 #define TIMER_GRANULARITY 1000
11 #endif
12
13 #ifndef TIMER_LEVEL_BITS
14 /* This gives 32 pointers per level, up to 13 levels deep. */
15 #define TIMER_LEVEL_BITS 5
16 #endif
17
18 struct timers;
19 struct timer;
20
21 /**
22  * timers_init - initialize a timers struct.
23  * @timers: the struct timers
24  * @start: the minimum time which will ever be added.
25  *
26  * This sets up a timers struct: any timers added before @start will be
27  * set to expire immediately.
28  *
29  * Example:
30  *      struct timers timeouts;
31  *
32  *      timers_init(&timeouts, time_mono());
33  */
34 void timers_init(struct timers *timers, struct timemono start);
35
36 /**
37  * timers_cleanup - free allocations within timers struct.
38  * @timers: the struct timers
39  *
40  * This frees any timer layers allocated during use.
41  *
42  * Example:
43  *      timers_cleanup(&timeouts);
44  */
45 void timers_cleanup(struct timers *timers);
46
47 /**
48  * timer_init - initialize a timer.
49  * @timer: the timer to initialize
50  *
51  * Example:
52  *      struct timer t;
53  *
54  *      timer_init(&t);
55  */
56 void timer_init(struct timer *t);
57
58 /**
59  * timer_addrel - insert a relative timer.
60  * @timers: the struct timers
61  * @timer: the (initialized or timer_del'd) timer to add
62  * @rel: when @timer expires (relative).
63  *
64  * This efficiently adds @timer to @timers, to expire @rel (rounded to
65  * TIMER_GRANULARITY nanoseconds) after the current time.  This
66  * is a convenient wrapper around timer_addmono().
67  *
68  * Example:
69  *      // Timeout in 100ms.
70  *      timer_addrel(&timeouts, &t, time_from_msec(100));
71  */
72 void timer_addrel(struct timers *timers, struct timer *timer, struct timerel rel);
73
74 /**
75  * timer_addmono - insert an absolute timer.
76  * @timers: the struct timers
77  * @timer: the (initialized or timer_del'd) timer to add
78  * @when: when @timer expires (absolute).
79  *
80  * This efficiently adds @timer to @timers, to expire @when (rounded to
81  * TIMER_GRANULARITY nanoseconds).
82  *
83  * Note that if @when is before time_mono(), then it will be set to expire
84  * immediately.
85  *
86  * Example:
87  *      // Timeout in 100ms.
88  *      timer_addmono(&timeouts, &t, timemono_add(time_mono(), time_from_msec(100)));
89  */
90 void timer_addmono(struct timers *timers, struct timer *timer,
91                    struct timemono when);
92
93 /**
94  * timer_del - remove a timer.
95  * @timers: the struct timers
96  * @timer: the timer
97  *
98  * This efficiently removes @timer from @timers, if timer_add() was
99  * called.  It can be called multiple times without bad effect, and
100  * can be called any time after timer_init().
101  *
102  * Example:
103  *      timer_del(&timeouts, &t);
104  */
105 void timer_del(struct timers *timers, struct timer *timer);
106
107 /**
108  * timer_earliest - find out the first time when a timer will expire
109  * @timers: the struct timers
110  * @first: the expiry time, only set if there is a timer.
111  *
112  * This returns false, and doesn't alter @first if there are no
113  * timers.  Otherwise, it sets @first to the expiry time of the first
114  * timer (rounded to TIMER_GRANULARITY nanoseconds), and returns true.
115  *
116  * Example:
117  *      struct timemono next = { { (time_t)-1ULL, -1UL } };
118  *      timer_earliest(&timeouts, &next);
119  */
120 bool timer_earliest(struct timers *timers, struct timemono *first);
121
122 /**
123  * timers_expire - update timers structure and remove one expire timer.
124  * @timers: the struct timers
125  * @expire: the current time
126  *
127  * A timers added with a @when arg less than or equal to @expire will be
128  * returned (within TIMER_GRANULARITY nanosecond precision).  If
129  * there are no timers due to expire, NULL is returned.
130  *
131  * After this returns NULL, @expire is considered the current time,
132  * and adding any timers with @when before this value will be silently
133  * changed to adding them with immediate expiration.
134  *
135  * You should not move @expire backwards, though it need not move
136  * forwards.
137  *
138  * Example:
139  *      struct timer *expired;
140  *
141  *      while ((expired = timers_expire(&timeouts, time_mono())) != NULL)
142  *              printf("Timer expired!\n");
143  *
144  */
145 struct timer *timers_expire(struct timers *timers, struct timemono expire);
146
147 /**
148  * timers_check - check timer structure for consistency
149  * @t: the struct timers
150  * @abortstr: the location to print on aborting, or NULL.
151  *
152  * Because timers have redundant information, consistency checking can
153  * be done on the tree.  This is useful as a debugging check.  If
154  * @abortstr is non-NULL, that will be printed in a diagnostic if the
155  * timers structure is inconsistent, and the function will abort.
156  *
157  * Returns the timers struct if it is consistent, NULL if not (it can
158  * never return NULL if @abortstr is set).
159  *
160  * Example:
161  *      timers_check(&timeouts, "After timer_expire");
162  */
163 struct timers *timers_check(const struct timers *t, const char *abortstr);
164
165 /**
166  * timers_set_allocator - set malloc/free functions.
167  * @alloc: allocator to use
168  * @free: unallocator to use (@p is NULL or a return from @alloc)
169  *
170  * This replaces the underlying malloc/free with these allocators.
171  * Setting either one to NULL restores the default allocators.
172  */
173 void timers_set_allocator(void *(*alloc)(struct timers *, size_t len),
174                           void (*free)(struct timers *, void *p));
175
176 #ifdef CCAN_TIMER_DEBUG
177 #include <stdio.h>
178
179 /**
180  * timers_dump - dump the timers datastructure (for debugging it)
181  * @t: the struct timers
182  * @fp: the FILE to dump to (stderr if @fp is NULL)
183  */
184 void timers_dump(const struct timers *timers, FILE *fp);
185 #endif
186
187 /**
188  * struct timers - structure to hold a set of timers.
189  *
190  * Initialized using timers_init, the levels of the timer are
191  * allocated as necessary, using malloc.
192  *
193  * See Also:
194  *      timers_init(), timers_cleanup()
195  */
196 struct timers {
197         /* Far in the future. */
198         struct list_head far;
199         /* Current time. */
200         uint64_t base;
201         /* Overall first value. */
202         uint64_t first;
203         /* First value in each level (plus 1 for far list) */
204         uint64_t firsts[(64 + TIMER_LEVEL_BITS-1) / TIMER_LEVEL_BITS + 1];
205
206         struct timer_level *level[(64 + TIMER_LEVEL_BITS-1) / TIMER_LEVEL_BITS];
207 };
208
209 /**
210  * struct timer - a single timer.
211  *
212  * Set up by timer_add(), this is usually contained within an
213  * application-specific structure.
214  *
215  * See Also:
216  *      ccan/container_of, timer_add(), timer_del()
217  */
218 struct timer {
219         struct list_node list;
220         uint64_t time;
221 };
222 #endif /* CCAN_TIMER_H */