The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
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: 884d5c21932d3c68a7283c734d6c8b40d09948a6 $
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 */
27RCSIDH(time_h, "$Id: 884d5c21932d3c68a7283c734d6c8b40d09948a6 $")
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
43extern "C" {
44#endif
45
46/** The base resolution for print parse operations
47 */
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 */
69typedef 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 */
80typedef 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 */
95typedef 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
112extern "C" {
113#endif
114
115extern int64_t const fr_time_multiplier_by_res[];
117extern size_t fr_time_precision_table_len;
118
119static 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) \
131fr_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) }
146static 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 */
154static 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) }
161static 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 */
179
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
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 */
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 */
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
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
375typedef 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 */
400extern 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 */
411static 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
423static inline fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
424{
425 return fr_unix_time_wrap(nsec);
426}
427
428static 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
435static 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
442static 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
449static 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
456static 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
473static 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
486static inline int64_t fr_unix_time_to_integer(fr_unix_time_t delta, fr_time_res_t res)
487{
489}
490
491static 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
496static 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
501static 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
506static 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/** Seconds since the epoch as a double, for printing and for arithmetic which need not be exact
512 */
514{
515 uint64_t nsec = fr_unix_time_unwrap(when);
516
517 return (double) nsec / (double) NSEC;
518}
519
520static inline int64_t fr_unix_time_to_min(fr_unix_time_t delta)
521{
522 return (fr_unix_time_unwrap(delta) / NSEC) / 60;
523}
524
525static inline int64_t fr_unix_time_to_hour(fr_unix_time_t delta)
526{
527 return (fr_unix_time_unwrap(delta) / NSEC) / 3600;
528}
529
530static inline int64_t fr_unix_time_to_day(fr_unix_time_t delta)
531{
532 return (fr_unix_time_unwrap(delta) / NSEC) / 86400;
533}
534
535/** Convert a time_t into out internal fr_unix_time_t
536 *
537 * Our internal unix time representation is unsigned and in nanoseconds which
538 * is different from time_t which is signed and has seconds resolution.
539 *
540 * If time is negative we return 0.
541 *
542 * @param[in] time to convert.
543 * @return Unix time in seconds.
544 */
545static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_time(time_t time)
546{
547 if (time < 0) return fr_unix_time_min();
548
549 return fr_unix_time_wrap(time * NSEC);
550}
551/** @} */
552
553/** @name fr_time_delta_t scale conversion macros/functions
554 *
555 * @{
556 */
557static inline fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
558{
559 int64_t out;
560 if (res == FR_TIME_RES_INVALID) {
561 if (overflow) *overflow = true;
562 return fr_time_delta_max();
563 }
564 if (!fr_multiply(&out, integer, fr_time_multiplier_by_res[res])) {
565 if (overflow) *overflow = true;
566 return fr_time_delta_wrap(integer > 0 ? INT64_MAX: INT64_MIN);
567 }
568 if (overflow) *overflow = false;
569 return fr_time_delta_wrap(out);
570}
571
572static inline fr_time_delta_t fr_time_delta_from_nsec(int64_t nsec)
573{
574 return fr_time_delta_wrap(nsec);
575}
576
577static inline fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
578{
579 int64_t out;
580 if (!fr_multiply(&out, usec, (NSEC / USEC))) return (usec > 0) ? fr_time_delta_max() : fr_time_delta_min();
581 return fr_time_delta_wrap(out);
582}
583
584static inline fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
585{
586 int64_t out;
587 if (!fr_multiply(&out, msec, (NSEC / MSEC))) return (msec > 0) ? fr_time_delta_max() : fr_time_delta_min();
588 return fr_time_delta_wrap(out);
589}
590
591static inline fr_time_delta_t fr_time_delta_from_csec(int64_t csec)
592{
593 int64_t out;
594 if (!fr_multiply(&out, csec, (NSEC / CSEC))) return (csec > 0) ? fr_time_delta_max() : fr_time_delta_min();
595 return fr_time_delta_wrap(out);
596}
597
598/** @hidecallergraph */
599static inline fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
600{
601 int64_t out;
602 if (!fr_multiply(&out, sec, NSEC)) return (sec > 0) ? fr_time_delta_max() : fr_time_delta_min();
603 return fr_time_delta_wrap(out);
604}
605
606static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv)
607{
608 typeof_field(fr_time_delta_t, value) integer, fraction, out;
609
610 if (!fr_multiply(&integer, (typeof_field(fr_time_delta_t, value)) tv->tv_sec, NSEC)) {
611 overflow:
612 return fr_time_delta_max();
613 }
614
615 if (!fr_multiply(&fraction,
616 (typeof_field(fr_time_delta_t, value)) tv->tv_usec, (NSEC / USEC))) goto overflow;
617
618 if (!fr_add(&out, integer, fraction)) goto overflow;
619
620 return fr_time_delta_wrap(out);
621}
622
623static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
624{
626
627 if (!fr_multiply(&integer, (typeof_field(fr_time_delta_t, value)) ts->tv_sec, NSEC)) {
628 overflow:
629 return fr_time_delta_max();
630 }
631 if (!fr_add(&out, integer, ts->tv_nsec)) goto overflow;
632
633 return fr_time_delta_wrap(out);
634}
635
637{
639}
640
641static inline int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
642{
643 return fr_time_delta_unwrap(delta) / (NSEC / USEC);
644}
645
646static inline int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
647{
648 return fr_time_delta_unwrap(delta) / (NSEC / MSEC);
649}
650
651static inline int64_t fr_time_delta_to_csec(fr_time_delta_t delta)
652{
653 return fr_time_delta_unwrap(delta) / (NSEC / CSEC);
654}
655
656static inline int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
657{
658 return (fr_time_delta_unwrap(delta) / NSEC);
659}
660
661/** Seconds as a double, for printing and for arithmetic which need not be exact
662 */
664{
665 int64_t nsec = fr_time_delta_unwrap(delta);
666
667 return (double) nsec / (double) NSEC;
668}
669
670/** Convert a delta to a timeval
671 *
672 * @param[in] _delta in nanoseconds.
673 */
674#define fr_time_delta_to_timeval(_delta) \
675(struct timeval){ \
676 .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
677 .tv_usec = (fr_time_delta_unwrap(_delta) % NSEC) / (NSEC / USEC) \
678}
679
680/** Convert a delta to a timespec
681 *
682 * @param[in] _delta in nanoseconds.
683 */
684#define fr_time_delta_to_timespec(_delta)\
685(struct timespec){ \
686 .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
687 .tv_nsec = (fr_time_delta_unwrap(_delta) % NSEC) \
688}
689/** @} */
690
691/** @name fr_time_delta_t scale conversion macros/functions
692 *
693 * @{
694 */
695/** Return the current value of fr_time_monotonic_to_realtime.
696 *
697 */
702
703/** Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
704 *
705 */
707{
708 int64_t out;
709
712 }
713 return fr_unix_time_wrap(out);
714}
715
716/** Convert an fr_time_t (internal time) to number of usec since the unix epoch (wallclock time)
717 *
718 */
719static inline int64_t fr_time_to_usec(fr_time_t when)
720{
721 /* Divide each operand separately to avoid overflow on addition */
722 return (((fr_time_unwrap(when) / (NSEC / USEC)) +
724}
725
726/** Convert an fr_time_t (internal time) to number of msec since the unix epoch (wallclock time)
727 *
728 */
729static inline int64_t fr_time_to_msec(fr_time_t when)
730{
731 /* Divide each operand separately to avoid overflow on addition */
732 return (((fr_time_unwrap(when) / (NSEC / MSEC)) +
734}
735
736/** Convert an fr_time_t (internal time) to number of csec since the unix epoch (wallclock time)
737 *
738 */
739static inline int64_t fr_time_to_csec(fr_time_t when)
740{
741 /* Divide each operand separately to avoid overflow on addition */
742 return (((fr_time_unwrap(when) / (NSEC / CSEC)) +
744}
745
746/** Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
747 *
748 */
749static inline int64_t fr_time_to_sec(fr_time_t when)
750{
751 /* Divide each operand separately to avoid overflow on addition */
752 return (((fr_time_unwrap(when) / NSEC) +
754}
755
756/** Convert server epoch time to unix epoch time
757 *
758 * @param[in] _when The server epoch time to convert.
759 */
760#define fr_time_to_timeval(_when) fr_time_delta_to_timeval(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
761
762/** Convert server epoch time to unix epoch time
763 *
764 * @param[in] _when The server epoch time to convert.
765 */
766#define fr_time_to_timespec(_when) fr_time_delta_to_timespec(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
767
768/** Convert wallclock time to a fr_time_t (internal time)
769 *
770 * @param[out] overflow Whether the conversion overflowed.
771 * @param[in] when The timestamp to convert.
772 * @param[in] res The scale the integer value is in.
773 * @return
774 * - >0 number of nanoseconds since the server started.
775 * - 0 when the server started.
776 * - <0 number of nanoseconds before the server started.
777 */
778static inline fr_time_t fr_time_from_integer(bool *overflow, int64_t when, fr_time_res_t res)
779{
781
782 if (!fr_multiply(&out, when, fr_time_multiplier_by_res[res])) {
783 if (overflow) *overflow = true;
784 return when > 0 ? fr_time_max() : fr_time_min();
785 }
786
788 if (overflow) *overflow = true;
789 return when < 0 ? fr_time_max() : fr_time_min();
790 }
791
792 if (overflow) *overflow = false;
793 return fr_time_wrap(out);
794}
795
796/** Convert a nsec (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 */
804static inline fr_time_t fr_time_from_nsec(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 usec (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 */
822static inline fr_time_t fr_time_from_usec(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 msec (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 */
840static inline fr_time_t fr_time_from_msec(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 csec (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 */
858static inline fr_time_t fr_time_from_csec(int64_t when)
859{
861
863 return when > 0 ? fr_time_min() : fr_time_max();
864 }
865 return fr_time_wrap(out);
866}
867
868/** Convert a time_t (wallclock time) to a fr_time_t (internal time)
869 *
870 * @param[in] when The timestamp to convert.
871 * @return
872 * - >0 number of nanoseconds since the server started.
873 * - 0 when the server started.
874 * - <0 number of nanoseconds before the server started.
875 */
876static inline fr_time_t fr_time_from_sec(time_t when)
877{
879
881 return when > 0 ? fr_time_min() : fr_time_max();
882 }
883 return fr_time_wrap(out);
884}
885
886
887
888/** Convert a timespec (wallclock time) to a fr_time_t (internal time)
889 *
890 * @param[in] when_ts The timestamp to convert.
891 * @return
892 * - >0 number of nanoseconds since the server started.
893 * - 0 when the server started.
894 * - 0 if when_tv occurred before the server started.
895 */
896static inline CC_HINT(nonnull) fr_time_t fr_time_from_timespec(struct timespec const *when_ts)
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/** Convert a timeval (wallclock time) to a fr_time_t (internal time)
907 *
908 * @param[in] when_tv The timestamp to convert.
909 * @return
910 * - >0 number of nanoseconds since the server started.
911 * - 0 when the server started.
912 * - <0 number of nanoseconds before the server started.
913 */
914static inline CC_HINT(nonnull) fr_time_t fr_time_from_timeval(struct timeval const *when_tv)
915{
917
918 if (!fr_sub(&out, tmp, fr_time_offset_to_realtime())) {
919 return tmp > 0 ? fr_time_min() : fr_time_max();
920 }
921 return fr_time_wrap(out);
922}
923/** @} */
924
925/** Compare two fr_time_t values
926 *
927 * @param[in] a The first value to compare.
928 * @param[in] b The second value to compare.
929 * @return
930 * - +1 if a > b
931 * - 0 if a == b
932 * - -1 if a < b
933 */
935{
936 return CMP(fr_time_unwrap(a), fr_time_unwrap(b));
937}
938
939/** Compare two fr_time_delta_t values
940 *
941 * @param[in] a The first value to compare.
942 * @param[in] b The second value to compare.
943 * @return
944 * - +1 if a > b
945 * - 0 if a == b
946 * - -1 if a < b
947 */
952
953/** Compare two fr_unix_time_t values
954 *
955 * @param[in] a The first value to compare.
956 * @param[in] b The second value to compare.
957 * @return
958 * - +1 if a > b
959 * - 0 if a == b
960 * - -1 if a < b
961 */
966
967#ifndef CLOCK_MONOTONIC_RAW
968#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
969#endif
970
971/** Return a relative time since the server fr_time_epoch
972 *
973 * This time is useful for doing time comparisons, deltas, etc.
974 * Human (i.e. printable) time is something else.
975 *
976 * @returns fr_time_t time in nanoseconds since the server fr_time_epoch.
977 *
978 * @hidecallergraph
979 */
980static inline fr_time_t fr_time(void)
981{
982 struct timespec ts;
983 (void) clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
985}
986
987int fr_time_start(void);
988int fr_time_sync(void);
989
990int64_t fr_time_scale(int64_t t, fr_time_res_t hint);
991
992int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta)
993 CC_HINT(nonnull);
994
996 bool no_trailing, fr_sbuff_term_t const *tt)
997 CC_HINT(nonnull(1,2));
998
999fr_slen_t fr_time_delta_from_str(fr_time_delta_t *out, char const *in, size_t inlen, fr_time_res_t hint)
1000 CC_HINT(nonnull);
1001
1003 CC_HINT(nonnull);
1004
1005size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt)
1006 CC_HINT(format(strftime, 3, 0));
1007
1008size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt)
1009 CC_HINT(format(strftime, 3, 0));
1010
1012 CC_HINT(nonnull);
1013
1014void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs)
1015 CC_HINT(nonnull(1,2));
1016
1018 CC_HINT(nonnull);
1019
1020int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
1021 CC_HINT(nonnull);
1022
1024 CC_HINT(nonnull);
1025
1027
1028bool fr_time_is_dst(void);
1029
1030#ifdef __cplusplus
1031}
1032#endif
static int const char * fmt
Definition acutest.h:638
static uint8_t overflow[100]
#define typeof_field(_type, _field)
Typeof field.
Definition build.h:210
#define RCSIDH(h, id)
Definition build.h:604
#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:130
fr_cmp_ret_t
Result of an ordering comparison.
Definition build.h:113
static const char * tabs
Definition command.c:1589
Test enumeration values.
Definition dict_test.h:92
#define fr_sub(_out, _a, _b)
Subtracts two integers.
Definition math.h:201
#define fr_add(_out, _a, _b)
Adds two integers.
Definition math.h:190
#define fr_multiply(_out, _a, _b)
Multiplies two integers together.
Definition math.h:179
ssize_t fr_slen_t
Set of terminal elements.
@ 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:858
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:221
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:914
void fr_time_elapsed_update(fr_time_elapsed_t *elapsed, fr_time_t start, fr_time_t end)
Definition time.c:581
static fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
Definition time.h:557
fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
Definition time.c:662
#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:804
#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:584
static int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
Definition time.h:636
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:840
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:749
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:109
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:729
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:520
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:778
#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:599
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
static fr_cmp_ret_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:962
#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:183
#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:430
static double fr_unix_time_to_sec_double(fr_unix_time_t when)
Seconds since the epoch as a double, for printing and for arithmetic which need not be exact.
Definition time.h:513
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:1248
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:651
#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:719
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
Definition time.h:656
_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:828
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:822
#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:717
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
static int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
Definition time.h:641
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:896
static double fr_time_delta_to_sec_double(fr_time_delta_t delta)
Seconds as a double, for printing and for arithmetic which need not be exact.
Definition time.h:663
static fr_unix_time_t fr_unix_time_from_csec(int64_t csec)
Definition time.h:442
static fr_cmp_ret_t fr_time_cmp(fr_time_t a, fr_time_t b)
Compare two fr_time_t values.
Definition time.h:934
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:566
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
#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:530
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:1240
#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
void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs))
Definition time.c:626
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:876
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
static fr_cmp_ret_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:948
#define CLOCK_MONOTONIC_RAW
Definition time.h:968
#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:572
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:458
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:606
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:537
static fr_time_delta_t fr_time_delta_from_csec(int64_t csec)
Definition time.h:591
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:980
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:545
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:698
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:739
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:706
static fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
Definition time.h:577
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:157
static fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
Definition time.h:623
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:525
static int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
Definition time.h:646
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:1163
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 fr_sbuff_err_t char size_t fr_sbuff_t * in
Definition value.h:1061
static fr_sbuff_err_t char ** out
Definition value.h:1061
int nonnull(2, 5))
int format(printf, 5, 0))