This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Max gerrit-no-reply at lists.osmocom.orgHello Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/5103 to look at the new patch set (#5). Add function to estimate elapsed time * add function which uses monotonic clock for proper time estimation * add corresponding tests Change-Id: I83d865ff633a7ebda2c943477205fd31aceda277 Related: OS#2586 --- M TODO-RELEASE M include/osmocom/core/timer.h M src/timer.c M tests/timer/timer_test.c M tests/timer/timer_test.ok 5 files changed, 168 insertions(+), 8 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/03/5103/5 diff --git a/TODO-RELEASE b/TODO-RELEASE index a5def79..82b2e34 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -9,3 +9,4 @@ #library what description / commit summary line core msgb_queue_free() add inline func to msgb.h coding gsm0503_rach_ext-encode() add func to gsm0503_coding.h +core osmo_time_elapsed() add function to estimate elapsed time diff --git a/include/osmocom/core/timer.h b/include/osmocom/core/timer.h index 4958efb..221709b 100644 --- a/include/osmocom/core/timer.h +++ b/include/osmocom/core/timer.h @@ -50,6 +50,31 @@ #define OSMO_SEC2HRS(sec) ((sec % (60 * 60 * 24)) / (60 * 60)) #define OSMO_SEC2DAY(sec) ((sec % (60 * 60 * 24 * 365)) / (60 * 60 * 24)) /* we ignore leap year for simplicity */ +#define OSMO_SEC2US(sec) (sec * 1000000) +#define OSMO_SEC2MS(sec) (sec * 1000) +#define OSMO_SEC2CS(sec) (sec * 100) + +#define OSMO_US2SEC(us) (us / 1000000) +#define OSMO_MS2SEC(ms) (ms / 1000) +#define OSMO_CS2SEC(cs) (cs / 100) + +#define OSMO_USEC2MS(us) (us / 1000) +#define OSMO_USEC2NS(us) (us * 1000) + +#define OSMO_NSEC2US(ns) (ns / 1000) +#define OSMO_NSEC2MS(ns) (ns / 1000000) +#define OSMO_NSEC2CS(ns) (ns / 10000000) + +/* how much time elapses between checks, in microsecs */ +#define OSMO_TIME_TEST_MAGIC 423210 + +enum osmo_elapsed { + T_SECS, + T_MILLIS, + T_CENTIS, + T_TEST +}; + /*! A structure representing a single instance of a timer */ struct osmo_timer_list { struct rb_node node; /*!< rb-tree node header */ @@ -61,6 +86,8 @@ void *data; /*!< user data for callback */ }; +time_t osmo_time_elapsed(const struct timespec *from, enum osmo_elapsed kind); + /* * timer management */ diff --git a/src/timer.c b/src/timer.c index 02160a1..75307c2 100644 --- a/src/timer.c +++ b/src/timer.c @@ -25,6 +25,7 @@ * */ +#include "config.h" /*! \addtogroup timer * @{ @@ -35,6 +36,10 @@ #include <assert.h> #include <string.h> #include <limits.h> +#include <errno.h> +#include <time.h> + +#include <osmocom/core/logging.h> #include <osmocom/core/timer.h> #include <osmocom/core/timer_compat.h> #include <osmocom/core/linuxlist.h> @@ -168,6 +173,62 @@ return 0; } +#if !defined(EMBEDDED) + +/* isolated nanoseconds clock difference */ +static inline long t_diff_nsec(const struct timespec *from, const struct timespec *to) +{ + return (from->tv_nsec > to->tv_nsec) ? (from->tv_nsec - to->tv_nsec) : (to->tv_nsec - from->tv_nsec); +} + +/* isolated seconds clock difference */ +static inline time_t t_diff_sec(const struct timespec *from, const struct timespec *to) +{ + return (from->tv_sec > to->tv_sec) ? difftime(from->tv_sec, to->tv_sec) : difftime(to->tv_sec, from->tv_sec); +} + +/*! Determine the time difference between now and the given time point + * \returns time difference + * + * \param[in] from timespec of a reference time point + * \param[in] kind expected return value type: milliseconds, centiseconds etc. + */ +time_t osmo_time_elapsed(const struct timespec *from, enum osmo_elapsed kind) +{ + struct timespec t_now; + long ns; + time_t sec; + + if (kind == T_TEST) { /* used for internal test only: */ + ns = 2 * from->tv_sec + OSMO_TIME_TEST_MAGIC; + t_now.tv_sec = OSMO_US2SEC(ns); + t_now.tv_nsec = OSMO_TIME_TEST_MAGIC + OSMO_USEC2NS(ns - t_now.tv_sec); + } else if (clock_gettime(CLOCK_MONOTONIC, &t_now) != 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "Failed to get time for elapsed computation: %s\n", strerror(errno)); + return 0; + } + + ns = t_diff_nsec(&t_now, from); + sec = t_diff_sec(&t_now, from); + + switch (kind) { + case T_SECS: + return sec; + case T_MILLIS: + return OSMO_SEC2MS(sec) + OSMO_NSEC2MS(ns); + case T_CENTIS: + return OSMO_SEC2CS(sec) + OSMO_NSEC2CS(ns); + case T_TEST: + return OSMO_SEC2US(sec) + OSMO_NSEC2US(ns); + default: + LOGP(DLGLOBAL, LOGL_ERROR, "Unhandled kind in elapsed time computation: %u\n", kind); + } + + return 0; +} + +#endif /* !EMBEDDED */ + /*! Determine time between now and the nearest timer * \returns pointer to timeval of nearest timer, NULL if there is none * diff --git a/tests/timer/timer_test.c b/tests/timer/timer_test.c index d2b0204..03811e0 100644 --- a/tests/timer/timer_test.c +++ b/tests/timer/timer_test.c @@ -27,6 +27,9 @@ #include <signal.h> #include <getopt.h> #include <unistd.h> +#include <string.h> +#include <errno.h> +#include <time.h> #include <osmocom/core/talloc.h> #include <osmocom/core/timer.h> @@ -35,7 +38,6 @@ #include "../config.h" -static void main_timer_fired(void *data); static void secondary_timer_fired(void *data); static unsigned int main_timer_step = 0; @@ -55,9 +57,6 @@ /* time between two steps, in secs. */ #define TIME_BETWEEN_STEPS 1 - -/* how much time elapses between checks, in microsecs */ -#define TIME_BETWEEN_TIMER_CHECKS 423210 static int timer_nsteps = MAIN_TIMER_NSTEPS; static unsigned int expired_timers = 0; @@ -109,7 +108,7 @@ { struct test_timer *v = data, *this, *tmp; struct timeval current, res; - struct timeval precision = { 0, TIME_BETWEEN_TIMER_CHECKS + 1}; + struct timeval precision = { 0, OSMO_TIME_TEST_MAGIC + 1}; int i, deleted; osmo_gettimeofday(¤t, NULL); @@ -162,10 +161,35 @@ total_timers - expired_timers); } +static inline void print_elapsed(struct timespec *t, int step) +{ + time_t us, ms, cs, sec; + + t->tv_sec = step; + + us = osmo_time_elapsed(t, T_TEST); + ms = OSMO_USEC2MS(us); + cs = OSMO_NSEC2CS(OSMO_USEC2NS(us)); + sec = OSMO_US2SEC(us); /* should be equal to step as long as OSMO_TIME_TEST_MAGIC < 1 second */ + + printf("[%d] Elapsed time: milliseconds %s, centiseconds %s => %s\n", step, + (OSMO_MS2SEC(ms) == sec) ? "OK" : "FAIL", + (OSMO_CS2SEC(cs) == sec) ? "OK" : "FAIL", + (step == sec) ? "OK" : "FAIL"); +} + int main(int argc, char *argv[]) { int c; int steps; + struct timespec t_start; + + printf("Running elapsed timer tests...\n"); + + if (clock_gettime(CLOCK_MONOTONIC, &t_start) != 0) + printf("failed to start timer: %s\n", strerror(errno)); + else + printf("monotonic timer started...\n"); osmo_gettimeofday_override = true; @@ -185,11 +209,11 @@ } steps = ((MAIN_TIMER_NSTEPS * TIME_BETWEEN_STEPS + 20) * 1e6) - / TIME_BETWEEN_TIMER_CHECKS; + / OSMO_TIME_TEST_MAGIC; printf("Running timer test for %d iterations," " %d steps of %d msecs each\n", - timer_nsteps, steps, TIME_BETWEEN_TIMER_CHECKS / 1000); + timer_nsteps, steps, OSMO_TIME_TEST_MAGIC / 1000); osmo_timer_setup(&main_timer, main_timer_fired, &main_timer_step); osmo_timer_schedule(&main_timer, 1, 0); @@ -200,10 +224,12 @@ (int)osmo_gettimeofday_override_time.tv_usec); osmo_timers_prepare(); osmo_timers_update(); - osmo_gettimeofday_override_add(0, TIME_BETWEEN_TIMER_CHECKS); + osmo_gettimeofday_override_add(0, OSMO_TIME_TEST_MAGIC); + print_elapsed(&t_start, steps); } #else printf("Select not supported on this platform!\n"); #endif + return 0; } diff --git a/tests/timer/timer_test.ok b/tests/timer/timer_test.ok index 75b11c7..c6cae2c 100644 --- a/tests/timer/timer_test.ok +++ b/tests/timer/timer_test.ok @@ -1,13 +1,21 @@ +Running elapsed timer tests... +monotonic timer started... Running timer test for 8 iterations, 66 steps of 423 msecs each 23.424242 +[65] Elapsed time: milliseconds OK, centiseconds OK => OK 23.847452 +[64] Elapsed time: milliseconds OK, centiseconds OK => OK 24.270662 +[63] Elapsed time: milliseconds OK, centiseconds OK => OK 24.693872 main_timer_fired() scheduled timer at 25.693872 added 1 timers in step 0 (expired=0) +[62] Elapsed time: milliseconds OK, centiseconds OK => OK 25.117082 +[61] Elapsed time: milliseconds OK, centiseconds OK => OK 25.540292 +[60] Elapsed time: milliseconds OK, centiseconds OK => OK 25.963502 main_timer_fired() scheduled timer at 26.963502 @@ -15,8 +23,11 @@ added 2 timers in step 1 (expired=0) timer fired on time: 25.693872 (+ 0.269630) early deleted 0 timers, 2 still active +[59] Elapsed time: milliseconds OK, centiseconds OK => OK 26.386712 +[58] Elapsed time: milliseconds OK, centiseconds OK => OK 26.809922 +[57] Elapsed time: milliseconds OK, centiseconds OK => OK 27.233132 main_timer_fired() scheduled timer at 28.233132 @@ -26,10 +37,13 @@ added 4 timers in step 2 (expired=1) timer fired on time: 26.963502 (+ 0.269630) early deleted 1 timers, 4 still active +[56] Elapsed time: milliseconds OK, centiseconds OK => OK 27.656342 +[55] Elapsed time: milliseconds OK, centiseconds OK => OK 28.079552 timer fired on time: 27.963502 (+ 0.116050) early deleted 0 timers, 3 still active +[54] Elapsed time: milliseconds OK, centiseconds OK => OK 28.502762 main_timer_fired() scheduled timer at 29.502762 @@ -41,10 +55,13 @@ scheduled timer at 35.502762 scheduled timer at 36.502762 added 8 timers in step 3 (expired=4) +[53] Elapsed time: milliseconds OK, centiseconds OK => OK 28.925972 +[52] Elapsed time: milliseconds OK, centiseconds OK => OK 29.349182 timer fired on time: 29.233132 (+ 0.116050) early deleted 2 timers, 8 still active +[51] Elapsed time: milliseconds OK, centiseconds OK => OK 29.772392 main_timer_fired() scheduled timer at 30.772392 @@ -64,12 +81,15 @@ scheduled timer at 36.772392 scheduled timer at 37.772392 added 16 timers in step 4 (expired=7) +[50] Elapsed time: milliseconds OK, centiseconds OK => OK 30.195602 +[49] Elapsed time: milliseconds OK, centiseconds OK => OK 30.618812 timer fired on time: 30.502762 (+ 0.116050) early deleted 5 timers, 18 still active timer fired on time: 30.233132 (+ 0.385680) early deleted 4 timers, 13 still active +[48] Elapsed time: milliseconds OK, centiseconds OK => OK 31.042022 main_timer_fired() scheduled timer at 32.042022 @@ -105,12 +125,15 @@ scheduled timer at 38.042022 scheduled timer at 39.042022 added 32 timers in step 5 (expired=18) +[47] Elapsed time: milliseconds OK, centiseconds OK => OK 31.465232 timer fired on time: 31.233132 (+ 0.232100) early deleted 11 timers, 33 still active +[46] Elapsed time: milliseconds OK, centiseconds OK => OK 31.888442 timer fired on time: 31.772392 (+ 0.116050) early deleted 8 timers, 24 still active +[45] Elapsed time: milliseconds OK, centiseconds OK => OK 32.311652 main_timer_fired() scheduled timer at 33.311652 @@ -178,12 +201,15 @@ scheduled timer at 39.311652 scheduled timer at 40.311652 added 64 timers in step 6 (expired=39) +[44] Elapsed time: milliseconds OK, centiseconds OK => OK 32.734862 +[43] Elapsed time: milliseconds OK, centiseconds OK => OK 33.158072 timer fired on time: 33.042022 (+ 0.116050) early deleted 21 timers, 66 still active timer fired on time: 33.042022 (+ 0.116050) early deleted 16 timers, 49 still active +[42] Elapsed time: milliseconds OK, centiseconds OK => OK 33.581282 main_timer_fired() scheduled timer at 34.581282 @@ -315,7 +341,9 @@ scheduled timer at 40.581282 scheduled timer at 41.581282 added 128 timers in step 7 (expired=78) +[41] Elapsed time: milliseconds OK, centiseconds OK => OK 34.004492 +[40] Elapsed time: milliseconds OK, centiseconds OK => OK 34.427702 timer fired on time: 34.311652 (+ 0.116050) early deleted 44 timers, 132 still active @@ -323,10 +351,13 @@ early deleted 32 timers, 99 still active timer fired on time: 34.311652 (+ 0.116050) early deleted 24 timers, 74 still active +[39] Elapsed time: milliseconds OK, centiseconds OK => OK 34.850912 main_timer_fired() Main timer has finished, please, wait a bit for the final report. +[38] Elapsed time: milliseconds OK, centiseconds OK => OK 35.274122 +[37] Elapsed time: milliseconds OK, centiseconds OK => OK 35.697332 timer fired on time: 35.581282 (+ 0.116050) early deleted 18 timers, 55 still active @@ -334,35 +365,49 @@ early deleted 13 timers, 41 still active timer fired on time: 35.581282 (+ 0.116050) early deleted 10 timers, 30 still active +[36] Elapsed time: milliseconds OK, centiseconds OK => OK 36.120542 +[35] Elapsed time: milliseconds OK, centiseconds OK => OK 36.543752 timer fired on time: 36.311652 (+ 0.232100) early deleted 7 timers, 22 still active timer fired on time: 36.311652 (+ 0.232100) early deleted 5 timers, 16 still active +[34] Elapsed time: milliseconds OK, centiseconds OK => OK 36.966962 timer fired on time: 36.581282 (+ 0.385680) early deleted 3 timers, 12 still active +[33] Elapsed time: milliseconds OK, centiseconds OK => OK 37.390172 timer fired on time: 37.042022 (+ 0.348150) early deleted 2 timers, 9 still active +[32] Elapsed time: milliseconds OK, centiseconds OK => OK 37.813382 timer fired on time: 37.581282 (+ 0.232100) early deleted 2 timers, 6 still active +[31] Elapsed time: milliseconds OK, centiseconds OK => OK 38.236592 +[30] Elapsed time: milliseconds OK, centiseconds OK => OK 38.659802 +[29] Elapsed time: milliseconds OK, centiseconds OK => OK 39.083012 +[28] Elapsed time: milliseconds OK, centiseconds OK => OK 39.506222 timer fired on time: 39.311652 (+ 0.194570) early deleted 1 timers, 4 still active +[27] Elapsed time: milliseconds OK, centiseconds OK => OK 39.929432 timer fired on time: 39.581282 (+ 0.348150) early deleted 0 timers, 3 still active +[26] Elapsed time: milliseconds OK, centiseconds OK => OK 40.352642 +[25] Elapsed time: milliseconds OK, centiseconds OK => OK 40.775852 timer fired on time: 40.581282 (+ 0.194570) early deleted 0 timers, 2 still active +[24] Elapsed time: milliseconds OK, centiseconds OK => OK 41.199062 +[23] Elapsed time: milliseconds OK, centiseconds OK => OK 41.622272 timer fired on time: 41.581282 (+ 0.040990) early deleted 0 timers, 1 still active -- To view, visit https://gerrit.osmocom.org/5103 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I83d865ff633a7ebda2c943477205fd31aceda277 Gerrit-PatchSet: 5 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Max <msuraev at sysmocom.de> Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de> Gerrit-Reviewer: Vadim Yanitskiy <axilirator at gmail.com>