diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /shared/nm-glib-aux/nm-time-utils.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'shared/nm-glib-aux/nm-time-utils.c')
| -rw-r--r-- | shared/nm-glib-aux/nm-time-utils.c | 328 |
1 files changed, 162 insertions, 166 deletions
diff --git a/shared/nm-glib-aux/nm-time-utils.c b/shared/nm-glib-aux/nm-time-utils.c index 356ed1a5..511363c3 100644 --- a/shared/nm-glib-aux/nm-time-utils.c +++ b/shared/nm-glib-aux/nm-time-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2018 Red Hat, Inc. */ @@ -12,97 +12,94 @@ /*****************************************************************************/ typedef struct { - /* the offset to the native clock, in seconds. */ - gint64 offset_sec; - clockid_t clk_id; + /* the offset to the native clock, in seconds. */ + gint64 offset_sec; + clockid_t clk_id; } GlobalState; static const GlobalState *volatile p_global_state; static const GlobalState * -_t_init_global_state (void) +_t_init_global_state(void) { - static GlobalState global_state = { }; - static gsize init_once = 0; - const GlobalState *p; - clockid_t clk_id; - struct timespec tp; - gint64 offset_sec; - int r; - - clk_id = CLOCK_BOOTTIME; - r = clock_gettime (clk_id, &tp); - if (r == -1 && errno == EINVAL) { - clk_id = CLOCK_MONOTONIC; - r = clock_gettime (clk_id, &tp); - } - - /* The only failure we tolerate is that CLOCK_BOOTTIME is not supported. - * Other than that, we rely on kernel to not fail on this. */ - g_assert (r == 0); - g_assert (tp.tv_nsec >= 0 && tp.tv_nsec < NM_UTILS_NSEC_PER_SEC); - - /* Calculate an offset for the time stamp. - * - * We always want positive values, because then we can initialize - * a timestamp with 0 and be sure, that it will be less then any - * value nm_utils_get_monotonic_timestamp_*() might return. - * For this to be true also for nm_utils_get_monotonic_timestamp_sec() at - * early boot, we have to shift the timestamp to start counting at - * least from 1 second onward. - * - * Another advantage of shifting is, that this way we make use of the whole 31 bit - * range of signed int, before the time stamp for nm_utils_get_monotonic_timestamp_sec() - * wraps (~68 years). - **/ - offset_sec = (- ((gint64) tp.tv_sec)) + 1; - - if (!g_once_init_enter (&init_once)) { - /* there was a race. We expect the pointer to be fully initialized now. */ - p = g_atomic_pointer_get (&p_global_state); - g_assert (p); - return p; - } - - global_state.offset_sec = offset_sec; - global_state.clk_id = clk_id; - p = &global_state; - g_atomic_pointer_set (&p_global_state, p); - g_once_init_leave (&init_once, 1); - - _nm_utils_monotonic_timestamp_initialized (&tp, - p->offset_sec, - p->clk_id == CLOCK_BOOTTIME); - - return p; + static GlobalState global_state = {}; + static gsize init_once = 0; + const GlobalState *p; + clockid_t clk_id; + struct timespec tp; + gint64 offset_sec; + int r; + + clk_id = CLOCK_BOOTTIME; + r = clock_gettime(clk_id, &tp); + if (r == -1 && errno == EINVAL) { + clk_id = CLOCK_MONOTONIC; + r = clock_gettime(clk_id, &tp); + } + + /* The only failure we tolerate is that CLOCK_BOOTTIME is not supported. + * Other than that, we rely on kernel to not fail on this. */ + g_assert(r == 0); + g_assert(tp.tv_nsec >= 0 && tp.tv_nsec < NM_UTILS_NSEC_PER_SEC); + + /* Calculate an offset for the time stamp. + * + * We always want positive values, because then we can initialize + * a timestamp with 0 and be sure, that it will be less then any + * value nm_utils_get_monotonic_timestamp_*() might return. + * For this to be true also for nm_utils_get_monotonic_timestamp_sec() at + * early boot, we have to shift the timestamp to start counting at + * least from 1 second onward. + * + * Another advantage of shifting is, that this way we make use of the whole 31 bit + * range of signed int, before the time stamp for nm_utils_get_monotonic_timestamp_sec() + * wraps (~68 years). + **/ + offset_sec = (-((gint64) tp.tv_sec)) + 1; + + if (!g_once_init_enter(&init_once)) { + /* there was a race. We expect the pointer to be fully initialized now. */ + p = g_atomic_pointer_get(&p_global_state); + g_assert(p); + return p; + } + + global_state.offset_sec = offset_sec; + global_state.clk_id = clk_id; + p = &global_state; + g_atomic_pointer_set(&p_global_state, p); + g_once_init_leave(&init_once, 1); + + _nm_utils_monotonic_timestamp_initialized(&tp, p->offset_sec, p->clk_id == CLOCK_BOOTTIME); + + return p; } -#define _t_get_global_state() \ - ({ \ - const GlobalState *_p; \ - \ - _p = g_atomic_pointer_get (&p_global_state); \ - (G_LIKELY (_p) ? _p : _t_init_global_state ()); \ - }) - -#define _t_clock_gettime_eval(p, tp) \ - ({ \ - struct timespec *const _tp = (tp); \ - const GlobalState *const _p2 = (p); \ - int _r; \ - \ - nm_assert (_tp); \ - \ - _r = clock_gettime (_p2->clk_id, _tp); \ - \ - nm_assert (_r == 0); \ - nm_assert (_tp->tv_nsec >= 0 && _tp->tv_nsec < NM_UTILS_NSEC_PER_SEC); \ - \ - _p2; \ - }) - -#define _t_clock_gettime(tp) \ - _t_clock_gettime_eval (_t_get_global_state (), tp); +#define _t_get_global_state() \ + ({ \ + const GlobalState *_p; \ + \ + _p = g_atomic_pointer_get(&p_global_state); \ + (G_LIKELY(_p) ? _p : _t_init_global_state()); \ + }) + +#define _t_clock_gettime_eval(p, tp) \ + ({ \ + struct timespec *const _tp = (tp); \ + const GlobalState *const _p2 = (p); \ + int _r; \ + \ + nm_assert(_tp); \ + \ + _r = clock_gettime(_p2->clk_id, _tp); \ + \ + nm_assert(_r == 0); \ + nm_assert(_tp->tv_nsec >= 0 && _tp->tv_nsec < NM_UTILS_NSEC_PER_SEC); \ + \ + _p2; \ + }) + +#define _t_clock_gettime(tp) _t_clock_gettime_eval(_t_get_global_state(), tp); /*****************************************************************************/ @@ -119,19 +116,18 @@ _t_init_global_state (void) * timestamp but in different scales (nsec, usec, msec, sec). **/ gint64 -nm_utils_get_monotonic_timestamp_nsec (void) +nm_utils_get_monotonic_timestamp_nsec(void) { - const GlobalState *p; - struct timespec tp; + const GlobalState *p; + struct timespec tp; - p = _t_clock_gettime (&tp); + p = _t_clock_gettime(&tp); - /* Although the result will always be positive, we return a signed - * integer, which makes it easier to calculate time differences (when - * you want to subtract signed values). - **/ - return (((gint64) tp.tv_sec) + p->offset_sec) * NM_UTILS_NSEC_PER_SEC + - tp.tv_nsec; + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * NM_UTILS_NSEC_PER_SEC + tp.tv_nsec; } /** @@ -147,19 +143,19 @@ nm_utils_get_monotonic_timestamp_nsec (void) * timestamp but in different scales (nsec, usec, msec, sec). **/ gint64 -nm_utils_get_monotonic_timestamp_usec (void) +nm_utils_get_monotonic_timestamp_usec(void) { - const GlobalState *p; - struct timespec tp; + const GlobalState *p; + struct timespec tp; - p = _t_clock_gettime (&tp); + p = _t_clock_gettime(&tp); - /* Although the result will always be positive, we return a signed - * integer, which makes it easier to calculate time differences (when - * you want to subtract signed values). - **/ - return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) G_USEC_PER_SEC) + - (tp.tv_nsec / (NM_UTILS_NSEC_PER_SEC/G_USEC_PER_SEC)); + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) G_USEC_PER_SEC) + + (tp.tv_nsec / (NM_UTILS_NSEC_PER_SEC / G_USEC_PER_SEC)); } /** @@ -175,19 +171,19 @@ nm_utils_get_monotonic_timestamp_usec (void) * timestamp but in different scales (nsec, usec, msec, sec). **/ gint64 -nm_utils_get_monotonic_timestamp_msec (void) +nm_utils_get_monotonic_timestamp_msec(void) { - const GlobalState *p; - struct timespec tp; + const GlobalState *p; + struct timespec tp; - p = _t_clock_gettime (&tp); + p = _t_clock_gettime(&tp); - /* Although the result will always be positive, we return a signed - * integer, which makes it easier to calculate time differences (when - * you want to subtract signed values). - **/ - return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) 1000) + - (tp.tv_nsec / (NM_UTILS_NSEC_PER_SEC/1000)); + /* Although the result will always be positive, we return a signed + * integer, which makes it easier to calculate time differences (when + * you want to subtract signed values). + **/ + return (((gint64) tp.tv_sec) + p->offset_sec) * ((gint64) 1000) + + (tp.tv_nsec / (NM_UTILS_NSEC_PER_SEC / 1000)); } /** @@ -203,14 +199,14 @@ nm_utils_get_monotonic_timestamp_msec (void) * timestamp but in different scales (nsec, usec, msec, sec). **/ gint32 -nm_utils_get_monotonic_timestamp_sec (void) +nm_utils_get_monotonic_timestamp_sec(void) { - const GlobalState *p; - struct timespec tp; + const GlobalState *p; + struct timespec tp; - p = _t_clock_gettime (&tp); + p = _t_clock_gettime(&tp); - return (((gint64) tp.tv_sec) + p->offset_sec); + return (((gint64) tp.tv_sec) + p->offset_sec); } /** @@ -234,35 +230,35 @@ nm_utils_get_monotonic_timestamp_sec (void) * On older kernels that don't support CLOCK_BOOTTIME, the returned time is instead CLOCK_MONOTONIC. **/ gint64 -nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timestamp_nsec_per_tick) +nm_utils_monotonic_timestamp_as_boottime(gint64 timestamp, gint64 timestamp_nsec_per_tick) { - const GlobalState *p; - gint64 offset; + const GlobalState *p; + gint64 offset; - /* only support nsec-per-tick being a multiple of 10. */ - g_return_val_if_fail ( timestamp_nsec_per_tick == 1 - || (timestamp_nsec_per_tick > 0 && - timestamp_nsec_per_tick <= NM_UTILS_NSEC_PER_SEC && - timestamp_nsec_per_tick % 10 == 0), - -1); + /* only support nsec-per-tick being a multiple of 10. */ + g_return_val_if_fail(timestamp_nsec_per_tick == 1 + || (timestamp_nsec_per_tick > 0 + && timestamp_nsec_per_tick <= NM_UTILS_NSEC_PER_SEC + && timestamp_nsec_per_tick % 10 == 0), + -1); - /* if the caller didn't yet ever fetch a monotonic-timestamp, he cannot pass any meaningful - * value (because he has no idea what these timestamps would be). That would be a bug. */ - nm_assert (g_atomic_pointer_get (&p_global_state)); + /* if the caller didn't yet ever fetch a monotonic-timestamp, he cannot pass any meaningful + * value (because he has no idea what these timestamps would be). That would be a bug. */ + nm_assert(g_atomic_pointer_get(&p_global_state)); - p = _t_get_global_state (); + p = _t_get_global_state(); - nm_assert (p->offset_sec <= 0); + nm_assert(p->offset_sec <= 0); - /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ - offset = p->offset_sec * (NM_UTILS_NSEC_PER_SEC / timestamp_nsec_per_tick); + /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ + offset = p->offset_sec * (NM_UTILS_NSEC_PER_SEC / timestamp_nsec_per_tick); - nm_assert (offset <= 0 && offset > G_MININT64); + nm_assert(offset <= 0 && offset > G_MININT64); - /* check for overflow (note that offset is non-positive). */ - g_return_val_if_fail (timestamp < G_MAXINT64 + offset, G_MAXINT64); + /* check for overflow (note that offset is non-positive). */ + g_return_val_if_fail(timestamp < G_MAXINT64 + offset, G_MAXINT64); - return timestamp - offset; + return timestamp - offset; } /** @@ -284,49 +280,49 @@ nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timestamp_nse * This is the inverse of nm_utils_monotonic_timestamp_as_boottime(). */ gint64 -nm_utils_monotonic_timestamp_from_boottime (guint64 boottime, gint64 timestamp_nsec_per_tick) +nm_utils_monotonic_timestamp_from_boottime(guint64 boottime, gint64 timestamp_nsec_per_tick) { - const GlobalState *p; - gint64 offset; + const GlobalState *p; + gint64 offset; - /* only support nsec-per-tick being a multiple of 10. */ - g_return_val_if_fail ( timestamp_nsec_per_tick == 1 - || (timestamp_nsec_per_tick > 0 && - timestamp_nsec_per_tick <= NM_UTILS_NSEC_PER_SEC && - timestamp_nsec_per_tick % 10 == 0), - -1); + /* only support nsec-per-tick being a multiple of 10. */ + g_return_val_if_fail(timestamp_nsec_per_tick == 1 + || (timestamp_nsec_per_tick > 0 + && timestamp_nsec_per_tick <= NM_UTILS_NSEC_PER_SEC + && timestamp_nsec_per_tick % 10 == 0), + -1); - p = _t_get_global_state (); + p = _t_get_global_state(); - nm_assert (p->offset_sec <= 0); + nm_assert(p->offset_sec <= 0); - /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ - offset = p->offset_sec * (NM_UTILS_NSEC_PER_SEC / timestamp_nsec_per_tick); + /* calculate the offset of monotonic-timestamp to boottime. offset_s is <= 1. */ + offset = p->offset_sec * (NM_UTILS_NSEC_PER_SEC / timestamp_nsec_per_tick); - nm_assert (offset <= 0 && offset > G_MININT64); + nm_assert(offset <= 0 && offset > G_MININT64); - /* check for overflow (note that offset is non-positive). */ - g_return_val_if_fail (boottime < G_MAXINT64, G_MAXINT64); + /* check for overflow (note that offset is non-positive). */ + g_return_val_if_fail(boottime < G_MAXINT64, G_MAXINT64); - return (gint64) boottime + offset; + return (gint64) boottime + offset; } gint64 -nm_utils_clock_gettime_nsec (clockid_t clockid) +nm_utils_clock_gettime_nsec(clockid_t clockid) { - struct timespec tp; + struct timespec tp; - if (clock_gettime (clockid, &tp) != 0) - return -NM_ERRNO_NATIVE (errno); - return nm_utils_timespec_to_nsec (&tp); + if (clock_gettime(clockid, &tp) != 0) + return -NM_ERRNO_NATIVE(errno); + return nm_utils_timespec_to_nsec(&tp); } gint64 -nm_utils_clock_gettime_msec (clockid_t clockid) +nm_utils_clock_gettime_msec(clockid_t clockid) { - struct timespec tp; + struct timespec tp; - if (clock_gettime (clockid, &tp) != 0) - return -NM_ERRNO_NATIVE (errno); - return nm_utils_timespec_to_msec (&tp); + if (clock_gettime(clockid, &tp) != 0) + return -NM_ERRNO_NATIVE(errno); + return nm_utils_timespec_to_msec(&tp); } |