[PATCH] osmocom-bb[master]: host/trxcon/scheduler: simplify timeslot management

Harald Welte gerrit-no-reply at lists.osmocom.org
Thu Feb 22 15:33:13 UTC 2018


Review at  https://gerrit.osmocom.org/6753

host/trxcon/scheduler: simplify timeslot management

As we know the count of timeslots per GSM TDMA frame, it would
be better to have an array of pointers to trx_ts instances instead
of linux list, which is more usable for lists with unknown length.

Change-Id: I9510a5cddde22950ceb8422e0990d59f05ed4d60
---
M src/host/trxcon/sched_trx.c
M src/host/trxcon/sched_trx.h
M src/host/trxcon/trx_if.h
3 files changed, 51 insertions(+), 58 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/53/6753/1

diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 7ac6497..3e61582 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -55,13 +55,20 @@
 	uint8_t offset, bid;
 	struct trx_ts *ts;
 	uint32_t fn;
+	int i;
 
-	/* If we have no active timeslots, nothing to do */
-	if (llist_empty(&trx->ts_list))
-		return;
+	/* Iterate over timeslot list */
+	for (i = 0; i < TRX_TS_COUNT; i++) {
+		/* Timeslot is not allocated */
+		ts = trx->ts_list[i];
+		if (ts == NULL)
+			continue;
 
-	/* For each allocated timeslot */
-	llist_for_each_entry(ts, &trx->ts_list, list) {
+		/* Timeslot is not configured */
+		if (ts->mf_layout == NULL)
+			continue;
+
+		/* There is nothing to send */
 		if (llist_empty(&ts->tx_prims))
 			continue;
 
@@ -107,8 +114,6 @@
 	sched = &trx->sched;
 	sched->data = trx;
 
-	INIT_LLIST_HEAD(&trx->ts_list);
-
 	return 0;
 }
 
@@ -142,8 +147,6 @@
 	for (i = 0; i < TRX_TS_COUNT; i++)
 		sched_trx_del_ts(trx, i);
 
-	INIT_LLIST_HEAD(&trx->ts_list);
-
 	/* Stop and reset clock counter if required */
 	if (reset_clock)
 		sched_clck_reset(&trx->sched);
@@ -151,89 +154,81 @@
 	return 0;
 }
 
