]> git.ozlabs.org Git - ccan/blob - ccan/time/time.h
time: make timemono a first-class citizen.
[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 #define TIMEREL_CHECK(t) \
22         timerel_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ")
23 #define TIMEABS_CHECK(t) \
24         timeabs_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ")
25 #define TIMEMONO_CHECK(t) \
26         timemono_check((t), __FILE__ ":" stringify(__LINE__) " (" stringify(t) ") ")
27 #else
28 #define TIME_CHECK(t) (t)
29 #define TIMEREL_CHECK(t) (t)
30 #define TIMEABS_CHECK(t) (t)
31 #define TIMEMONO_CHECK(t) (t)
32 #endif
33
34 /**
35  * struct timerel - a relative time.
36  * @ts: the actual timespec value.
37  *
38  * For example, 1 second: ts.tv_sec = 1, ts.tv_nsec = 0
39  */
40 struct timerel {
41         struct timespec ts;
42 };
43
44 /**
45  * struct timeabs - an absolue time.
46  * @ts: the actual timespec value.
47  *
48  * For example, Midnight UTC January 1st, 1970: ts.tv_sec = 0, ts.tv_nsec = 0
49  */
50 struct timeabs {
51         struct timespec ts;
52 };
53
54 /**
55  * struct timemono - a monotonic time.
56  * @ts: the actual timespec value.
57  *
58  * This comes from the monotonic clock (if available), so it's useful
59  * for measuring intervals as it won't change even if the system clock
60  * is moved for some reason.
61  */
62 struct timemono {
63         struct timespec ts;
64 };
65
66 /**
67  * TIME_HAVE_MONOTONIC - defined if we really have a monotonic clock.
68  *
69  * Otherwise time_mono() just refers to time_now().  Your code might
70  * test this if you really need a monotonic clock.
71  */
72 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
73 #define TIME_HAVE_MONOTONIC 1
74 #endif
75
76 struct timespec time_check_(struct timespec in, const char *abortstr);
77
78 /**
79  * timerel_check - check if a relative time is malformed.
80  * @in: the relative time to check (returned)
81  * @abortstr: the string to print to stderr before aborting (if set).
82  *
83  * This can be used to make sure a time isn't negative and doesn't
84  * have a tv_nsec >= 1000000000.  If it is, and @abortstr is non-NULL,
85  * that will be printed and abort() is called.  Otherwise, if
86  * @abortstr is NULL then the returned timerel will be normalized and
87  * tv_sec set to 0 if it was negative.
88  *
89  * Note that if ccan/time is compiled with DEBUG, then it will call this
90  * for all passed and returned times.
91  *
92  * Example:
93  *      printf("Time to calc this was %lu nanoseconds\n",
94  *              (long)timerel_check(time_between(time_now(), time_now()),
95  *                                  "time_now() failed?").ts.tv_nsec);
96  */
97 struct timerel timerel_check(struct timerel in, const char *abortstr);
98
99 /**
100  * timeabs_check - check if an absolute time is malformed.
101  * @in: the absolute time to check (returned)
102  * @abortstr: the string to print to stderr before aborting (if set).
103  *
104  * This can be used to make sure a time isn't negative and doesn't
105  * have a tv_nsec >= 1000000000.  If it is, and @abortstr is non-NULL,
106  * that will be printed and abort() is called.  Otherwise, if
107  * @abortstr is NULL then the returned timeabs will be normalized and
108  * tv_sec set to 0 if it was negative.
109  *
110  * Note that if ccan/time is compiled with DEBUG, then it will call this
111  * for all passed and returned times.
112  *
113  * Example:
114  *      printf("Now is %lu seconds since epoch\n",
115  *              (long)timeabs_check(time_now(), "time_now failed?").ts.tv_sec);
116  */
117 struct timeabs timeabs_check(struct timeabs in, const char *abortstr);
118
119 /**
120  * timemono_check - check if a monotonic time is malformed.
121  * @in: the monotonic time to check (returned)
122  * @abortstr: the string to print to stderr before aborting (if set).
123  *
124  * This can be used to make sure a time isn't negative and doesn't
125  * have a tv_nsec >= 1000000000.  If it is, and @abortstr is non-NULL,
126  * that will be printed and abort() is called.  Otherwise, if
127  * @abortstr is NULL then the returned timemono will be normalized and
128  * tv_sec set to 0 if it was negative.
129  *
130  * Note that if ccan/time is compiled with DEBUG, then it will call this
131  * for all passed and returned times.
132  *
133  * Example:
134  *      printf("Now is %lu seconds since mono start\n",
135  *              (long)timemono_check(time_mono(), "time_mono failed?").ts.tv_sec);
136  */
137 struct timemono timemono_check(struct timemono in, const char *abortstr);
138
139 /**
140  * time_now - return the current time
141  *
142  * Example:
143  *      printf("Now is %lu seconds since epoch\n", (long)time_now().ts.tv_sec);
144  */
145 struct timeabs time_now(void);
146
147 /**
148  * time_mono - return the current monotonic time
149  *
150  * This value is only really useful for measuring time intervals.
151  *
152  * See also:
153  *      timemono_since()
154  */
155 struct timemono time_mono(void);
156
157 static inline bool time_greater_(struct timespec a, struct timespec b)
158 {
159         if (TIME_CHECK(a).tv_sec > TIME_CHECK(b).tv_sec)
160                 return true;
161         else if (a.tv_sec < b.tv_sec)
162                  return false;
163
164         return a.tv_nsec > b.tv_nsec;
165 }
166
167 /**
168  * time_after - is a after b?
169  * @a: one abstime.
170  * @b: another abstime.
171  *
172  * Example:
173  *      static bool timed_out(const struct timeabs *start)
174  *      {
175  *      #define TIMEOUT time_from_msec(1000)
176  *              return time_after(time_now(), timeabs_add(*start, TIMEOUT));
177  *      }
178  */
179 static inline bool time_after(struct timeabs a, struct timeabs b)
180 {
181         return time_greater_(a.ts, b.ts);
182 }
183
184 /**
185  * time_greater - is a greater than b?
186  * @a: one reltime.
187  * @b: another reltime.
188  */
189 static inline bool time_greater(struct timerel a, struct timerel b)
190 {
191         return time_greater_(a.ts, b.ts);
192 }
193
194 static inline bool time_less_(struct timespec a, struct timespec b)
195 {
196         if (TIME_CHECK(a).tv_sec < TIME_CHECK(b).tv_sec)
197                 return true;
198         else if (a.tv_sec > b.tv_sec)
199                  return false;
200
201         return a.tv_nsec < b.tv_nsec;
202 }
203
204 /**
205  * time_before - is a before b?
206  * @a: one absolute time.
207  * @b: another absolute time.
208  *
209  * Example:
210  *      static bool still_valid(const struct timeabs *start)
211  *      {
212  *      #define TIMEOUT time_from_msec(1000)
213  *              return time_before(time_now(), timeabs_add(*start, TIMEOUT));
214  *      }
215  */
216 static inline bool time_before(struct timeabs a, struct timeabs b)
217 {
218         return time_less_(a.ts, b.ts);
219 }
220
221 /**
222  * time_less - is a before b?
223  * @a: one relative time.
224  * @b: another relative time.
225  */
226 static inline bool time_less(struct timerel a, struct timerel b)
227 {
228         return time_less_(a.ts, b.ts);
229 }
230
231 /**
232  * timeabs_eq - is a equal to b?
233  * @a: one absolute time.
234  * @b: another absolute time.
235  *
236  * Example:
237  *      #include <sys/types.h>
238  *      #include <sys/wait.h>
239  *
240  *      // Can we fork in under a nanosecond?
241  *      static bool fast_fork(void)
242  *      {
243  *              struct timeabs start = time_now();
244  *              if (fork() != 0) {
245  *                      exit(0);
246  *              }
247  *              wait(NULL);
248  *              return timeabs_eq(start, time_now());
249  *      }
250  */
251 static inline bool timeabs_eq(struct timeabs a, struct timeabs b)
252 {
253         return TIMEABS_CHECK(a).ts.tv_sec == TIMEABS_CHECK(b).ts.tv_sec
254                 && a.ts.tv_nsec == b.ts.tv_nsec;
255 }
256
257 /**
258  * timemono_eq - is a equal to b?
259  * @a: one monotonic time.
260  * @b: another monotonic time.
261  *
262  * Example:
263  *      #include <sys/types.h>
264  *      #include <sys/wait.h>
265  *
266  *      // Can we fork in under a nanosecond?
267  *      static bool fast_fork(void)
268  *      {
269  *              struct timemono start = time_mono();
270  *              if (fork() != 0) {
271  *                      exit(0);
272  *              }
273  *              wait(NULL);
274  *              return timemono_eq(start, time_mono());
275  *      }
276  */
277 static inline bool timemono_eq(struct timemono a, struct timemono b)
278 {
279         return TIMEMONO_CHECK(a).ts.tv_sec == TIMEMONO_CHECK(b).ts.tv_sec
280                 && a.ts.tv_nsec == b.ts.tv_nsec;
281 }
282
283 /**
284  * timerel_eq - is a equal to b?
285  * @a: one relative time.
286  * @b: another relative time.
287  *
288  * Example:
289  *      #include <sys/types.h>
290  *      #include <sys/wait.h>
291  *
292  *      // Can we fork in under a nanosecond?
293  *      static bool fast_fork(void)
294  *      {
295  *              struct timeabs start = time_now();
296  *              struct timerel diff, zero = { .ts = { 0, 0 } };
297  *              if (fork() != 0) {
298  *                      exit(0);
299  *              }
300  *              wait(NULL);
301  *              diff = time_between(time_now(), start);
302  *              return timerel_eq(diff, zero);
303  *      }
304  */
305 static inline bool timerel_eq(struct timerel a, struct timerel b)
306 {
307         return TIMEREL_CHECK(a).ts.tv_sec == TIMEREL_CHECK(b).ts.tv_sec
308                 && a.ts.tv_nsec == b.ts.tv_nsec;
309 }
310
311 static inline struct timespec time_sub_(struct timespec recent,
312                                         struct timespec old)
313 {
314         struct timespec diff;
315
316         diff.tv_sec = TIME_CHECK(recent).tv_sec - TIME_CHECK(old).tv_sec;
317         if (old.tv_nsec > recent.tv_nsec) {
318                 diff.tv_sec--;
319                 diff.tv_nsec = 1000000000 + recent.tv_nsec - old.tv_nsec;
320         } else
321                 diff.tv_nsec = recent.tv_nsec - old.tv_nsec;
322
323         return TIME_CHECK(diff);
324 }
325
326 /**
327  * time_sub - subtract two relative times
328  * @a: the larger time.
329  * @b: the smaller time.
330  *
331  * This returns a well formed struct timerel of @a - @b.
332  */
333 static inline struct timerel time_sub(struct timerel a, struct timerel b)
334 {
335         struct timerel t;
336
337         t.ts = time_sub_(a.ts, b.ts);
338         return t;
339 }
340
341 /**
342  * time_between - time between two absolute times
343  * @recent: the larger time.
344  * @old: the smaller time.
345  *
346  * This returns a well formed struct timerel of @a - @b.
347  */
348 static inline struct timerel time_between(struct timeabs recent, struct timeabs old)
349 {
350         struct timerel t;
351
352         t.ts = time_sub_(recent.ts, old.ts);
353         return t;
354 }
355
356 /**
357  * timemono_between - time between two monotonic times
358  * @recent: the larger time.
359  * @old: the smaller time.
360  *
361  * This returns a well formed struct timerel of @recent - @old.
362  */
363 static inline struct timerel timemono_between(struct timemono recent,
364                                               struct timemono old)
365 {
366         struct timerel t;
367
368         t.ts = time_sub_(recent.ts, old.ts);
369         return t;
370 }
371
372 /**
373  * timemono_since - elapsed monotonic time since @old
374  * @old: a monotonic time from the past.
375  */
376 static inline struct timerel timemono_since(struct timemono old)
377 {
378         struct timemono now = time_mono();
379
380         return timemono_between(now, TIMEMONO_CHECK(old));
381 }
382
383 /**
384  * timeabs_sub - subtract a relative time from an absolute time
385  * @abs: the absolute time.
386  * @rel: the relative time.
387  *
388  * This returns a well formed struct timeabs of @a - @b.
389  *
390  * Example:
391  *      // We do one every second.
392  *      static struct timeabs previous_time(void)
393  *      {
394  *              return timeabs_sub(time_now(), time_from_msec(1000));
395  *      }
396  */
397 static inline struct timeabs timeabs_sub(struct timeabs abs, struct timerel rel)
398 {
399         struct timeabs t;
400
401         t.ts = time_sub_(abs.ts, rel.ts);
402         return t;
403 }
404
405 static inline struct timespec time_add_(struct timespec a, struct timespec b)
406 {
407         struct timespec sum;
408
409         sum.tv_sec = TIME_CHECK(a).tv_sec + TIME_CHECK(b).tv_sec;
410         sum.tv_nsec = a.tv_nsec + b.tv_nsec;
411         if (sum.tv_nsec >= 1000000000) {
412                 sum.tv_sec++;
413                 sum.tv_nsec -= 1000000000;
414         }
415         return TIME_CHECK(sum);
416 }
417
418 /**
419  * timeabs_add - add a relative to an absolute time
420  * @a: the absolute time.
421  * @b: a relative time.
422  *
423  * The times must not overflow, or the results are undefined.
424  *
425  * Example:
426  *      // We do one every second.
427  *      static struct timeabs next_time(void)
428  *      {
429  *              return timeabs_add(time_now(), time_from_msec(1000));
430  *      }
431  */
432 static inline struct timeabs timeabs_add(struct timeabs a, struct timerel b)
433 {
434         struct timeabs t;
435
436         t.ts = time_add_(a.ts, b.ts);
437         return t;
438 }
439
440 /**
441  * timemono_add - add a relative to a monotonic time
442  * @a: the monotonic time.
443  * @b: a relative time.
444  *
445  * The times must not overflow, or the results are undefined.
446  *
447  * Example:
448  *      // We do one every second.
449  *      static struct timemono next_timem(void)
450  *      {
451  *              return timemono_add(time_mono(), time_from_msec(1000));
452  *      }
453  */
454 static inline struct timemono timemono_add(struct timemono a, struct timerel b)
455 {
456         struct timemono t;
457
458         t.ts = time_add_(a.ts, b.ts);
459         return t;
460 }
461
462 /**
463  * timerel_add - add two relative times
464  * @a: one relative time.
465  * @b: another relative time.
466  *
467  * The times must not overflow, or the results are undefined.
468  *
469  * Example:
470  *      static struct timerel double_time(struct timerel a)
471  *      {
472  *              return timerel_add(a, a);
473  *      }
474  */
475 static inline struct timerel timerel_add(struct timerel a, struct timerel b)
476 {
477         struct timerel t;
478
479         t.ts = time_add_(a.ts, b.ts);
480         return t;
481 }
482
483 /**
484  * time_divide - divide a time by a value.
485  * @t: a time.
486  * @div: number to divide it by.
487  *
488  * Example:
489  *      // How long does it take to do a fork?
490  *      static struct timerel forking_time(void)
491  *      {
492  *              struct timeabs start = time_now();
493  *              unsigned int i;
494  *
495  *              for (i = 0; i < 1000; i++) {
496  *                      if (fork() != 0) {
497  *                              exit(0);
498  *                      }
499  *                      wait(NULL);
500  *              }
501  *              return time_divide(time_between(time_now(), start), i);
502  *      }
503  */
504 struct timerel time_divide(struct timerel t, unsigned long div);
505
506 /**
507  * time_multiply - multiply a time by a value.
508  * @t: a relative time.
509  * @mult: number to multiply it by.
510  *
511  * Example:
512  *      ...
513  *      printf("Time to do 100000 forks would be %u sec\n",
514  *             (unsigned)time_multiply(forking_time(), 1000000).ts.tv_sec);
515  */
516 struct timerel time_multiply(struct timerel t, unsigned long mult);
517
518 /**
519  * time_to_sec - return number of seconds
520  * @t: a time
521  *
522  * It's often more convenient to deal with time values as seconds.
523  * Note that this will fit into an unsigned 32-bit variable if it's a
524  * time of less than about 136 years.
525  *
526  * Example:
527  *      ...
528  *      printf("Forking time is %u sec\n",
529  *             (unsigned)time_to_sec(forking_time()));
530  */
531 static inline uint64_t time_to_sec(struct timerel t)
532 {
533         return t.ts.tv_sec;
534 }
535
536 /**
537  * time_to_msec - return number of milliseconds
538  * @t: a relative time
539  *
540  * It's often more convenient to deal with time values as
541  * milliseconds.  Note that this will fit into a 32-bit variable if
542  * it's a time difference of less than ~7 weeks.
543  *
544  * Example:
545  *      ...
546  *      printf("Forking time is %u msec\n",
547  *             (unsigned)time_to_msec(forking_time()));
548  */
549 static inline uint64_t time_to_msec(struct timerel t)
550 {
551         uint64_t msec;
552
553         msec = TIMEREL_CHECK(t).ts.tv_nsec/1000000 + (uint64_t)t.ts.tv_sec*1000;
554         return msec;
555 }
556
557 /**
558  * time_to_usec - return number of microseconds
559  * @t: a relative time
560  *
561  * It's often more convenient to deal with time values as
562  * microseconds.  Note that this will fit into a 32-bit variable if
563  * it's a time difference of less than ~1 hour.
564  *
565  * Example:
566  *      ...
567  *      printf("Forking time is %u usec\n",
568  *             (unsigned)time_to_usec(forking_time()));
569  *
570  */
571 static inline uint64_t time_to_usec(struct timerel t)
572 {
573         uint64_t usec;
574
575         usec = TIMEREL_CHECK(t).ts.tv_nsec/1000 + (uint64_t)t.ts.tv_sec*1000000;
576         return usec;
577 }
578
579 /**
580  * time_to_nsec - return number of nanoseconds
581  * @t: a relative time
582  *
583  * It's sometimes more convenient to deal with time values as
584  * nanoseconds.  Note that this will fit into a 32-bit variable if
585  * it's a time difference of less than ~4 seconds.
586  *
587  * Example:
588  *      ...
589  *      printf("Forking time is %u nsec\n",
590  *             (unsigned)time_to_nsec(forking_time()));
591  *
592  */
593 static inline uint64_t time_to_nsec(struct timerel t)
594 {
595         uint64_t nsec;
596
597         nsec = TIMEREL_CHECK(t).ts.tv_nsec + (uint64_t)t.ts.tv_sec * 1000000000;
598         return nsec;
599 }
600
601 /**
602  * time_from_sec - convert seconds to a relative time
603  * @msec: time in seconds
604  *
605  * Example:
606  *      // 1 minute timeout
607  *      #define TIMEOUT time_from_sec(60)
608  */
609 static inline struct timerel time_from_sec(uint64_t sec)
610 {
611         struct timerel t;
612
613         t.ts.tv_nsec = 0;
614         t.ts.tv_sec = sec;
615         return TIMEREL_CHECK(t);
616 }
617
618 /**
619  * time_from_msec - convert milliseconds to a relative time
620  * @msec: time in milliseconds
621  *
622  * Example:
623  *      // 1/2 second timeout
624  *      #define TIMEOUT time_from_msec(500)
625  */
626 static inline struct timerel time_from_msec(uint64_t msec)
627 {
628         struct timerel t;
629
630         t.ts.tv_nsec = (msec % 1000) * 1000000;
631         t.ts.tv_sec = msec / 1000;
632         return TIMEREL_CHECK(t);
633 }
634
635 /**
636  * time_from_usec - convert microseconds to a relative time
637  * @usec: time in microseconds
638  *
639  * Example:
640  *      // 1/2 second timeout
641  *      #define TIMEOUT time_from_usec(500000)
642  */
643 static inline struct timerel time_from_usec(uint64_t usec)
644 {
645         struct timerel t;
646
647         t.ts.tv_nsec = (usec % 1000000) * 1000;
648         t.ts.tv_sec = usec / 1000000;
649         return TIMEREL_CHECK(t);
650 }
651
652 /**
653  * time_from_nsec - convert nanoseconds to a relative time
654  * @nsec: time in nanoseconds
655  *
656  * Example:
657  *      // 1/2 second timeout
658  *      #define TIMEOUT time_from_nsec(500000000)
659  */
660 static inline struct timerel time_from_nsec(uint64_t nsec)
661 {
662         struct timerel t;
663
664         t.ts.tv_nsec = nsec % 1000000000;
665         t.ts.tv_sec = nsec / 1000000000;
666         return TIMEREL_CHECK(t);
667 }
668
669 static inline struct timeval timespec_to_timeval(struct timespec ts)
670 {
671         struct timeval tv;
672         tv.tv_sec = ts.tv_sec;
673         tv.tv_usec = ts.tv_nsec / 1000;
674         return tv;
675 }
676
677 /**
678  * timerel_to_timeval - convert a relative time to a timeval.
679  * @t: a relative time.
680  *
681  * Example:
682  *      struct timerel t = { { 100, 0 } }; // 100 seconds
683  *      struct timeval tv;
684  *
685  *      tv = timerel_to_timeval(t);
686  *      printf("time = %lu.%06u\n", (long)tv.tv_sec, (int)tv.tv_usec);
687  */
688 static inline struct timeval timerel_to_timeval(struct timerel t)
689 {
690         return timespec_to_timeval(t.ts);
691 }
692
693 /**
694  * timeabs_to_timeval - convert an absolute time to a timeval.
695  * @t: an absolute time.
696  *
697  * Example:
698  *      struct timeval tv;
699  *
700  *      tv = timeabs_to_timeval(time_now());
701  *      printf("time = %lu.%06u\n", (long)tv.tv_sec, (int)tv.tv_usec);
702  */
703 static inline struct timeval timeabs_to_timeval(struct timeabs t)
704 {
705         return timespec_to_timeval(t.ts);
706 }
707
708 static inline struct timespec timeval_to_timespec(struct timeval tv)
709 {
710         struct timespec ts;
711         ts.tv_sec = tv.tv_sec;
712         ts.tv_nsec = tv.tv_usec * 1000;
713         return ts;
714 }
715
716 /**
717  * timeval_to_timerel - convert a timeval to a relative time.
718  * @tv: a timeval.
719  *
720  * Example:
721  *      struct timeval tv = { 0, 500 };
722  *      struct timerel t;
723  *
724  *      t = timeval_to_timerel(tv);
725  *      printf("timerel = %lu.%09lu\n", (long)t.ts.tv_sec, (long)t.ts.tv_nsec);
726  */
727 static inline struct timerel timeval_to_timerel(struct timeval tv)
728 {
729         struct timerel t;
730         t.ts = timeval_to_timespec(tv);
731         return TIMEREL_CHECK(t);
732 }
733
734 /**
735  * timeval_to_timeabs - convert a timeval to an absolute time.
736  * @tv: a timeval.
737  *
738  * Example:
739  *      struct timeval tv = { 1401762008, 500 };
740  *      struct timeabs t;
741  *
742  *      t = timeval_to_timeabs(tv);
743  *      printf("timeabs = %lu.%09lu\n", (long)t.ts.tv_sec, (long)t.ts.tv_nsec);
744  */
745 static inline struct timeabs timeval_to_timeabs(struct timeval tv)
746 {
747         struct timeabs t;
748         t.ts = timeval_to_timespec(tv);
749         return TIMEABS_CHECK(t);
750 }
751 #endif /* CCAN_TIME_H */