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: 8b88a88bde62d1f04e9478da459d19c419a206b7 $
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: 8b88a88bde62d1f04e9478da459d19c419a206b7 $")
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 {
269  if (fr_time_delta_unwrap(b) == 0) return fr_time_delta_wrap(0);
270 
272 }
274 {
276  if (!fr_multiply(&out, fr_time_delta_unwrap(a), b)) {
277  return a;
278  }
279  return fr_time_delta_wrap(out);
280 }
281 
282 #define fr_time_delta_cond(_a, _op, _b) (fr_time_delta_unwrap(_a) _op fr_time_delta_unwrap(_b))
283 #define fr_time_delta_gt(_a, _b) (fr_time_delta_unwrap(_a) > fr_time_delta_unwrap(_b))
284 #define fr_time_delta_gteq(_a, _b) (fr_time_delta_unwrap(_a) >= fr_time_delta_unwrap(_b))
285 #define fr_time_delta_lt(_a, _b) (fr_time_delta_unwrap(_a) < fr_time_delta_unwrap(_b))
286 #define fr_time_delta_lteq(_a, _b) (fr_time_delta_unwrap(_a) <= fr_time_delta_unwrap(_b))
287 #define fr_time_delta_eq(_a, _b) (fr_time_delta_unwrap(_a) == fr_time_delta_unwrap(_b))
288 #define fr_time_delta_neq(_a, _b) (fr_time_delta_unwrap(_a) != fr_time_delta_unwrap(_b))
289 
290 #define fr_time_delta_ispos(_a) (fr_time_delta_unwrap(_a) > 0)
291 #define fr_time_delta_isneg(_a) (fr_time_delta_unwrap(_a) < 0)
292 /** @} */
293 
294 /** @name fr_unix_time_t arithmetic and comparison macros
295  *
296  * We wrap the 64bit signed time value in a struct to prevent misuse.
297  *
298  * The macros below allow basic arithmetic and comparisons to be performed.
299  * @{
300  */
301 /* Don't add fr_unix_time_add_time_time, it's almost always a type error */
303 {
306  return fr_unix_time_wrap(out);
307 }
309 {
312  return fr_unix_time_wrap(out);
313 }
314 
315 /** Add a time/time delta together
316  *
317  * Types may either be:
318  * - fr_unix_time_add((fr_unix_time_t), (fr_time_delta_t))
319  * - fr_unix_time_add((fr_time_delta_t), (fr_time_delta_t))
320  *
321  * Adding two time values together is most likely an error.
322  * Adding two time_delta values together can be done with #fr_time_delta_add.
323  */
324 #define fr_unix_time_add(_a, _b) \
325  _Generic(_a, \
326  fr_unix_time_t : _Generic(_b, \
327  fr_time_delta_t : fr_unix_time_add_time_delta \
328  ), \
329  fr_time_delta_t : _Generic(_b, \
330  fr_unix_time_t : fr_unix_time_add_delta_time, \
331  fr_time_delta_t : fr_time_delta_add \
332  ) \
333  )(_a, _b)
334 
336 {
339  return fr_time_delta_wrap(out);
340 }
342 {
345  return fr_unix_time_wrap(out);
346 }
347 
348 /** Subtract one time from another
349  *
350  * Types may either be:
351  * - fr_unix_time_sub((fr_unix_time_t), (fr_unix_time_t)) - Produces a #fr_time_delta_t
352  * - fr_unix_time_sub((fr_unix_time_t), (fr_time_delta_t)) - Produces a #fr_unix_time_t
353  *
354  * Subtracting time from a delta is most likely an error.
355  * Subtracting two time_delta values can be done with #fr_time_delta_sub
356  */
357 #define fr_unix_time_sub(_a, _b) \
358  _Generic(_a, \
359  fr_unix_time_t : _Generic(_b, \
360  fr_unix_time_t : fr_unix_time_sub_time_time, \
361  fr_time_delta_t : fr_unix_time_sub_time_delta \
362  ) \
363  )(_a, _b)
364 
365 #define fr_unix_time_gt(_a, _b) (fr_unix_time_unwrap(_a) > fr_unix_time_unwrap(_b))
366 #define fr_unix_time_gteq(_a, _b) (fr_unix_time_unwrap(_a) >= fr_unix_time_unwrap(_b))
367 #define fr_unix_time_lt(_a, _b) (fr_unix_time_unwrap(_a) < fr_unix_time_unwrap(_b))
368 #define fr_unix_time_lteq(_a, _b) (fr_unix_time_unwrap(_a) <= fr_unix_time_unwrap(_b))
369 #define fr_unix_time_eq(_a, _b) (fr_unix_time_unwrap(_a) == fr_unix_time_unwrap(_b))
370 #define fr_unix_time_neq(_a, _b) (fr_unix_time_unwrap(_a) != fr_unix_time_unwrap(_b))
371 
372 #define fr_unix_time_ispos(_a) (fr_unix_time_unwrap(_a) > 0)
373 /** @} */
374 
375 typedef struct {
376  uint64_t array[8]; //!< 100ns to 100s
378 
379 #define NSEC (1000000000)
380 #define USEC (1000000)
381 #define MSEC (1000)
382 #define CSEC (100)
383 
384 /*
385  * Pre-defined "magic" values for time in a month and year. The number of seconds in a year is:
386  *
387  * 1 year is 365.2425 days. times 86400 seconds in a day.
388  *
389  * The average month is simply one twelfth of that. Note that the exact value for both year and month
390  * duration are really magic values, which people will never stumble upon themselves. As such, they can
391  * be used (somewhat, in some cases) as magic tokens meaning "year" or "month".
392  */
393 #define FR_TIME_DUR_YEAR ((int64_t)NSEC * 31556952)
394 #define FR_TIME_DUR_MONTH (FR_TIME_DUR_YEAR/12)
395 
396 
397 /*
398  * The value of clock_gettime(CLOCK_MONOTONIC_RAW) when we started. i.e. our epoch.
399  */
400 extern int64_t fr_time_epoch;
401 
402 /*
403  * The offset from CLOCK_MONOTONIC_RAW to CLOCK_REALTIME.
404  */
406 
407 /** @name fr_unix_time_t scale conversion macros/functions
408  *
409  * @{
410  */
411 static inline fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
412 {
413  int64_t out;
414  if (res == FR_TIME_RES_INVALID) return fr_unix_time_max();
415  if (!fr_multiply(&out, integer, fr_time_multiplier_by_res[res])) {
416  if (overflow) *overflow = true;
417  return fr_unix_time_max();
418  }
419  if (overflow) *overflow = false;
420  return fr_unix_time_wrap(out);
421 }
422 
423 static inline fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
424 {
425  return fr_unix_time_wrap(nsec);
426 }
427 
428 static inline fr_unix_time_t fr_unix_time_from_usec(int64_t usec)
429 {
430  uint64_t out;
431  if (!fr_multiply(&out, usec, (NSEC / USEC))) return (usec > 0) ? fr_unix_time_max() : fr_unix_time_min();
432  return fr_unix_time_wrap(out);
433 }
434 
435 static inline fr_unix_time_t fr_unix_time_from_msec(int64_t msec)
436 {
437  uint64_t out;
438  if (!fr_multiply(&out, msec, (NSEC / MSEC))) return (msec > 0) ? fr_unix_time_max() : fr_unix_time_min();
439  return fr_unix_time_wrap(out);
440 }
441 
442 static inline fr_unix_time_t fr_unix_time_from_csec(int64_t csec)
443 {
444  uint64_t out;
445  if (!fr_multiply(&out, csec, (NSEC / CSEC))) return (csec > 0) ? fr_unix_time_max() : fr_unix_time_min();
446  return fr_unix_time_wrap(out);
447 }
448 
449 static inline fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
450 {
451  uint64_t out;
452  if (!fr_multiply(&out, sec, NSEC)) return (sec > 0) ? fr_unix_time_max() : fr_unix_time_min();
453  return fr_unix_time_wrap(out);
454 }
455 
456 static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timeval(struct timeval const *tv)
457 {
458  typeof_field(fr_unix_time_t, value) integer, fraction, out;
459 
460  if (!fr_multiply(&integer, (typeof_field(fr_unix_time_t, value)) tv->tv_sec, NSEC)) {
461  overflow:
462  return fr_unix_time_max();
463  }
464 
465  if (!fr_multiply(&fraction,
466  (typeof_field(fr_unix_time_t, value)) tv->tv_usec, (NSEC / USEC))) goto overflow;
467 
468  if (!fr_add(&out, integer, fraction)) goto overflow;
469 
470  return fr_unix_time_wrap(out);
471 }
472 
473 static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timespec(struct timespec const *ts)
474 {
476 
477  if (!fr_multiply(&integer, (typeof_field(fr_unix_time_t, value)) ts->tv_sec, NSEC)) {
478  overflow:
479  return fr_unix_time_max();
480  }
481  if (!fr_add(&out, integer, ts->tv_nsec)) goto overflow;
482 
483  return fr_unix_time_wrap(out);
484 }
485 
486 static inline int64_t fr_unix_time_to_integer(fr_unix_time_t delta, fr_time_res_t res)
487 {
488  return fr_unix_time_unwrap(delta) / fr_time_multiplier_by_res[res];
489 }
490 
491 static inline int64_t fr_unix_time_to_usec(fr_unix_time_t delta)
492 {
493  return fr_unix_time_unwrap(delta) / (NSEC / USEC);
494 }
495 
496 static inline int64_t fr_unix_time_to_msec(fr_unix_time_t delta)
497 {
498  return fr_unix_time_unwrap(delta) / (NSEC / MSEC);
499 }
500 
501 static inline int64_t fr_unix_time_to_csec(fr_unix_time_t delta)
502 {
503  return fr_unix_time_unwrap(delta) / (NSEC / CSEC);
504 }
505 
506 static inline int64_t fr_unix_time_to_sec(fr_unix_time_t delta)
507 {
508  return (fr_unix_time_unwrap(delta) / NSEC);
509 }
510 
511 static inline int64_t fr_unix_time_to_min(fr_unix_time_t delta)
512 {
513  return (fr_unix_time_unwrap(delta) / NSEC) / 60;
514 }
515 
516 static inline int64_t fr_unix_time_to_hour(fr_unix_time_t delta)
517 {
518  return (fr_unix_time_unwrap(delta) / NSEC) / 3600;
519 }
520 
521 static inline int64_t fr_unix_time_to_day(fr_unix_time_t delta)
522 {
523  return (fr_unix_time_unwrap(delta) / NSEC) / 386400;
524 }
525 
526 /** Convert a time_t into out internal fr_unix_time_t
527  *
528  * Our internal unix time representation is unsigned and in nanoseconds which
529  * is different from time_t which is signed and has seconds resolution.
530  *
531  * If time is negative we return 0.
532  *
533  * @param[in] time to convert.
534  * @return Unix time in seconds.
535  */
536 static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_time(time_t time)
537 {
538  if (time < 0) return fr_unix_time_min();
539 
540  return fr_unix_time_wrap(time * NSEC);
541 }
542 /** @} */
543 
544 /** @name fr_time_delta_t scale conversion macros/functions
545  *
546  * @{
547  */
548 static inline fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
549 {
550  int64_t out;
551  if (res == FR_TIME_RES_INVALID) {
552  if (overflow) *overflow = true;
553  return fr_time_delta_max();
554  }
555  if (!fr_multiply(&out, integer, fr_time_multiplier_by_res[res])) {
556  if (overflow) *overflow = true;
557  return fr_time_delta_wrap(integer > 0 ? INT64_MAX: INT64_MIN);
558  }
559  if (overflow) *overflow = false;
560  return fr_time_delta_wrap(out);
561 }
562 
563 static inline fr_time_delta_t fr_time_delta_from_nsec(int64_t nsec)
564 {
565  return fr_time_delta_wrap(nsec);
566 }
567 
568 static inline fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
569 {
570  int64_t out;
571  if (!fr_multiply(&out, usec, (NSEC / USEC))) return (usec > 0) ? fr_time_delta_max() : fr_time_delta_min();
572  return fr_time_delta_wrap(out);
573 }
574 
575 static inline fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
576 {
577  int64_t out;
578  if (!fr_multiply(&out, msec, (NSEC / MSEC))) return (msec > 0) ? fr_time_delta_max() : fr_time_delta_min();
579  return fr_time_delta_wrap(out);
580 }
581 
582 static inline fr_time_delta_t fr_time_delta_from_csec(int64_t csec)
583 {
584  int64_t out;
585  if (!fr_multiply(&out, csec, (NSEC / CSEC))) return (csec > 0) ? fr_time_delta_max() : fr_time_delta_min();
586  return fr_time_delta_wrap(out);
587 }
588 
589 /** @hidecallergraph */
590 static inline fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
591 {
592  int64_t out;
593  if (!fr_multiply(&out, sec, NSEC)) return (sec > 0) ? fr_time_delta_max() : fr_time_delta_min();
594  return fr_time_delta_wrap(out);
595 }
596 
597 static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv)
598 {
599  typeof_field(fr_time_delta_t, value) integer, fraction, out;
600 
601  if (!fr_multiply(&integer, (typeof_field(fr_time_delta_t, value)) tv->tv_sec, NSEC)) {
602  overflow:
603  return fr_time_delta_max();
604  }
605 
606  if (!fr_multiply(&fraction,
607  (typeof_field(fr_time_delta_t, value)) tv->tv_usec, (NSEC / USEC))) goto overflow;
608 
609  if (!fr_add(&out, integer, fraction)) goto overflow;
610 
611  return fr_time_delta_wrap(out);
612 }
613 
614 static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
615 {
617 
618  if (!fr_multiply(&integer, (typeof_field(fr_time_delta_t, value)) ts->tv_sec, NSEC)) {
619  overflow:
620  return fr_time_delta_max();
621  }
622  if (!fr_add(&out, integer, ts->tv_nsec)) goto overflow;
623 
624  return fr_time_delta_wrap(out);
625 }
626 
627 static inline int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
628 {
629  return fr_time_delta_unwrap(delta) / fr_time_multiplier_by_res[res];
630 }
631 
632 static inline int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
633 {
634  return fr_time_delta_unwrap(delta) / (NSEC / USEC);
635 }
636 
637 static inline int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
638 {
639  return fr_time_delta_unwrap(delta) / (NSEC / MSEC);
640 }
641 
642 static inline int64_t fr_time_delta_to_csec(fr_time_delta_t delta)
643 {
644  return fr_time_delta_unwrap(delta) / (NSEC / CSEC);
645 }
646 
647 static inline int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
648 {
649  return (fr_time_delta_unwrap(delta) / NSEC);
650 }
651 
652 /** Convert a delta to a timeval
653  *
654  * @param[in] _delta in nanoseconds.
655  */
656 #define fr_time_delta_to_timeval(_delta) \
657 (struct timeval){ \
658  .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
659  .tv_usec = (fr_time_delta_unwrap(_delta) % NSEC) / (NSEC / USEC) \
660 }
661 
662 /** Convert a delta to a timespec
663  *
664  * @param[in] _delta in nanoseconds.
665  */
666 #define fr_time_delta_to_timespec(_delta)\
667 (struct timespec){ \
668  .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
669  .tv_nsec = (fr_time_delta_unwrap(_delta) % NSEC) \
670 }
671 /** @} */
672 
673 /** @name fr_time_delta_t scale conversion macros/functions
674  *
675  * @{
676  */
677 /** Return the current value of fr_time_monotonic_to_realtime.
678  *
679  */
680 static inline int64_t fr_time_offset_to_realtime(void)
681 {
683 }
684 
685 /** Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
686  *
687  */
689 {
690  int64_t out;
691 
693  return fr_time_unwrap(when) ? fr_unix_time_max() : fr_unix_time_min();
694  }
695  return fr_unix_time_wrap(out);
696 }
697 
698 /** Convert an fr_time_t (internal time) to number of usec since the unix epoch (wallclock time)
699  *
700  */
701 static inline int64_t fr_time_to_usec(fr_time_t when)
702 {
703  /* Divide each operand separately to avoid overflow on addition */
704  return (((fr_time_unwrap(when) / (NSEC / USEC)) +
706 }
707 
708 /** Convert an fr_time_t (internal time) to number of msec since the unix epoch (wallclock time)
709  *
710  */
711 static inline int64_t fr_time_to_msec(fr_time_t when)
712 {
713  /* Divide each operand separately to avoid overflow on addition */
714  return (((fr_time_unwrap(when) / (NSEC / MSEC)) +
716 }
717 
718 /** Convert an fr_time_t (internal time) to number of csec since the unix epoch (wallclock time)
719  *
720  */
721 static inline int64_t fr_time_to_csec(fr_time_t when)
722 {
723  /* Divide each operand separately to avoid overflow on addition */
724  return (((fr_time_unwrap(when) / (NSEC / CSEC)) +
726 }
727 
728 /** Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
729  *
730  */
731 static inline int64_t fr_time_to_sec(fr_time_t when)
732 {
733  /* Divide each operand separately to avoid overflow on addition */
734  return (((fr_time_unwrap(when) / NSEC) +
736 }
737 
738 /** Convert server epoch time to unix epoch time
739  *
740  * @param[in] _when The server epoch time to convert.
741  */
742 #define fr_time_to_timeval(_when) fr_time_delta_to_timeval(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
743 
744 /** Convert server epoch time to unix epoch time
745  *
746  * @param[in] _when The server epoch time to convert.
747  */
748 #define fr_time_to_timespec(_when) fr_time_delta_to_timespec(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
749 
750 /** Convert wallclock time to a fr_time_t (internal time)
751  *
752  * @param[out] overflow Whether the conversion overflowed.
753  * @param[in] when The timestamp to convert.
754  * @param[in] res The scale the integer value is in.
755  * @return
756  * - >0 number of nanoseconds since the server started.
757  * - 0 when the server started.
758  * - <0 number of nanoseconds before the server started.
759  */
760 static inline fr_time_t fr_time_from_integer(bool *overflow, int64_t when, fr_time_res_t res)
761 {
763 
764  if (!fr_multiply(&out, when, fr_time_multiplier_by_res[res])) {
765  if (overflow) *overflow = true;
766  return when > 0 ? fr_time_max() : fr_time_min();
767  }
768 
770  if (overflow) *overflow = true;
771  return when < 0 ? fr_time_max() : fr_time_min();
772  }
773 
774  if (overflow) *overflow = false;
775  return fr_time_wrap(out);
776 }
777 
778 /** Convert a nsec (wallclock time) to a fr_time_t (internal time)
779  *
780  * @param[in] when The timestamp to convert.
781  * @return
782  * - >0 number of nanoseconds since the server started.
783  * - 0 when the server started.
784  * - <0 number of nanoseconds before the server started.
785  */
786 static inline fr_time_t fr_time_from_nsec(int64_t when)
787 {
789 
791  return when > 0 ? fr_time_min() : fr_time_max();
792  }
793  return fr_time_wrap(out);
794 }
795 
796 /** Convert usec (wallclock time) to a fr_time_t (internal time)
797  *
798  * @param[in] when The timestamp to convert.
799  * @return
800  * - >0 number of nanoseconds since the server started.
801  * - 0 when the server started.
802  * - <0 number of nanoseconds before the server started.
803  */
804 static inline fr_time_t fr_time_from_usec(int64_t when)
805 {
807 
809  return when > 0 ? fr_time_min() : fr_time_max();
810  }
811  return fr_time_wrap(out);
812 }
813 
814 /** Convert msec (wallclock time) to a fr_time_t (internal time)
815  *
816  * @param[in] when The timestamp to convert.
817  * @return
818  * - >0 number of nanoseconds since the server started.
819  * - 0 when the server started.
820  * - <0 number of nanoseconds before the server started.
821  */
822 static inline fr_time_t fr_time_from_msec(int64_t when)
823 {
825 
827  return when > 0 ? fr_time_min() : fr_time_max();
828  }
829  return fr_time_wrap(out);
830 }
831 
832 /** Convert csec (wallclock time) to a fr_time_t (internal time)
833  *
834  * @param[in] when The timestamp to convert.
835  * @return
836  * - >0 number of nanoseconds since the server started.
837  * - 0 when the server started.
838  * - <0 number of nanoseconds before the server started.
839  */
840 static inline fr_time_t fr_time_from_csec(int64_t when)
841 {
843 
845  return when > 0 ? fr_time_min() : fr_time_max();
846  }
847  return fr_time_wrap(out);
848 }
849 
850 /** Convert a time_t (wallclock time) to a fr_time_t (internal time)
851  *
852  * @param[in] when The timestamp to convert.
853  * @return
854  * - >0 number of nanoseconds since the server started.
855  * - 0 when the server started.
856  * - <0 number of nanoseconds before the server started.
857  */
858 static inline fr_time_t fr_time_from_sec(time_t when)
859 {
861 
863  return when > 0 ? fr_time_min() : fr_time_max();
864  }
865  return fr_time_wrap(out);
866 }
867 
868 
869 
870 /** Convert a timespec (wallclock time) to a fr_time_t (internal time)
871  *
872  * @param[in] when_ts The timestamp to convert.
873  * @return
874  * - >0 number of nanoseconds since the server started.
875  * - 0 when the server started.
876  * - 0 if when_tv occurred before the server started.
877  */
878 static inline CC_HINT(nonnull) fr_time_t fr_time_from_timespec(struct timespec const *when_ts)
879 {
881 
882  if (!fr_sub(&out, tmp, fr_time_offset_to_realtime())) {
883  return tmp > 0 ? fr_time_min() : fr_time_max();
884  }
885  return fr_time_wrap(out);
886 }
887 
888 /** Convert a timeval (wallclock time) to a fr_time_t (internal time)
889  *
890  * @param[in] when_tv The timestamp to convert.
891  * @return
892  * - >0 number of nanoseconds since the server started.
893  * - 0 when the server started.
894  * - <0 number of nanoseconds before the server started.
895  */
896 static inline CC_HINT(nonnull) fr_time_t fr_time_from_timeval(struct timeval const *when_tv)
897 {
899 
900  if (!fr_sub(&out, tmp, fr_time_offset_to_realtime())) {
901  return tmp > 0 ? fr_time_min() : fr_time_max();
902  }
903  return fr_time_wrap(out);
904 }
905 /** @} */
906 
907 /** Compare two fr_time_t values
908  *
909  * @param[in] a The first value to compare.
910  * @param[in] b The second value to compare.
911  * @return
912  * - +1 if a > b
913  * - 0 if a == b
914  * - -1 if a < b
915  */
916 static inline int8_t fr_time_cmp(fr_time_t a, fr_time_t b)
917 {
918  return CMP(fr_time_unwrap(a), fr_time_unwrap(b));
919 }
920 
921 /** Compare two fr_time_delta_t values
922  *
923  * @param[in] a The first value to compare.
924  * @param[in] b The second value to compare.
925  * @return
926  * - +1 if a > b
927  * - 0 if a == b
928  * - -1 if a < b
929  */
931 {
933 }
934 
935 /** Compare two fr_unix_time_t values
936  *
937  * @param[in] a The first value to compare.
938  * @param[in] b The second value to compare.
939  * @return
940  * - +1 if a > b
941  * - 0 if a == b
942  * - -1 if a < b
943  */
945 {
947 }
948 
949 #ifndef CLOCK_MONOTONIC_RAW
950 #define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
951 #endif
952 
953 /** Return a relative time since the server fr_time_epoch
954  *
955  * This time is useful for doing time comparisons, deltas, etc.
956  * Human (i.e. printable) time is something else.
957  *
958  * @returns fr_time_t time in nanoseconds since the server fr_time_epoch.
959  *
960  * @hidecallergraph
961  */
962 static inline fr_time_t fr_time(void)
963 {
964  struct timespec ts;
965  (void) clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
967 }
968 
969 int fr_time_start(void);
970 int fr_time_sync(void);
971 
972 int64_t fr_time_scale(int64_t t, fr_time_res_t hint);
973 
974 int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta)
975  CC_HINT(nonnull);
976 
978  bool no_trailing, fr_sbuff_term_t const *tt)
979  CC_HINT(nonnull(1,2));
980 
982  CC_HINT(nonnull);
983 
985  CC_HINT(nonnull);
986 
987 size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt)
988  CC_HINT(format(strftime, 3, 0));
989 
990 size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt)
991  CC_HINT(format(strftime, 3, 0));
992 
994  CC_HINT(nonnull);
995 
996 void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs)
997  CC_HINT(nonnull(1,2));
998 
1000  CC_HINT(nonnull);
1001 
1002 int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
1003  CC_HINT(nonnull);
1004 
1006  CC_HINT(nonnull);
1007 
1009 
1010 bool fr_time_is_dst(void);
1011 
1012 #ifdef __cplusplus
1013 }
1014 #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:482
#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:821
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:57
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:840
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:341
static fr_unix_time_t fr_unix_time_from_msec(int64_t msec)
Definition: time.h:435
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:896
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:548
fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
Definition: time.c:661
#define MSEC
Definition: time.h:381
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:786
#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:575
static int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
Definition: time.h:627
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:822
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:731
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:308
static fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
Definition: time.h:423
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:711
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:930
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:511
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:760
#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:590
static int64_t fr_unix_time_to_csec(fr_unix_time_t delta)
Definition: time.h:501
#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:506
#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:1239
static fr_time_delta_t fr_time_delta_mul(fr_time_delta_t a, int64_t b)
Definition: time.h:273
#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:456
static int64_t fr_time_delta_to_csec(fr_time_delta_t delta)
Definition: time.h:642
#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:473
#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:701
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
Definition: time.h:647
_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:804
#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
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:632
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:878
static fr_unix_time_t fr_unix_time_from_csec(int64_t csec)
Definition: time.h:442
static fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
Definition: time.h:449
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:521
static fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
Definition: time.h:411
fr_time_delta_t fr_time_gmtoff(void)
Get the offset to gmt.
Definition: time.c:1231
#define NSEC
Definition: time.h:379
static int64_t fr_unix_time_to_usec(fr_unix_time_t delta)
Definition: time.h:491
#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:944
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:858
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:302
#define CLOCK_MONOTONIC_RAW
Definition: time.h:950
#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:563
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:486
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:597
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:582
static int64_t fr_unix_time_to_msec(fr_unix_time_t delta)
Definition: time.h:496
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:962
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:536
static bool fr_time_op_ispos(bool a, bool op, bool b)
Definition: time.h:119
#define USEC
Definition: time.h:380
static int64_t fr_time_offset_to_realtime(void)
Return the current value of fr_time_monotonic_to_realtime.
Definition: time.h:680
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:721
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:688
static fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
Definition: time.h:568
struct fr_time_delta_s fr_time_delta_t
A time delta, a difference in time measured in nanoseconds.
#define CSEC
Definition: time.h:382
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:614
static fr_time_delta_t fr_unix_time_sub_time_time(fr_unix_time_t a, fr_unix_time_t b)
Definition: time.h:335
#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:516
static int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
Definition: time.h:637
fr_slen_t fr_unix_time_to_str(fr_sbuff_t *out, fr_unix_time_t time, fr_time_res_t res, bool utc)
Convert unix time to string.
Definition: time.c:1154
static int8_t fr_time_cmp(fr_time_t a, fr_time_t b)
Compare two fr_time_t values.
Definition: time.h:916
static fr_unix_time_t fr_unix_time_from_usec(int64_t usec)
Definition: time.h:428
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:997
int nonnull(2, 5))
int format(printf, 5, 0))
static size_t char ** out
Definition: value.h:997