The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
time.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /**
19  * $Id: 80d48c172e2330c19e8b9d2dea81e0e9ac29f19b $
20  *
21  * @file lib/util/time.h
22  * @brief Simple time functions
23  *
24  * @copyright 2016-2019 Alan DeKok (aland@freeradius.org)
25  * @copyright 2019-2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
26  */
27 RCSIDH(time_h, "$Id: 80d48c172e2330c19e8b9d2dea81e0e9ac29f19b $")
28 
29 #include <stdint.h>
30 #include <inttypes.h>
31 #include <stdatomic.h>
32 #include <stdio.h>
33 #include <sys/time.h>
34 
35 /*
36  * Avoid too many ifdef's later in the code.
37  */
38 #if !defined(HAVE_CLOCK_GETTIME)
39 #error clock_gettime is required
40 #endif
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /** The base resolution for print parse operations
47  */
48 typedef enum {
62 
63 /** "server local" time. This is the time in nanoseconds since the application started.
64  *
65  * This time is our *private* view of time. It should only be used
66  * for internal timers, events, etc. It can skew randomly as NTP
67  * plays with the local clock.
68  */
69 typedef struct fr_time_s {
70  int64_t value; //!< Signed because we need times before the server started
71  ///< for things like certificate validity checks and cache
72  ///< entries.
74 
75 /** A time delta, a difference in time measured in nanoseconds.
76  *
77  * This is easier to distinguish where server epoch time is being
78  * used, and where relative time is being used.
79  */
80 typedef struct fr_time_delta_s {
81  int64_t value;
83 
84 /** "Unix" time. This is the time in nanoseconds since midnight January 1, 1970
85  *
86  * Note that it is *unsigned*, as we don't use dates before 1970. Having it
87  * unsigned also allows the compiler to catch issues where people confuse the
88  * two types of time.
89  *
90  * The unix times are *public* times. i.e. times that we get from
91  * the network, or send to the network. We have no idea if the other
92  * parties idea of time is correct (or if ours is wrong), so we don't
93  * mangle unix time based on clock skew.
94  */
95 typedef struct fr_unix_time_s {
96  uint64_t value;
98 
99 #ifdef __cplusplus
100 }
101 #endif
102 
103 /*
104  * For sys/time.h and time.h
105  */
106 #include <freeradius-devel/missing.h>
107 #include <freeradius-devel/util/debug.h>
108 #include <freeradius-devel/util/sbuff.h>
109 #include <freeradius-devel/util/math.h>
110 
111 #ifdef __cplusplus
112 extern "C" {
113 #endif
114 
115 extern int64_t const fr_time_multiplier_by_res[];
117 extern size_t fr_time_precision_table_len;
118 
119 static bool fr_time_op_ispos(bool a, bool op, bool b)
120 {
121  return ((a == op) == b);
122 }
123 
124 /** Determine, if an overflow has occurred, which direction it occurred in
125  *
126  * @param[in] _a First operand.
127  * @param[in] _op Operator, true if add or multiply, false if subtract.
128  * @param[in] _b Second operand.
129  */
130 #define fr_time_overflow_ispos(_a, _op, _b) \
131 fr_time_op_ispos( \
132  _Generic(&(_a), \
133  fr_time_t *: (fr_time_unwrap(*((fr_time_t *)&(_a))) >= 0), \
134  fr_time_delta_t *: (fr_time_delta_unwrap(*((fr_time_delta_t *)&(_a))) >= 0), \
135  fr_unix_time_t *: true), \
136  _op, \
137  _Generic(&(_b), \
138  fr_time_t *: (fr_time_unwrap(*((fr_time_t *)&(_b))) >= 0), \
139  fr_time_delta_t *: (fr_time_delta_unwrap(*((fr_time_delta_t *)&(_b))) >= 0), \
140  fr_unix_time_t *: true)\
141  )
142 
143 #define fr_time_max() (fr_time_t){ .value = INT64_MAX }
144 #define fr_time_min() (fr_time_t){ .value = INT64_MIN }
145 #define fr_time_wrap(_time) (fr_time_t){ .value = (_time) }
146 static inline int64_t fr_time_unwrap(fr_time_t time) { return time.value; } /* func to stop mixing with fr_time_delta_t */
147 #define fr_time_overflow_add(_a, _b) (fr_time_overflow_ispos(_a, true, _b) ? fr_time_max() : fr_time_min())
148 #define fr_time_overflow_sub(_a, _b) (fr_time_overflow_ispos(_a, false, _b) ? fr_time_max() : fr_time_min())
149 
150 #define fr_time_delta_max() (fr_time_delta_t){ .value = INT64_MAX }
151 #define fr_time_delta_min() (fr_time_delta_t){ .value = INT64_MIN }
152 #define fr_time_delta_wrap(_time) (fr_time_delta_t){ .value = (_time) }
153 /** @hidecallergraph */
154 static inline int64_t fr_time_delta_unwrap(fr_time_delta_t time) { return time.value; } /* func to stop mixing with fr_time_t */
155 #define fr_time_delta_overflow_add(_a, _b) (fr_time_overflow_ispos(_a, true, _b) ? fr_time_delta_max() : fr_time_delta_min())
156 #define fr_time_delta_overflow_sub(_a, _b) (fr_time_overflow_ispos(_a, false, _b) ? fr_time_delta_max() : fr_time_delta_min())
157 
158 #define fr_unix_time_max() (fr_unix_time_t){ .value = UINT64_MAX }
159 #define fr_unix_time_min() (fr_unix_time_t){ .value = 0 }
160 #define fr_unix_time_wrap(_time) (fr_unix_time_t){ .value = (_time) }
161 static inline uint64_t fr_unix_time_unwrap(fr_unix_time_t time) { return time.value; } /* func to stop mixing with fr_time_t */
162 #define fr_unix_time_overflow_add(_a, _b) (fr_time_overflow_ispos(_a, true, _b) ? fr_unix_time_max() : fr_unix_time_min())
163 #define fr_unix_time_overflow_sub(_a, _b) (fr_time_overflow_ispos(_a, false, _b) ? fr_unix_time_max() : fr_unix_time_min())
164 
165 /** @name fr_time_t arithmetic and comparison macros
166  *
167  * We wrap the 64bit signed time value in a struct to prevent misuse.
168  *
169  * The macros below allow basic arithmetic and comparisons to be performed.
170  * @{
171  */
172 /* Don't add fr_time_add_time_time, it's almost always a type error */
174 {
177  return fr_time_wrap(out);
178 }
179 
181 {
184  return fr_time_wrap(out);
185 }
186 
187 /** Add a time/time delta together
188  *
189  * Types may either be:
190  * - fr_time_add((fr_time_t), (fr_time_delta_t))
191  * - fr_time_add((fr_time_delta_t), (fr_time_delta_t))
192  *
193  * Adding two time values together is most likely an error.
194  * Adding two time_delta values together can be done with #fr_time_delta_add.
195  */
196 #define fr_time_add(_a, _b) \
197  _Generic(_a, \
198  fr_time_t : _Generic(_b, \
199  fr_time_delta_t : fr_time_add_time_delta \
200  ), \
201  fr_time_delta_t : _Generic(_b, \
202  fr_time_t : fr_time_add_delta_time, \
203  fr_time_delta_t : fr_time_delta_add \
204  ) \
205  )(_a, _b)
206 
208 {
211  return fr_time_delta_wrap(out);
212 }
214 {
217  return fr_time_wrap(out);
218 }
219 
220 /** Subtract one time from another
221  *
222  * Types may either be:
223  * - fr_time_sub((fr_time_t), (fr_time_t)) - Produces a #fr_time_delta_t
224  * - fr_time_sub((fr_time_t), (fr_time_delta_t)) - Produces a #fr_time_t
225  *
226  * Subtracting time from a delta is most likely an error.
227  * Subtracting two time_delta values can be done with #fr_time_delta_sub
228  */
229 #define fr_time_sub(_a, _b) \
230  _Generic(_a, \
231  fr_time_t : _Generic(_b, \
232  fr_time_t : fr_time_sub_time_time, \
233  fr_time_delta_t : fr_time_sub_time_delta \
234  ) \
235  )(_a, _b)
236 
237 #define fr_time_gt(_a, _b) (fr_time_unwrap(_a) > fr_time_unwrap(_b))
238 #define fr_time_gteq(_a, _b) (fr_time_unwrap(_a) >= fr_time_unwrap(_b))
239 #define fr_time_lt(_a, _b) (fr_time_unwrap(_a) < fr_time_unwrap(_b))
240 #define fr_time_lteq(_a, _b) (fr_time_unwrap(_a) <= fr_time_unwrap(_b))
241 #define fr_time_eq(_a, _b) (fr_time_unwrap(_a) == fr_time_unwrap(_b))
242 #define fr_time_neq(_a, _b) (fr_time_unwrap(_a) != fr_time_unwrap(_b))
243 
244 #define fr_time_ispos(_a) (fr_time_unwrap(_a) > 0)
245 #define fr_time_isneg(_a) (fr_time_unwrap(_a) < 0)
246 /** @} */
247 
248 /** @name fr_time_delta_t arithmetic and comparison macros
249  *
250  * We wrap the 64bit signed time delta value in a struct to prevent misuse.
251  *
252  * The macros below allow basic arithmetic and comparisons to be performed.
253  * @{
254  */
256 {
259  return fr_time_delta_wrap(out);
260 }
262 {
265  return fr_time_delta_wrap(out);
266 }
268 {
270 }
272 {
275  return fr_time_delta_overflow_add(a, b);
276  }
277  return fr_time_delta_wrap(out);
278 }
279 
280 #define fr_time_delta_cond(_a, _op, _b) (fr_time_delta_unwrap(_a) _op fr_time_delta_unwrap(_b))
281 #define fr_time_delta_gt(_a, _b) (fr_time_delta_unwrap(_a) > fr_time_delta_unwrap(_b))
282 #define fr_time_delta_gteq(_a, _b) (fr_time_delta_unwrap(_a) >= fr_time_delta_unwrap(_b))
283 #define fr_time_delta_lt(_a, _b) (fr_time_delta_unwrap(_a) < fr_time_delta_unwrap(_b))
284 #define fr_time_delta_lteq(_a, _b) (fr_time_delta_unwrap(_a) <= fr_time_delta_unwrap(_b))
285 #define fr_time_delta_eq(_a, _b) (fr_time_delta_unwrap(_a) == fr_time_delta_unwrap(_b))
286 #define fr_time_delta_neq(_a, _b) (fr_time_delta_unwrap(_a) != fr_time_delta_unwrap(_b))
287 
288 #define fr_time_delta_ispos(_a) (fr_time_delta_unwrap(_a) > 0)
289 #define fr_time_delta_isneg(_a) (fr_time_delta_unwrap(_a) < 0)
290 /** @} */
291 
292 /** @name fr_unix_time_t arithmetic and comparison macros
293  *
294  * We wrap the 64bit signed time value in a struct to prevent misuse.
295  *
296  * The macros below allow basic arithmetic and comparisons to be performed.
297  * @{
298  */
299 /* Don't add fr_unix_time_add_time_time, it's almost always a type error */
301 {
304  return fr_unix_time_wrap(out);
305 }
307 {
310  return fr_unix_time_wrap(out);
311 }
312 
313 /** Add a time/time delta together
314  *
315  * Types may either be:
316  * - fr_unix_time_add((fr_unix_time_t), (fr_time_delta_t))
317  * - fr_unix_time_add((fr_time_delta_t), (fr_time_delta_t))
318  *
319  * Adding two time values together is most likely an error.
320  * Adding two time_delta values together can be done with #fr_time_delta_add.
321  */
322 #define fr_unix_time_add(_a, _b) \
323  _Generic(_a, \
324  fr_unix_time_t : _Generic(_b, \
325  fr_time_delta_t : fr_unix_time_add_time_delta \
326  ), \
327  fr_time_delta_t : _Generic(_b, \
328  fr_unix_time_t : fr_unix_time_add_delta_time, \
329  fr_time_delta_t : fr_time_delta_add \
330  ) \
331  )(_a, _b)
332 
334 {
337  return fr_time_delta_wrap(out);
338 }
340 {
343  return fr_unix_time_wrap(out);
344 }
345 
346 /** Subtract one time from another
347  *
348  * Types may either be:
349  * - fr_unix_time_sub((fr_unix_time_t), (fr_unix_time_t)) - Produces a #fr_time_delta_t
350  * - fr_unix_time_sub((fr_unix_time_t), (fr_time_delta_t)) - Produces a #fr_unix_time_t
351  *
352  * Subtracting time from a delta is most likely an error.
353  * Subtracting two time_delta values can be done with #fr_time_delta_sub
354  */
355 #define fr_unix_time_sub(_a, _b) \
356  _Generic(_a, \
357  fr_unix_time_t : _Generic(_b, \
358  fr_unix_time_t : fr_unix_time_sub_time_time, \
359  fr_time_delta_t : fr_unix_time_sub_time_delta \
360  ) \
361  )(_a, _b)
362 
363 #define fr_unix_time_gt(_a, _b) (fr_unix_time_unwrap(_a) > fr_unix_time_unwrap(_b))
364 #define fr_unix_time_gteq(_a, _b) (fr_unix_time_unwrap(_a) >= fr_unix_time_unwrap(_b))
365 #define fr_unix_time_lt(_a, _b) (fr_unix_time_unwrap(_a) < fr_unix_time_unwrap(_b))
366 #define fr_unix_time_lteq(_a, _b) (fr_unix_time_unwrap(_a) <= fr_unix_time_unwrap(_b))
367 #define fr_unix_time_eq(_a, _b) (fr_unix_time_unwrap(_a) == fr_unix_time_unwrap(_b))
368 #define fr_unix_time_neq(_a, _b) (fr_unix_time_unwrap(_a) != fr_unix_time_unwrap(_b))
369 
370 #define fr_unix_time_ispos(_a) (fr_unix_time_unwrap(_a) > 0)
371 /** @} */
372 
373 typedef struct {
374  uint64_t array[8]; //!< 100ns to 100s
376 
377 #define NSEC (1000000000)
378 #define USEC (1000000)
379 #define MSEC (1000)
380 #define CSEC (100)
381 
382 /*
383  * Pre-defined "magic" values for time in a month and year. The number of seconds in a year is:
384  *
385  * 1 year is 365.2425 days. times 86400 seconds in a day.
386  *
387  * The average month is simply one twelfth of that. Note that the exact value for both year and month
388  * duration are really magic values, which people will never stumble upon themselves. As such, they can
389  * be used (somewhat, in some cases) as magic tokens meaning "year" or "month".
390  */
391 #define FR_TIME_DUR_YEAR ((int64_t)NSEC * 31556952)
392 #define FR_TIME_DUR_MONTH (FR_TIME_DUR_YEAR/12)
393 
394 
395 /*
396  * The value of clock_gettime(CLOCK_MONOTONIC_RAW) when we started. i.e. our epoch.
397  */
398 extern int64_t fr_time_epoch;
399 
400 /*
401  * The offset from CLOCK_MONOTONIC_RAW to CLOCK_REALTIME.
402  */
404 
405 /** @name fr_unix_time_t scale conversion macros/functions
406  *
407  * @{
408  */
409 static inline fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
410 {
411  int64_t out;
412  if (res == FR_TIME_RES_INVALID) return fr_unix_time_max();
413  if (!fr_multiply(&out, integer, fr_time_multiplier_by_res[res])) {
414  if (overflow) *overflow = true;
415  return fr_unix_time_max();
416  }
417  if (overflow) *overflow = false;
418  return fr_unix_time_wrap(out);
419 }
420 
421 static inline fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
422 {
423  return fr_unix_time_wrap(nsec);
424 }
425 
426 static inline fr_unix_time_t fr_unix_time_from_usec(int64_t usec)
427 {
428  uint64_t out;
429  if (!fr_multiply(&out, usec, (NSEC / USEC))) return (usec > 0) ? fr_unix_time_max() : fr_unix_time_min();
430  return fr_unix_time_wrap(out);
431 }
432 
433 static inline fr_unix_time_t fr_unix_time_from_msec(int64_t msec)
434 {
435  uint64_t out;
436  if (!fr_multiply(&out, msec, (NSEC / MSEC))) return (msec > 0) ? fr_unix_time_max() : fr_unix_time_min();
437  return fr_unix_time_wrap(out);
438 }
439 
440 static inline fr_unix_time_t fr_unix_time_from_csec(int64_t csec)
441 {
442  uint64_t out;
443  if (!fr_multiply(&out, csec, (NSEC / CSEC))) return (csec > 0) ? fr_unix_time_max() : fr_unix_time_min();
444  return fr_unix_time_wrap(out);
445 }
446 
447 static inline fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
448 {
449  uint64_t out;
450  if (!fr_multiply(&out, sec, NSEC)) return (sec > 0) ? fr_unix_time_max() : fr_unix_time_min();
451  return fr_unix_time_wrap(out);
452 }
453 
454 static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timeval(struct timeval const *tv)
455 {
456  typeof_field(fr_unix_time_t, value) integer, fraction, out;
457 
458  if (!fr_multiply(&integer, (typeof_field(fr_unix_time_t, value)) tv->tv_sec, NSEC)) {
459  overflow:
460  return fr_unix_time_max();
461  }
462 
463  if (!fr_multiply(&fraction,
464  (typeof_field(fr_unix_time_t, value)) tv->tv_usec, (NSEC / USEC))) goto overflow;
465 
466  if (!fr_add(&out, integer, fraction)) goto overflow;
467 
468  return fr_unix_time_wrap(out);
469 }
470 
471 static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timespec(struct timespec const *ts)
472 {
474 
475  if (!fr_multiply(&integer, (typeof_field(fr_unix_time_t, value)) ts->tv_sec, NSEC)) {
476  overflow:
477  return fr_unix_time_max();
478  }
479  if (!fr_add(&out, integer, ts->tv_nsec)) goto overflow;
480 
481  return fr_unix_time_wrap(out);
482 }
483 
484 static inline int64_t fr_unix_time_to_integer(fr_unix_time_t delta, fr_time_res_t res)
485 {
486  return fr_unix_time_unwrap(delta) / fr_time_multiplier_by_res[res];
487 }
488 
489 static inline int64_t fr_unix_time_to_usec(fr_unix_time_t delta)
490 {
491  return fr_unix_time_unwrap(delta) / (NSEC / USEC);
492 }
493 
494 static inline int64_t fr_unix_time_to_msec(fr_unix_time_t delta)
495 {
496  return fr_unix_time_unwrap(delta) / (NSEC / MSEC);
497 }
498 
499 static inline int64_t fr_unix_time_to_csec(fr_unix_time_t delta)
500 {
501  return fr_unix_time_unwrap(delta) / (NSEC / CSEC);
502 }
503 
504 static inline int64_t fr_unix_time_to_sec(fr_unix_time_t delta)
505 {
506  return (fr_unix_time_unwrap(delta) / NSEC);
507 }
508 
509 static inline int64_t fr_unix_time_to_min(fr_unix_time_t delta)
510 {
511  return (fr_unix_time_unwrap(delta) / NSEC) / 60;
512 }
513 
514 static inline int64_t fr_unix_time_to_hour(fr_unix_time_t delta)
515 {
516  return (fr_unix_time_unwrap(delta) / NSEC) / 3600;
517 }
518 
519 static inline int64_t fr_unix_time_to_day(fr_unix_time_t delta)
520 {
521  return (fr_unix_time_unwrap(delta) / NSEC) / 386400;
522 }
523 
524 /** Convert a time_t into out internal fr_unix_time_t
525  *
526  * Our internal unix time representation is unsigned and in nanoseconds which
527  * is different from time_t which is signed and has seconds resolution.
528  *
529  * If time is negative we return 0.
530  *
531  * @param[in] time to convert.
532  * @return Unix time in seconds.
533  */
534 static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_time(time_t time)
535 {
536  if (time < 0) return fr_unix_time_min();
537 
538  return fr_unix_time_wrap(time * NSEC);
539 }
540 /** @} */
541 
542 /** @name fr_time_delta_t scale conversion macros/functions
543  *
544  * @{
545  */
546 static inline fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
547 {
548  int64_t out;
549  if (res == FR_TIME_RES_INVALID) {
550  if (overflow) *overflow = true;
551  return fr_time_delta_max();
552  }
553  if (!fr_multiply(&out, integer, fr_time_multiplier_by_res[res])) {
554  if (overflow) *overflow = true;
555  return fr_time_delta_wrap(integer > 0 ? INT64_MAX: INT64_MIN);
556  }
557  if (overflow) *overflow = false;
558  return fr_time_delta_wrap(out);
559 }
560 
561 static inline fr_time_delta_t fr_time_delta_from_nsec(int64_t nsec)
562 {
563  return fr_time_delta_wrap(nsec);
564 }
565 
566 static inline fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
567 {
568  int64_t out;
569  if (!fr_multiply(&out, usec, (NSEC / USEC))) return (usec > 0) ? fr_time_delta_max() : fr_time_delta_min();
570  return fr_time_delta_wrap(out);
571 }
572 
573 static inline fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
574 {
575  int64_t out;
576  if (!fr_multiply(&out, msec, (NSEC / MSEC))) return (msec > 0) ? fr_time_delta_max() : fr_time_delta_min();
577  return fr_time_delta_wrap(out);
578 }
579 
580 static inline fr_time_delta_t fr_time_delta_from_csec(int64_t csec)
581 {
582  int64_t out;
583  if (!fr_multiply(&out, csec, (NSEC / CSEC))) return (csec > 0) ? fr_time_delta_max() : fr_time_delta_min();
584  return fr_time_delta_wrap(out);
585 }
586 
587 /** @hidecallergraph */
588 static inline fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
589 {
590  int64_t out;
591  if (!fr_multiply(&out, sec, NSEC)) return (sec > 0) ? fr_time_delta_max() : fr_time_delta_min();
592  return fr_time_delta_wrap(out);
593 }
594 
595 static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv)
596 {
597  typeof_field(fr_time_delta_t, value) integer, fraction, out;
598 
599  if (!fr_multiply(&integer, (typeof_field(fr_time_delta_t, value)) tv->tv_sec, NSEC)) {
600  overflow:
601  return fr_time_delta_max();
602  }
603 
604  if (!fr_multiply(&fraction,
605  (typeof_field(fr_time_delta_t, value)) tv->tv_usec, (NSEC / USEC))) goto overflow;
606 
607  if (!fr_add(&out, integer, fraction)) goto overflow;
608 
609  return fr_time_delta_wrap(out);
610 }
611 
612 static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
613 {
615 
616  if (!fr_multiply(&integer, (typeof_field(fr_time_delta_t, value)) ts->tv_sec, NSEC)) {
617  overflow:
618  return fr_time_delta_max();
619  }
620  if (!fr_add(&out, integer, ts->tv_nsec)) goto overflow;
621 
622  return fr_time_delta_wrap(out);
623 }
624 
625 static inline int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
626 {
627  return fr_time_delta_unwrap(delta) / fr_time_multiplier_by_res[res];
628 }
629 
630 static inline int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
631 {
632  return fr_time_delta_unwrap(delta) / (NSEC / USEC);
633 }
634 
635 static inline int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
636 {
637  return fr_time_delta_unwrap(delta) / (NSEC / MSEC);
638 }
639 
640 static inline int64_t fr_time_delta_to_csec(fr_time_delta_t delta)
641 {
642  return fr_time_delta_unwrap(delta) / (NSEC / CSEC);
643 }
644 
645 static inline int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
646 {
647  return (fr_time_delta_unwrap(delta) / NSEC);
648 }
649 
650 /** Convert a delta to a timeval
651  *
652  * @param[in] _delta in nanoseconds.
653  */
654 #define fr_time_delta_to_timeval(_delta) \
655 (struct timeval){ \
656  .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
657  .tv_usec = (fr_time_delta_unwrap(_delta) % NSEC) / (NSEC / USEC) \
658 }
659 
660 /** Convert a delta to a timespec
661  *
662  * @param[in] _delta in nanoseconds.
663  */
664 #define fr_time_delta_to_timespec(_delta)\
665 (struct timespec){ \
666  .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
667  .tv_nsec = (fr_time_delta_unwrap(_delta) % NSEC) \
668 }
669 /** @} */
670 
671 /** @name fr_time_delta_t scale conversion macros/functions
672  *
673  * @{
674  */
675 /** Return the current value of fr_time_monotonic_to_realtime.
676  *
677  */
678 static inline int64_t fr_time_offset_to_realtime(void)
679 {
681 }
682 
683 /** Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
684  *
685  */
687 {
688  int64_t out;
689 
691  return fr_time_unwrap(when) ? fr_unix_time_max() : fr_unix_time_min();
692  }
693  return fr_unix_time_wrap(out);
694 }
695 
696 /** Convert an fr_time_t (internal time) to number of usec since the unix epoch (wallclock time)
697  *
698  */
699 static inline int64_t fr_time_to_usec(fr_time_t when)
700 {
701  /* Divide each operand separately to avoid overflow on addition */
702  return (((fr_time_unwrap(when) / (NSEC / USEC)) +
704 }
705 
706 /** Convert an fr_time_t (internal time) to number of msec since the unix epoch (wallclock time)
707  *
708  */
709 static inline int64_t fr_time_to_msec(fr_time_t when)
710 {
711  /* Divide each operand separately to avoid overflow on addition */
712  return (((fr_time_unwrap(when) / (NSEC / MSEC)) +
714 }
715 
716 /** Convert an fr_time_t (internal time) to number of csec since the unix epoch (wallclock time)
717  *
718  */
719 static inline int64_t fr_time_to_csec(fr_time_t when)
720 {
721  /* Divide each operand separately to avoid overflow on addition */
722  return (((fr_time_unwrap(when) / (NSEC / CSEC)) +
724 }
725 
726 /** Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
727  *
728  */
729 static inline int64_t fr_time_to_sec(fr_time_t when)
730 {
731  /* Divide each operand separately to avoid overflow on addition */
732  return (((fr_time_unwrap(when) / NSEC) +
734 }
735 
736 /** Convert server epoch time to unix epoch time
737  *
738  * @param[in] _when The server epoch time to convert.
739  */
740 #define fr_time_to_timeval(_when) fr_time_delta_to_timeval(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
741 
742 /** Convert server epoch time to unix epoch time
743  *
744  * @param[in] _when The server epoch time to convert.
745  */
746 #define fr_time_to_timespec(_when) fr_time_delta_to_timespec(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
747 
748 /** Convert wallclock time to a fr_time_t (internal time)
749  *
750  * @param[out] overflow Whether the conversion overflowed.
751  * @param[in] when The timestamp to convert.
752  * @param[in] res The scale the integer value is in.
753  * @return
754  * - >0 number of nanoseconds since the server started.
755  * - 0 when the server started.
756  * - <0 number of nanoseconds before the server started.
757  */
758 static inline fr_time_t fr_time_from_integer(bool *overflow, int64_t when, fr_time_res_t res)
759 {
761 
762  if (!fr_multiply(&out, when, fr_time_multiplier_by_res[res])) {
763  if (overflow) *overflow = true;
764  return when > 0 ? fr_time_max() : fr_time_min();
765  }
766 
768  if (overflow) *overflow = true;
769  return when < 0 ? fr_time_max() : fr_time_min();
770  }
771 
772  if (overflow) *overflow = false;
773  return fr_time_wrap(out);
774 }
775 
776 /** Convert a nsec (wallclock time) to a fr_time_t (internal time)
777  *
778  * @param[in] when The timestamp to convert.
779  * @return
780  * - >0 number of nanoseconds since the server started.
781  * - 0 when the server started.
782  * - <0 number of nanoseconds before the server started.
783  */
784 static inline fr_time_t fr_time_from_nsec(int64_t when)
785 {
787 
789  return when > 0 ? fr_time_min() : fr_time_max();
790  }
791  return fr_time_wrap(out);
792 }
793 
794 /** Convert usec (wallclock time) to a fr_time_t (internal time)
795  *
796  * @param[in] when The timestamp to convert.
797  * @return
798  * - >0 number of nanoseconds since the server started.
799  * - 0 when the server started.
800  * - <0 number of nanoseconds before the server started.
801  */
802 static inline fr_time_t fr_time_from_usec(int64_t when)
803 {
805 
807  return when > 0 ? fr_time_min() : fr_time_max();
808  }
809  return fr_time_wrap(out);
810 }
811 
812 /** Convert msec (wallclock time) to a fr_time_t (internal time)
813  *
814  * @param[in] when The timestamp to convert.
815  * @return
816  * - >0 number of nanoseconds since the server started.
817  * - 0 when the server started.
818  * - <0 number of nanoseconds before the server started.
819  */
820 static inline fr_time_t fr_time_from_msec(int64_t when)
821 {
823 
825  return when > 0 ? fr_time_min() : fr_time_max();
826  }
827  return fr_time_wrap(out);
828 }
829 
830 /** Convert csec (wallclock time) to a fr_time_t (internal time)
831  *
832  * @param[in] when The timestamp to convert.
833  * @return
834  * - >0 number of nanoseconds since the server started.
835  * - 0 when the server started.
836  * - <0 number of nanoseconds before the server started.
837  */
838 static inline fr_time_t fr_time_from_csec(int64_t when)
839 {
841 
843  return when > 0 ? fr_time_min() : fr_time_max();
844  }
845  return fr_time_wrap(out);
846 }
847 
848 /** Convert a time_t (wallclock time) to a fr_time_t (internal time)
849  *
850  * @param[in] when The timestamp to convert.
851  * @return
852  * - >0 number of nanoseconds since the server started.
853  * - 0 when the server started.
854  * - <0 number of nanoseconds before the server started.
855  */
856 static inline fr_time_t fr_time_from_sec(time_t when)
857 {
859 
861  return when > 0 ? fr_time_min() : fr_time_max();
862  }
863  return fr_time_wrap(out);
864 }
865 
866 
867 
868 /** Convert a timespec (wallclock time) to a fr_time_t (internal time)
869  *
870  * @param[in] when_ts The timestamp to convert.
871  * @return
872  * - >0 number of nanoseconds since the server started.
873  * - 0 when the server started.
874  * - 0 if when_tv occurred before the server started.
875  */
876 static inline CC_HINT(nonnull) fr_time_t fr_time_from_timespec(struct timespec const *when_ts)
877 {
879 
880  if (!fr_sub(&out, tmp, fr_time_offset_to_realtime())) {
881  return tmp > 0 ? fr_time_min() : fr_time_max();
882  }
883  return fr_time_wrap(out);
884 }
885 
886 /** Convert a timeval (wallclock time) to a fr_time_t (internal time)
887  *
888  * @param[in] when_tv The timestamp to convert.
889  * @return
890  * - >0 number of nanoseconds since the server started.
891  * - 0 when the server started.
892  * - <0 number of nanoseconds before the server started.
893  */
894 static inline CC_HINT(nonnull) fr_time_t fr_time_from_timeval(struct timeval const *when_tv)
895 {
897 
898  if (!fr_sub(&out, tmp, fr_time_offset_to_realtime())) {
899  return tmp > 0 ? fr_time_min() : fr_time_max();
900  }
901  return fr_time_wrap(out);
902 }
903 /** @} */
904 
905 /** Compare two fr_time_t values
906  *
907  * @param[in] a The first value to compare.
908  * @param[in] b The second value to compare.
909  * @return
910  * - +1 if a > b
911  * - 0 if a == b
912  * - -1 if a < b
913  */
914 static inline int8_t fr_time_cmp(fr_time_t a, fr_time_t b)
915 {
916  return CMP(fr_time_unwrap(a), fr_time_unwrap(b));
917 }
918 
919 /** Compare two fr_time_delta_t values
920  *
921  * @param[in] a The first value to compare.
922  * @param[in] b The second value to compare.
923  * @return
924  * - +1 if a > b
925  * - 0 if a == b
926  * - -1 if a < b
927  */
929 {
931 }
932 
933 /** Compare two fr_unix_time_t values
934  *
935  * @param[in] a The first value to compare.
936  * @param[in] b The second value to compare.
937  * @return
938  * - +1 if a > b
939  * - 0 if a == b
940  * - -1 if a < b
941  */
943 {
945 }
946 
947 #ifndef CLOCK_MONOTONIC_RAW
948 #define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
949 #endif
950 
951 /** Return a relative time since the server fr_time_epoch
952  *
953  * This time is useful for doing time comparisons, deltas, etc.
954  * Human (i.e. printable) time is something else.
955  *
956  * @returns fr_time_t time in nanoseconds since the server fr_time_epoch.
957  *
958  * @hidecallergraph
959  */
960 static inline fr_time_t fr_time(void)
961 {
962  struct timespec ts;
963  (void) clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
965 }
966 
967 int fr_time_start(void);
968 int fr_time_sync(void);
969 
970 int64_t fr_time_scale(int64_t t, fr_time_res_t hint);
971 
972 int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta)
973  CC_HINT(nonnull);
974 
976  bool no_trailing, fr_sbuff_term_t const *tt)
977  CC_HINT(nonnull(1,2));
978 
980  CC_HINT(nonnull);
981 
983  CC_HINT(nonnull);
984 
985 size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt)
986  CC_HINT(format(strftime, 3, 0));
987 
988 size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt)
989  CC_HINT(format(strftime, 3, 0));
990 
992  CC_HINT(nonnull);
993 
994 void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs)
995  CC_HINT(nonnull(1,2));
996 
998  CC_HINT(nonnull);
999 
1000 int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
1001  CC_HINT(nonnull);
1002 
1004  CC_HINT(nonnull);
1005 
1007 
1008 bool fr_time_is_dst(void);
1009 
1010 #ifdef __cplusplus
1011 }
1012 #endif
static int const char * fmt
Definition: acutest.h:573
#define typeof_field(_type, _field)
Typeof field.
Definition: build.h:172
#define RCSIDH(h, id)
Definition: build.h:445
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition: build.h:110
static const char * tabs
Definition: command.c:1581
static fr_slen_t in
Definition: dict.h:645
Test enumeration values.
Definition: dict_test.h:92
#define fr_sub(_out, _a, _b)
Subtracts two integers.
Definition: math.h:140
#define fr_add(_out, _a, _b)
Adds two integers.
Definition: math.h:129
#define fr_multiply(_out, _a, _b)
Multiplies two integers together.
Definition: math.h:118
ssize_t fr_slen_t
Definition: merged_model.c:35
static size_t array[MY_ARRAY_SIZE]
Set of terminal elements.
Definition: merged_model.c:161
@ memory_order_consume
Definition: stdatomic.h:128
#define _Atomic(T)
Definition: stdatomic.h:77
#define atomic_load_explicit(object, order)
Definition: stdatomic.h:312
An element in an arbitrarily ordered array of name to num mappings.
Definition: table.h:53
static fr_time_t fr_time_from_csec(int64_t when)
Convert csec (wallclock time) to a fr_time_t (internal time)
Definition: time.h:838
fr_slen_t fr_time_delta_from_substr(fr_time_delta_t *out, fr_sbuff_t *in, fr_time_res_t hint, bool no_trailing, fr_sbuff_term_t const *tt))
Create fr_time_delta_t from a string.
Definition: time.c:214
static fr_unix_time_t fr_unix_time_sub_time_delta(fr_unix_time_t a, fr_time_delta_t b)
Definition: time.h:339
static fr_unix_time_t fr_unix_time_from_msec(int64_t msec)
Definition: time.h:433
static fr_time_t fr_time_from_timeval(struct timeval const *when_tv)
Convert a timeval (wallclock time) to a fr_time_t (internal time)
Definition: time.h:894
void fr_time_elapsed_update(fr_time_elapsed_t *elapsed, fr_time_t start, fr_time_t end)
Definition: time.c:580
static fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
Definition: time.h:546
fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
Definition: time.c:661
#define MSEC
Definition: time.h:379
static fr_time_t fr_time_from_nsec(int64_t when)
Convert a nsec (wallclock time) to a fr_time_t (internal time)
Definition: time.h:784
#define fr_time_delta_min()
Definition: time.h:151
static fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
Definition: time.h:573
static int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
Definition: time.h:625
static fr_time_t fr_time_from_msec(int64_t when)
Convert msec (wallclock time) to a fr_time_t (internal time)
Definition: time.h:820
static int64_t fr_time_to_sec(fr_time_t when)
Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
Definition: time.h:729
static fr_time_delta_t fr_time_delta_add(fr_time_delta_t a, fr_time_delta_t b)
Definition: time.h:255
static fr_unix_time_t fr_unix_time_add_delta_time(fr_time_delta_t a, fr_unix_time_t b)
Definition: time.h:306
static fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
Definition: time.h:421
static fr_time_t fr_time_add_time_delta(fr_time_t a, fr_time_delta_t b)
Definition: time.h:173
int fr_time_sync(void)
Get a new fr_time_monotonic_to_realtime value.
Definition: time.c:102
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
Definition: time.h:154
static int64_t fr_time_to_msec(fr_time_t when)
Convert an fr_time_t (internal time) to number of msec since the unix epoch (wallclock time)
Definition: time.h:709
static int8_t fr_time_delta_cmp(fr_time_delta_t a, fr_time_delta_t b)
Compare two fr_time_delta_t values.
Definition: time.h:928
fr_table_num_ordered_t const fr_time_precision_table[]
Definition: time.c:46
static int64_t fr_unix_time_to_min(fr_unix_time_t delta)
Definition: time.h:509
static fr_time_t fr_time_from_integer(bool *overflow, int64_t when, fr_time_res_t res)
Convert wallclock time to a fr_time_t (internal time)
Definition: time.h:758
#define fr_time_delta_overflow_add(_a, _b)
Definition: time.h:155
static int64_t fr_time_unwrap(fr_time_t time)
Definition: time.h:146
int64_t value
Definition: time.h:81
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
Definition: time.h:588
static int64_t fr_unix_time_to_csec(fr_unix_time_t delta)
Definition: time.h:499
#define fr_unix_time_overflow_sub(_a, _b)
Definition: time.h:163
static int64_t fr_unix_time_to_sec(fr_unix_time_t delta)
Definition: time.h:504
#define fr_time_delta_wrap(_time)
Definition: time.h:152
int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta)
Return time delta from the time zone.
Definition: time.c:176
#define fr_time_min()
Definition: time.h:144
#define fr_time_wrap(_time)
Definition: time.h:145
fr_slen_t fr_time_delta_from_str(fr_time_delta_t *out, char const *in, size_t inlen, fr_time_res_t hint)
Create fr_time_delta_t from a string.
Definition: time.c:445
static fr_time_t fr_time_add_delta_time(fr_time_delta_t a, fr_time_t b)
Definition: time.h:180
bool fr_time_is_dst(void)
Whether or not we're daylight savings.
Definition: time.c:1241
#define fr_unix_time_min()
Definition: time.h:159
static fr_unix_time_t fr_unix_time_from_timeval(struct timeval const *tv)
Definition: time.h:454
static int64_t fr_time_delta_to_csec(fr_time_delta_t delta)
Definition: time.h:640
#define fr_time_overflow_add(_a, _b)
Definition: time.h:147
static fr_unix_time_t fr_unix_time_from_timespec(struct timespec const *ts)
Definition: time.h:471
#define fr_unix_time_wrap(_time)
Definition: time.h:160
static int64_t fr_time_to_usec(fr_time_t when)
Convert an fr_time_t (internal time) to number of usec since the unix epoch (wallclock time)
Definition: time.h:699
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
Definition: time.h:645
_Atomic int64_t fr_time_monotonic_to_realtime
difference between the two clocks
Definition: time.c:87
int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
Convert string in various formats to a fr_unix_time_t.
Definition: time.c:827
static fr_time_t fr_time_from_usec(int64_t when)
Convert usec (wallclock time) to a fr_time_t (internal time)
Definition: time.h:802
#define fr_time_delta_overflow_sub(_a, _b)
Definition: time.h:156
int64_t fr_time_scale(int64_t t, fr_time_res_t hint)
Scale an input time to NSEC, clamping it at max / min.
Definition: time.c:716
int64_t value
Signed because we need times before the server started for things like certificate validity checks an...
Definition: time.h:70
fr_slen_t fr_unix_time_to_str(fr_sbuff_t *out, fr_unix_time_t time, fr_time_res_t res)
Convert unix time to string.
Definition: time.c:1154
static fr_time_delta_t fr_time_sub_time_time(fr_time_t a, fr_time_t b)
Definition: time.h:207
fr_time_res_t
The base resolution for print parse operations.
Definition: time.h:48
@ FR_TIME_RES_MONTH
Definition: time.h:55
@ FR_TIME_RES_MSEC
Definition: time.h:58
@ FR_TIME_RES_WEEK
Definition: time.h:54
@ FR_TIME_RES_MIN
Definition: time.h:51
@ FR_TIME_RES_CSEC
Definition: time.h:57
@ FR_TIME_RES_HOUR
Definition: time.h:52
@ FR_TIME_RES_YEAR
Definition: time.h:56
@ FR_TIME_RES_DAY
Definition: time.h:53
@ FR_TIME_RES_NSEC
Definition: time.h:60
@ FR_TIME_RES_USEC
Definition: time.h:59
@ FR_TIME_RES_SEC
Definition: time.h:50
@ FR_TIME_RES_INVALID
Definition: time.h:49
static int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
Definition: time.h:630
static fr_time_t fr_time_from_timespec(struct timespec const *when_ts)
Convert a timespec (wallclock time) to a fr_time_t (internal time)
Definition: time.h:876
static fr_unix_time_t fr_unix_time_from_csec(int64_t csec)
Definition: time.h:440
static fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
Definition: time.h:447
size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt))
Copy a time string (UTC) to an sbuff.
Definition: time.c:565
#define fr_unix_time_overflow_add(_a, _b)
Definition: time.h:162
static int64_t fr_unix_time_to_day(fr_unix_time_t delta)
Definition: time.h:519
static fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
Definition: time.h:409
fr_time_delta_t fr_time_gmtoff(void)
Get the offset to gmt.
Definition: time.c:1233
#define NSEC
Definition: time.h:377
static int64_t fr_unix_time_to_usec(fr_unix_time_t delta)
Definition: time.h:489
#define fr_time_overflow_sub(_a, _b)
Definition: time.h:148
static int8_t fr_unix_time_cmp(fr_unix_time_t a, fr_unix_time_t b)
Compare two fr_unix_time_t values.
Definition: time.h:942
void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs))
Definition: time.c:625
struct fr_time_s fr_time_t
"server local" time.
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
Definition: time.h:856
static uint64_t fr_unix_time_unwrap(fr_unix_time_t time)
Definition: time.h:161
static fr_unix_time_t fr_unix_time_add_time_delta(fr_unix_time_t a, fr_time_delta_t b)
Definition: time.h:300
#define CLOCK_MONOTONIC_RAW
Definition: time.h:948
#define fr_unix_time_max()
Definition: time.h:158
static fr_time_delta_t fr_time_delta_from_nsec(int64_t nsec)
Definition: time.h:561
fr_slen_t fr_time_delta_to_str(fr_sbuff_t *out, fr_time_delta_t delta, fr_time_res_t res, bool is_unsigned)
Print fr_time_delta_t to a string with an appropriate suffix.
Definition: time.c:468
static int64_t fr_unix_time_to_integer(fr_unix_time_t delta, fr_time_res_t res)
Definition: time.h:484
static fr_time_delta_t fr_time_delta_sub(fr_time_delta_t a, fr_time_delta_t b)
Definition: time.h:261
static fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv)
Definition: time.h:595
uint64_t value
Definition: time.h:96
size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt))
Copy a time string (local timezone) to an sbuff.
Definition: time.c:536
static fr_time_delta_t fr_time_delta_from_csec(int64_t csec)
Definition: time.h:580
static int64_t fr_unix_time_to_msec(fr_unix_time_t delta)
Definition: time.h:494
size_t fr_time_precision_table_len
Definition: time.c:84
static fr_time_t fr_time(void)
Return a relative time since the server fr_time_epoch.
Definition: time.h:960
static fr_time_t fr_time_sub_time_delta(fr_time_t a, fr_time_delta_t b)
Definition: time.h:213
static fr_unix_time_t fr_unix_time_from_time(time_t time)
Convert a time_t into out internal fr_unix_time_t.
Definition: time.h:534
static bool fr_time_op_ispos(bool a, bool op, bool b)
Definition: time.h:119
#define USEC
Definition: time.h:378
static int64_t fr_time_offset_to_realtime(void)
Return the current value of fr_time_monotonic_to_realtime.
Definition: time.h:678
static int64_t fr_time_to_csec(fr_time_t when)
Convert an fr_time_t (internal time) to number of csec since the unix epoch (wallclock time)
Definition: time.h:719
static fr_time_delta_t fr_time_delta_mul(fr_time_delta_t a, fr_time_delta_t b)
Definition: time.h:271
static fr_time_delta_t fr_time_delta_div(fr_time_delta_t a, fr_time_delta_t b)
Definition: time.h:267
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
Definition: time.h:686
static fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
Definition: time.h:566
struct fr_time_delta_s fr_time_delta_t
A time delta, a difference in time measured in nanoseconds.
#define CSEC
Definition: time.h:380
int fr_time_start(void)
Initialize the local time.
Definition: time.c:150
static fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
Definition: time.h:612
static fr_time_delta_t fr_unix_time_sub_time_time(fr_unix_time_t a, fr_unix_time_t b)
Definition: time.h:333
#define fr_time_max()
Definition: time.h:143
#define fr_time_delta_max()
Definition: time.h:150
static int64_t fr_unix_time_to_hour(fr_unix_time_t delta)
Definition: time.h:514
static int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
Definition: time.h:635
static int8_t fr_time_cmp(fr_time_t a, fr_time_t b)
Compare two fr_time_t values.
Definition: time.h:914
static fr_unix_time_t fr_unix_time_from_usec(int64_t usec)
Definition: time.h:426
int64_t fr_time_epoch
monotonic clock at boot, i.e. our epoch
Definition: time.c:86
struct fr_unix_time_s fr_unix_time_t
"Unix" time.
int64_t const fr_time_multiplier_by_res[]
Definition: time.c:32
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
"server local" time.
Definition: time.h:69
"Unix" time.
Definition: time.h:95
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:984
int nonnull(2, 5))
int format(printf, 5, 0))
static size_t char ** out
Definition: value.h:984