-struct trx_ts *sched_trx_add_ts(struct trx_instance *trx, int ts_num)
+struct trx_ts *sched_trx_add_ts(struct trx_instance *trx, int tn)
 {
-	struct trx_ts *ts;
-
-	LOGP(DSCH, LOGL_NOTICE, "Add a new TDMA timeslot #%u\n", ts_num);
-
-	ts = talloc_zero(trx, struct trx_ts);
-	if (!ts)
+	/* Make sure that ts isn't allocated yet */
+	if (trx->ts_list[tn] != NULL) {
+		LOGP(DSCH, LOGL_ERROR, "Timeslot #%u already allocated\n", tn);
 		return NULL;
-
-	llist_add_tail(&ts->list, &trx->ts_list);
-
-	return ts;
-}
-
-struct trx_ts *sched_trx_find_ts(struct trx_instance *trx, int ts_num)
-{
-	struct trx_ts *ts;
-
-	if (llist_empty(&trx->ts_list))
-		return NULL;
-
-	llist_for_each_entry(ts, &trx->ts_list, list) {
-		if (ts->index == ts_num)
-			return ts;
 	}
 
-	return NULL;
+	LOGP(DSCH, LOGL_NOTICE, "Add a new TDMA timeslot #%u\n", tn);
+
+	/* Allocate a new one */
+	trx->ts_list[tn] = talloc_zero(trx, struct trx_ts);
+
+	/* Assign TS index */
+	trx->ts_list[tn]->index = tn;
+
+	return trx->ts_list[tn];
 }
 
-void sched_trx_del_ts(struct trx_instance *trx, int ts_num)
+/* FIXME: one kept here for compatibility reasons */
+struct trx_ts *sched_trx_find_ts(struct trx_instance *trx, int tn)
+{
+	return trx->ts_list[tn];
+}
+
+void sched_trx_del_ts(struct trx_instance *trx, int tn)
 {
 	struct trx_ts *ts;
 
 	/* Find ts in list */
-	ts = sched_trx_find_ts(trx, ts_num);
+	ts = trx->ts_list[tn];
 	if (ts == NULL)
 		return;
 
-	LOGP(DSCH, LOGL_NOTICE, "Delete TDMA timeslot #%u\n", ts_num);
+	LOGP(DSCH, LOGL_NOTICE, "Delete TDMA timeslot #%u\n", tn);
 
 	/* Flush queue primitives for TX */
 	msgb_queue_flush(&ts->tx_prims);
 
-	/* Remove ts from list */
-	llist_del(&ts->list);
+	/* Remove ts from list and free memory */
+	trx->ts_list[tn] = NULL;
 	talloc_free(ts);
 
 	/* Notify transceiver about that */
-	trx_if_cmd_setslot(trx, ts_num, 0);
+	trx_if_cmd_setslot(trx, tn, 0);
 }
 
-int sched_trx_configure_ts(struct trx_instance *trx, int ts_num,
+int sched_trx_configure_ts(struct trx_instance *trx, int tn,
 	enum gsm_phys_chan_config config)
 {
 	int i, type, lchan_cnt = 0;
 	struct trx_ts *ts;
 
 	/* Try to find specified ts */
-	ts = sched_trx_find_ts(trx, ts_num);
+	ts = trx->ts_list[tn];
 	if (ts != NULL) {
 		/* Reconfiguration of existing one */
-		sched_trx_reset_ts(trx, ts_num);
+		sched_trx_reset_ts(trx, tn);
 	} else {
 		/* Allocate a new one if doesn't exist */
-		ts = sched_trx_add_ts(trx, ts_num);
+		ts = sched_trx_add_ts(trx, tn);
 		if (ts == NULL)
 			return -ENOMEM;
-
-		/* Assign TS index */
-		ts->index = ts_num;
 	}
 
 	/* Init queue primitives for TX */
 	INIT_LLIST_HEAD(&ts->tx_prims);
 
 	/* Choose proper multiframe layout */
-	ts->mf_layout = sched_mframe_layout(config, ts_num);
+	ts->mf_layout = sched_mframe_layout(config, tn);
 	if (ts->mf_layout->chan_config != config)
 		return -EINVAL;
 
 	LOGP(DSCH, LOGL_NOTICE, "(Re)configure TDMA timeslot #%u as %s\n",
-		ts_num, ts->mf_layout->name);
+		tn, ts->mf_layout->name);
 
 	/* Count channel states */
 	for (type = 0; type < _TRX_CHAN_MAX; type++)
@@ -262,17 +257,17 @@
 
 	/* Notify transceiver about TS activation */
 	/* FIXME: set proper channel type */
-	trx_if_cmd_setslot(trx, ts_num, 1);
+	trx_if_cmd_setslot(trx, tn, 1);
 
 	return 0;
 }
 
-int sched_trx_reset_ts(struct trx_instance *trx, int ts_num)
+int sched_trx_reset_ts(struct trx_instance *trx, int tn)
 {
 	struct trx_ts *ts;
 
 	/* Try to find specified ts */
-	ts = sched_trx_find_ts(trx, ts_num);
+	ts = trx->ts_list[tn];
 	if (ts == NULL)
 		return -EINVAL;
 
@@ -289,7 +284,7 @@
 	talloc_free(ts->lchans);
 
 	/* Notify transceiver about that */
-	trx_if_cmd_setslot(trx, ts_num, 0);
+	trx_if_cmd_setslot(trx, tn, 0);
 
 	return 0;
 }
@@ -416,7 +411,7 @@
 	return TRXC_IDLE;
 }
 
-int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t ts_num,
+int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
 	uint32_t burst_fn, sbit_t *bits, uint16_t nbits, int8_t rssi, float toa)
 {
 	struct trx_lchan_state *lchan;
@@ -429,10 +424,10 @@
 	uint8_t offset, bid;
 
 	/* Check whether required timeslot is enabled / configured */
-	ts = sched_trx_find_ts(trx, ts_num);
+	ts = sched_trx_find_ts(trx, tn);
 	if (ts == NULL) {
 		LOGP(DSCH, LOGL_DEBUG, "TDMA timeslot #%u isn't configured, "
-			"ignoring burst...\n", ts_num);
+			"ignoring burst...\n", tn);
 		return -EINVAL;
 	}
 
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index ff3d254..42953b3 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -228,8 +228,6 @@
 	struct trx_lchan_state *lchans;
 	/*! \brief Queue primitives for TX */
 	struct llist_head tx_prims;
-	/*! \brief Link to parent list */
-	struct llist_head list;
 };
 
 /* Represents one TX primitive in the queue of trx_ts */
diff --git a/src/host/trxcon/trx_if.h b/src/host/trxcon/trx_if.h
index f09a256..fbfa8b5 100644
--- a/src/host/trxcon/trx_if.h
+++ b/src/host/trxcon/trx_if.h
@@ -38,7 +38,7 @@
 
 	/* Scheduler stuff */
 	struct trx_sched sched;
-	struct llist_head ts_list;
+	struct trx_ts *ts_list[TRX_TS_COUNT];
 
 	/* Bind L1CTL link */
 	struct l1ctl_link *l1l;

-- 
To view, visit https://gerrit.osmocom.org/6753
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9510a5cddde22950ceb8422e0990d59f05ed4d60
Gerrit-PatchSet: 1
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>


More information about the gerrit-log mailing list