e4298d07055d1ab66ad816a042ede0bcf9720b26
[ccan] / ccan / time / time.h
1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #ifndef CCAN_TIME_H
3 #define CCAN_TIME_H
4 #include "config.h"
5 #include <sys/time.h>
6 #if HAVE_STRUCT_TIMESPEC
7 #include <time.h>
8 #else
9 struct timespec {
10         time_t   tv_sec;        /* seconds */
11         long     tv_nsec;       /* nanoseconds */
12 };
13 #endif
14 #include <stdint.h>
15 #include <stdbool.h>
16
17 #ifdef DEBUG
18 #include <ccan/str/str.h>
19 #define TIME_CHECK(t) \
20         time_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ")
21 #else
22 #define TIME_CHECK(t) (t)
23 #endif
24
25 /**
26  * time_check - check if a time is malformed.
27  * @in: the time to check (returned)
28  * @abortstr: the string to print to stderr before aborting (if set).
29  *
30  * This can be used to make sure a time isn't negative and doesn't
31  * have a tv_nsec >= 1000000000.  If it is, and @abortstr is non-NULL,
32  * that will be printed and abort() is called.  Otherwise, if
33  * @abortstr is NULL then the returned timespec will be normalized and
34  * tv_sec set to 0 if it was negative.
35  *
36  * Note that if ccan/time is compiled with DEBUG, then it will call this
37  * for all passed and returned times.
38  *
39  * Example:
40  *      printf("Now is %lu seconds since epoch\n",
41  *              (long)time_check(time_now(), "time_now() failed?").tv_sec);
42  */
43 struct timespec time_check(struct timespec in, const char *abortstr);
44
45 /**
46  * time_now - return the current time
47  *
48  * Example:
49  *      printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
50  */
51 struct timespec time_now(void);
52
53 /**
54  * time_greater - is a after b?
55  * @a: one time.
56  * @b: another time.
57  *
58  * Example:
59  *      static bool timed_out(const struct timespec *start)
60  *      {
61  *      #define TIMEOUT time_from_msec(1000)
62  *              return time_greater(time_now(), time_add(*start, TIMEOUT));
63  *      }
64  */
65 static inline bool time_greater(struct timespec a, struct timespec b)
66 {
67         if (TIME_CHECK(a).tv_sec > TIME_CHECK(b).tv_sec)
68                 return true;
69         else if (a.tv_sec < b.tv_sec)
70                  return false;
71
72         return a.tv_nsec > b.tv_nsec;
73 }
74
75 /**
76  * time_less - is a before b?
77  * @a: one time.
78  * @b: another time.
79  *
80  * Example:
81  *      static bool still_valid(const struct timespec *start)
82  *      {
83  *      #define TIMEOUT time_from_msec(1000)
84  *              return time_less(time_now(), time_add(*start, TIMEOUT));
85  *      }
86  */
87 static inline bool time_less(struct timespec a, struct timespec b)
88 {
89         if (TIME_CHECK(a).tv_sec < TIME_CHECK(b).tv_sec)
90                 return true;
91         else if (a.tv_sec > b.tv_sec)
92                  return false;
93
94         return a.tv_nsec < b.tv_nsec;
95 }
96
97 /**
98  * time_eq - is a equal to b?
99  * @a: one time.
100  * @b: another time.
101  *
102  * Example:
103  *      #include <sys/types.h>
104  *      #include <sys/wait.h>
105  *
106  *      // Can we fork in under a nanosecond?
107  *      static bool fast_fork(void)
108  *      {
109  *              struct timespec start = time_now();
110  *              if (fork() != 0) {
111  *                      exit(0);
112  *              }
113  *              wait(NULL);
114  *              return time_eq(start, time_now());
115  *      }
116  */
117 static inline bool time_eq(struct timespec a, struct timespec b)
118 {
119         return TIME_CHECK(a).tv_sec == TIME_CHECK(b).tv_sec
120                 && a.tv_nsec == b.tv_nsec;
121 }
122
123 /**
124  * time_sub - subtract two times
125  * @recent: the larger (more recent) time.
126  * @old: the smaller (less recent) time.
127  *
128  * This returns a well formed struct timespec.
129  *
130  * Example:
131  *      static bool was_recent(const struct timespec *start)
132  *      {
133  *              return time_sub(time_now(), *start).tv_sec < 1;
134  *      }
135  */
136 static inline struct timespec time_sub(struct timespec recent,
137                                        struct timespec old)
138 {
139         struct timespec diff;
140
141         diff.tv_sec = TIME_CHECK(recent).tv_sec - TIME_CHECK(old).tv_sec;
142         if (old.tv_nsec > recent.tv_nsec) {
143                 diff.tv_sec--;
144                 diff.tv_nsec = 1000000000 + recent.tv_nsec - old.tv_nsec;
145         } else
146                 diff.tv_nsec = recent.tv_nsec - old.tv_nsec;
147
148         return TIME_CHECK(diff);
149 }
150
151 /**
152  * time_add - add two times
153  * @a: one time.
154  * @b: another time.
155  *
156  * The times must not overflow, or the results are undefined.
157  *
158  * Example:
159  *      // We do one every second.
160  *      static struct timespec next_time(void)
161  *      {
162  *              return time_add(time_now(), time_from_msec(1000));
163  *      }
164  */
165 static inline struct timespec time_add(struct timespec a, struct timespec b)
166 {
167         struct timespec sum;
168
169         sum.tv_sec = TIME_CHECK(a).tv_sec + TIME_CHECK(b).tv_sec;
170         sum.tv_nsec = a.tv_nsec + b.tv_nsec;
171         if (sum.tv_nsec >= 1000000000) {
172                 sum.tv_sec++;
173                 sum.tv_nsec -= 1000000000;
174         }
175         return TIME_CHECK(sum);
176 }
177
178 /**
179  * time_divide - divide a time by a value.
180  * @t: a time.
181  * @div: number to divide it by.
182  *
183  * Example:
184  *      // How long does it take to do a fork?
185  *      static struct timespec forking_time(void)
186  *      {
187  *              struct timespec start = time_now();
188  *              unsigned int i;
189  *
190  *              for (i = 0; i < 1000; i++) {
191  *                      if (fork() != 0) {
192  *                              exit(0);
193  *                      }
194  *                      wait(NULL);
195  *              }
196  *              return time_divide(time_sub(time_now(), start), i);
197  *      }
198  */
199 struct timespec time_divide(struct timespec t, unsigned long div);
200
201 /**
202  * time_multiply - multiply a time by a value.
203  * @t: a time.
204  * @mult: number to multiply it by.
205  *
206  * Example:
207  *      ...
208  *      printf("Time to do 100000 forks would be %u sec\n",
209  *             (unsigned)time_multiply(forking_time(), 1000000).tv_sec);
210  */
211 struct timespec time_multiply(struct timespec t, unsigned long mult);
212
213 /**
214  * time_to_sec - return number of seconds
215  * @t: a time
216  *
217  * It's often more convenient to deal with time values as seconds.
218  * Note that this will fit into an unsigned 32-bit variable if it's a
219  * time of less than about 136 years.
220  *
221  * Example:
222  *      ...
223  *      printf("Forking time is %u sec\n",
224  *             (unsigned)time_to_sec(forking_time()));
225  */
226 static inline uint64_t time_to_sec(struct timespec t)
227 {
228         return t.tv_sec;
229 }
230
231 /**
232  * time_to_msec - return number of milliseconds
233  * @t: a time
234  *
235  * It's often more convenient to deal with time values as
236  * milliseconds.  Note that this will fit into a 32-bit variable if
237  * it's a time difference of less than ~7 weeks.
238  *
239  * Example:
240  *      ...
241  *      printf("Forking time is %u msec\n",
242  *             (unsigned)time_to_msec(forking_time()));
243  */
244 static inline uint64_t time_to_msec(struct timespec t)
245 {
246         uint64_t msec;
247
248         msec = TIME_CHECK(t).tv_nsec / 1000000 + (uint64_t)t.tv_sec * 1000;
249         return msec;
250 }
251
252 /**
253  * time_to_usec - return number of microseconds
254  * @t: a time
255  *
256  * It's often more convenient to deal with time values as
257  * microseconds.  Note that this will fit into a 32-bit variable if
258  * it's a time difference of less than ~1 hour.
259  *
260  * Example:
261  *      ...
262  *      printf("Forking time is %u usec\n",
263  *             (unsigned)time_to_usec(forking_time()));
264  *
265  */
266 static inline uint64_t time_to_usec(struct timespec t)
267 {
268         uint64_t usec;
269
270         usec = TIME_CHECK(t).tv_nsec / 1000 + (uint64_t)t.tv_sec * 1000000;
271         return usec;
272 }
273
274 /**
275  * time_to_nsec - return number of nanoseconds
276  * @t: a time
277  *
278  * It's sometimes more convenient to deal with time values as
279  * nanoseconds.  Note that this will fit into a 32-bit variable if
280  * it's a time difference of less than ~4 seconds.
281  *
282  * Example:
283  *      ...
284  *      printf("Forking time is %u nsec\n",
285  *             (unsigned)time_to_nsec(forking_time()));
286  *
287  */
288 static inline uint64_t time_to_nsec(struct timespec t)
289 {
290         uint64_t nsec;
291
292         nsec = TIME_CHECK(t).tv_nsec + (uint64_t)t.tv_sec * 1000000000;
293         return nsec;
294 }
295
296 /**
297  * time_from_sec - convert seconds to a timespec
298  * @msec: time in seconds
299  *
300  * Example:
301  *      // 1 minute timeout
302  *      #define TIMEOUT time_from_sec(60)
303  */
304 static inline struct timespec time_from_sec(uint64_t sec)
305 {
306         struct timespec t;
307
308         t.tv_nsec = 0;
309         t.tv_sec = sec;
310         return TIME_CHECK(t);
311 }
312
313 /**
314  * time_from_msec - convert milliseconds to a timespec
315  * @msec: time in milliseconds
316  *
317  * Example:
318  *      // 1/2 second timeout
319  *      #define TIMEOUT time_from_msec(500)
320  */
321 static inline struct timespec time_from_msec(uint64_t msec)
322 {
323         struct timespec t;
324
325         t.tv_nsec = (msec % 1000) * 1000000;
326         t.tv_sec = msec / 1000;
327         return TIME_CHECK(t);
328 }
329
330 /**
331  * time_from_usec - convert microseconds to a timespec
332  * @usec: time in microseconds
333  *
334  * Example:
335  *      // 1/2 second timeout
336  *      #define TIMEOUT time_from_usec(500000)
337  */
338 static inline struct timespec time_from_usec(uint64_t usec)
339 {
340         struct timespec t;
341
342         t.tv_nsec = (usec % 1000000) * 1000;
343         t.tv_sec = usec / 1000000;
344         return TIME_CHECK(t);
345 }
346
347 /**
348  * time_from_nsec - convert nanoseconds to a timespec
349  * @nsec: time in nanoseconds
350  *
351  * Example:
352  *      // 1/2 second timeout
353  *      #define TIMEOUT time_from_nsec(500000000)
354  */
355 static inline struct timespec time_from_nsec(uint64_t nsec)
356 {
357         struct timespec t;
358
359         t.tv_nsec = nsec % 1000000000;
360         t.tv_sec = nsec / 1000000000;
361         return TIME_CHECK(t);
362 }
363
364 /**
365  * timespec_to_timeval - convert a timespec to a timeval.
366  * @ts: a timespec.
367  *
368  * Example:
369  *      struct timeval tv;
370  *
371  *      tv = timespec_to_timeval(time_now());
372  *      printf("time = %lu.%06u\n", (long)tv.tv_sec, (int)tv.tv_usec);
373  */
374 static inline struct timeval timespec_to_timeval(struct timespec ts)
375 {
376         struct timeval tv;
377         tv.tv_sec = ts.tv_sec;
378         tv.tv_usec = ts.tv_nsec / 1000;
379         return tv;
380 }
381
382 /**
383  * timeval_to_timespec - convert a timeval to a timespec.
384  * @tv: a timeval.
385  *
386  * Example:
387  *      struct timeval tv = { 0, 500 };
388  *      struct timespec ts;
389  *
390  *      ts = timeval_to_timespec(tv);
391  *      printf("timespec = %lu.%09lu\n", (long)ts.tv_sec, (long)ts.tv_nsec);
392  */
393 static inline struct timespec timeval_to_timespec(struct timeval tv)
394 {
395         struct timespec ts;
396         ts.tv_sec = tv.tv_sec;
397         ts.tv_nsec = tv.tv_usec * 1000;
398         return ts;
399 }
400 #endif /* CCAN_TIME_H */