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