msuraev has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/30302 )
Change subject: rate_ctr: convert to timerfd ......................................................................
rate_ctr: convert to timerfd
Use timerfd to schedule 1-second periodic timer once instead rescheduling every second in timer callback.
Related: OS#5671 Change-Id: I2525fd691caa380a862d305cfcb4fa3cc50b70d0 --- M src/rate_ctr.c 1 file changed, 46 insertions(+), 12 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved pespin: Looks good to me, but someone else must approve
diff --git a/src/rate_ctr.c b/src/rate_ctr.c index ffae1b8..3fc4992 100644 --- a/src/rate_ctr.c +++ b/src/rate_ctr.c @@ -53,14 +53,17 @@ * * \file rate_ctr.c */
+#include <errno.h> #include <stdbool.h> #include <stdint.h> #include <string.h> +#include <unistd.h> +#include <inttypes.h>
#include <osmocom/core/utils.h> #include <osmocom/core/linuxlist.h> #include <osmocom/core/talloc.h> -#include <osmocom/core/timer.h> +#include <osmocom/core/select.h> #include <osmocom/core/rate_ctr.h> #include <osmocom/core/logging.h>
@@ -310,7 +313,7 @@ ctr->intv[intv+1].rate += ctr->intv[intv].rate; }
-static struct osmo_timer_list rate_ctr_timer; +static struct osmo_fd rate_ctr_timer = { .fd = -1 }; static uint64_t timer_ticks;
/* The one-second interval has expired */ @@ -331,18 +334,35 @@ } }
-static void rate_ctr_timer_cb(void *data) +static int rate_ctr_timer_cb(struct osmo_fd *ofd, unsigned int what) { struct rate_ctr_group *ctrg; + uint64_t expire_count; + int rc;
- /* Increment number of ticks before we calculate intervals, - * as a counter value of 0 would already wrap all counters */ - timer_ticks++; + /* check that the timer has actually expired */ + if (!(what & OSMO_FD_READ)) + return 0;
- llist_for_each_entry(ctrg, &rate_ctr_groups, list) - rate_ctr_group_intv(ctrg); + /* read from timerfd: number of expirations of periodic timer */ + rc = read(ofd->fd, (void *) &expire_count, sizeof(expire_count)); + if (rc < 0 && errno == EAGAIN) + return 0;
- osmo_timer_schedule(&rate_ctr_timer, 1, 0); + OSMO_ASSERT(rc == sizeof(expire_count)); + + if (expire_count > 1) + LOGP(DLGLOBAL, LOGL_NOTICE, "Stats timer expire_count=%" PRIu64 ": We missed %" PRIu64 " timers\n", + expire_count, expire_count - 1); + + do { /* Increment number of ticks before we calculate intervals, + * as a counter value of 0 would already wrap all counters */ + timer_ticks++; + llist_for_each_entry(ctrg, &rate_ctr_groups, list) + rate_ctr_group_intv(ctrg); + } while (--expire_count); + + return 0; }
/*! Initialize the counter module. Call this once from your application. @@ -350,13 +370,27 @@ * \returns 0 on success; negative on error */ int rate_ctr_init(void *tall_ctx) { + struct timespec ts_interval = { .tv_sec = 1, .tv_nsec = 0 }; + int rc; + /* ignore repeated initialization */ - if (osmo_timer_pending(&rate_ctr_timer)) + if (osmo_fd_is_registered(&rate_ctr_timer)) return 0;
tall_rate_ctr_ctx = tall_ctx; - osmo_timer_setup(&rate_ctr_timer, rate_ctr_timer_cb, NULL); - osmo_timer_schedule(&rate_ctr_timer, 1, 0); + + rc = osmo_timerfd_setup(&rate_ctr_timer, rate_ctr_timer_cb, NULL); + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "Failed to setup the timer with error code %d (fd=%d)\n", + rc, rate_ctr_timer.fd); + return rc; + } + + rc = osmo_timerfd_schedule(&rate_ctr_timer, NULL, &ts_interval); + if (rc < 0) { + LOGP(DLGLOBAL, LOGL_ERROR, "Failed to schedule the timer with error code %d (fd=%d)\n", + rc, rate_ctr_timer.fd); + }
return 0; }
11 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one.