endian: add constant versions.
[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_now());
33  */
34 void timers_init(struct timers *timers, struct timespec 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_add - insert a timer.
49  * @timers: the struct timers
50  * @timer: the (uninitialized) timer to add
51  * @when: when @timer expires.
52  *
53  * This efficiently adds @timer to @timers, to expire @when (rounded to
54  * TIMER_GRANULARITY nanoseconds).
55  *
56  * Example:
57  *      struct timer t;
58  *
59  *      // Timeout in 100ms.
60  *      timer_add(&timeouts, &t, time_add(time_now(), time_from_msec(100)));
61  */
62 void timer_add(struct timers *timers, struct timer *timer,
63                struct timespec when);
64
65 /**
66  * timer_del - remove an unexpired timer.
67  * @timers: the struct timers
68  * @timer: the timer previously added with timer_add()
69  *
70  * This efficiently removes @timer from @timers.
71  *
72  * Example:
73  *      timer_del(&timeouts, &t);
74  */
75 void timer_del(struct timers *timers, struct timer *timer);
76
77 /**
78  * timer_earliest - find out the first time when a timer will expire
79  * @timers: the struct timers
80  * @first: the time, only set if there is a timer.
81  *
82  * This returns false, and doesn't alter @first if there are no
83  * timers.  Otherwise, it sets @first to the expiry time of the first
84  * timer (rounded to TIMER_GRANULARITY nanoseconds), and returns true.
85  *
86  * Example:
87  *      struct timespec next = { (time_t)-1ULL, -1UL };
88  *      timer_earliest(&timeouts, &next);
89  */
90 bool timer_earliest(struct timers *timers, struct timespec *first);
91
92 /**
93  * timers_expire - update timers structure and remove expired timers.
94  * @timers: the struct timers
95  * @expire: the current time
96  * @list: the list for expired timers.
97  *
98  * @list will be initialized to the empty list, then all timers added
99  * with a @when arg less than or equal to @expire will be added to it in
100  * expiry order (within TIMER_GRANULARITY nanosecond precision).
101  *
102  * After this, @expire is considered the current time, and adding any
103  * timers with @when before this value will be silently changed to
104  * adding them with immediate expiration.
105  *
106  * You should not move @expire backwards, though it need not move
107  * forwards.
108  *
109  * Example:
110  *      struct list_head expired;
111  *
112  *      timers_expire(&timeouts, time_now(), &expired);
113  *      if (!list_empty(&expired))
114  *              printf("Timer expired!\n");
115  */
116 void timers_expire(struct timers *timers,
117                    struct timespec expire,
118                    struct list_head *list);
119
120 /**
121  * timers_check - check timer structure for consistency
122  * @t: the struct timers
123  * @abortstr: the location to print on aborting, or NULL.
124  *
125  * Because timers have redundant information, consistency checking can
126  * be done on the tree.  This is useful as a debugging check.  If
127  * @abortstr is non-NULL, that will be printed in a diagnostic if the
128  * timers structure is inconsistent, and the function will abort.
129  *
130  * Returns the timers struct if it is consistent, NULL if not (it can
131  * never return NULL if @abortstr is set).
132  *
133  * Example:
134  *      timers_check(&timeouts, "After timer_expire");
135  */
136 struct timers *timers_check(const struct timers *t, const char *abortstr);
137
138 #ifdef CCAN_TIMER_DEBUG
139 #include <stdio.h>
140
141 /**
142  * timers_dump - dump the timers datastructure (for debugging it)
143  * @t: the struct timers
144  * @fp: the FILE to dump to (stderr if @fp is NULL)
145  */
146 void timers_dump(const struct timers *timers, FILE *fp);
147 #endif
148
149 /**
150  * struct timers - structure to hold a set of timers.
151  *
152  * Initialized using timers_init, the levels of the timer are
153  * allocated as necessary, using malloc.
154  *
155  * See Also:
156  *      timers_init(), timers_cleanup()
157  */
158 struct timers {
159         /* Far in the future. */
160         struct list_head far;
161         uint64_t base;
162         uint64_t first;
163
164         struct timer_level *level[(64 + TIMER_LEVEL_BITS-1) / TIMER_LEVEL_BITS];
165 };
166
167 /**
168  * struct timer - a single timer.
169  *
170  * Set up by timer_add(), this is usually contained within an
171  * application-specific structure.
172  *
173  * See Also:
174  *      ccan/container_of, timer_add(), timer_del()
175  */
176 struct timer {
177         struct list_node list;
178         uint64_t time;
179 };
180 #endif /* CCAN_TIMER_H */