Timur Davydov has uploaded this change for review.

View Change

trx: factor out FN timer processing into common helper

Extract core FN timer handling logic into trx_fn_timer_process()
to decouple it from timerfd-specific code.

This allows reusing the same scheduling logic for alternative
timer backends (e.g. WebSDR) while keeping timerfd integration
as a thin wrapper.

No functional changes intended.

Change-Id: Ia28cce57afb3dc97c8655e855ebd5ace7e096648
---
M src/osmo-bts-trx/scheduler_trx.c
1 file changed, 34 insertions(+), 24 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/92/42692/1
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index bac66da..277d4d5 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -405,26 +405,14 @@
ts->tv_nsec = ts->tv_nsec % 1000000000;
}

-/*! this is the timerfd-callback firing for every FN to be processed */
-static int trx_fn_timer_cb(struct osmo_fd *ofd, unsigned int what)
+/*! Common FN timer tick processing, shared by timerfd and WebSDR timer backends. */
+static int trx_fn_timer_process(struct gsm_bts *bts, uint64_t expire_count)
{
- struct gsm_bts *bts = ofd->data;
struct bts_trx_priv *bts_trx = (struct bts_trx_priv *)bts->model_priv;
struct osmo_trx_clock_state *tcs = &bts_trx->clk_s;
struct timespec tv_now;
- uint64_t expire_count;
int64_t elapsed_us, error_us;
- const char *reason = NULL;
- int rc, i;
-
- if (!(what & OSMO_FD_READ))
- return 0;
-
- /* 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_ASSERT(rc == sizeof(expire_count));
+ int i;

if (expire_count > 1) {
LOGP(DL1C, LOGL_NOTICE, "FN timer expire_count=%"PRIu64": We missed %"PRIu64" timers\n",
@@ -434,9 +422,8 @@

/* check if transceiver is still alive */
if (tcs->fn_without_clock_ind++ == TRX_LOSS_FRAMES) {
- reason = "No more clock from transceiver";
- LOGP(DL1C, LOGL_ERROR, "%s\n", reason);
- goto shutdown;
+ LOGP(DL1C, LOGL_ERROR, "No more clock from transceiver\n");
+ return -1;
}

/* compute actual elapsed time and resulting OS scheduling error */
@@ -454,8 +441,7 @@
LOGP(DL1C, LOGL_ERROR,
"PC clock skew: elapsed_us=%" PRId64 ", error_us=%" PRId64 "\n",
elapsed_us, error_us);
- reason = "PC clock skew too high";
- goto shutdown;
+ return -1;
}

/* call bts_sched_fn() for all expired FN */
@@ -463,11 +449,35 @@
bts_sched_fn(bts, GSM_TDMA_FN_INC(tcs->last_fn_timer.fn));

return 0;
+}

-shutdown:
- osmo_timerfd_disable(&tcs->fn_timer_ofd);
- bts_shutdown(bts, reason);
- return -1;
+/*! this is the timerfd-callback firing for every FN to be processed */
+static int trx_fn_timer_cb(struct osmo_fd *ofd, unsigned int what)
+{
+ struct gsm_bts *bts = ofd->data;
+ struct bts_trx_priv *bts_trx = (struct bts_trx_priv *)bts->model_priv;
+ struct osmo_trx_clock_state *tcs = &bts_trx->clk_s;
+ uint64_t expire_count;
+ const char *reason = NULL;
+ int rc;
+
+ if (!(what & OSMO_FD_READ))
+ return 0;
+
+ /* 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_ASSERT(rc == sizeof(expire_count));
+
+ rc = trx_fn_timer_process(bts, expire_count);
+ if (rc < 0) {
+ osmo_timerfd_disable(&tcs->fn_timer_ofd);
+ bts_shutdown(bts, reason);
+ return -1;
+ }
+
+ return 0;
}

/*! \brief This is the cb of the initial timer set upon start. On timeout, it

To view, visit change 42692. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Ia28cce57afb3dc97c8655e855ebd5ace7e096648
Gerrit-Change-Number: 42692
Gerrit-PatchSet: 1
Gerrit-Owner: Timur Davydov <dtv.comp@gmail.com>