aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Willmann <dwillmann@sysmocom.de>2014-05-30 20:21:30 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-06-04 17:17:45 +0200
commit17a1d5e1623ca7c09bc312fd402cdf0075b523be (patch)
tree20da98fbbb5ca7c9b2ed90cc3d12317077ccfe80
parent1e0c61032fbccc6bd4b1fbd89765f125643e79c3 (diff)
gprs_rlcmac_pdch: Get rid of ul/dl_tbf
The current code keeps a reference to all tbfs in the bts and another reference in the pdch. This allows for the possibility of both lists to go out of sync. This patch removes the pdch-specific list of ul and dl tbfs and uses the lists in the bts to lookup tbfs everywhere. Performance for going through the global list is not an issue yet. We can optimize this later and in a better way. Sponsored-by: On-Waves ehf
-rw-r--r--src/bts.cpp26
-rw-r--r--src/bts.h3
-rw-r--r--src/gprs_rlcmac_ts_alloc.cpp4
-rw-r--r--src/tbf.cpp17
4 files changed, 24 insertions, 26 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 3ca3628..9de6dc3 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -991,16 +991,26 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int8_t
return rc;
}
-struct gprs_rlcmac_tbf *gprs_rlcmac_pdch::ul_tbf_by_tfi(uint8_t tfi)
+gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi(struct llist_head *tbf_list, uint8_t tfi)
{
- if (tfi >= ARRAY_SIZE(ul_tbf))
- return NULL;
- return ul_tbf[tfi];
+ gprs_rlcmac_tbf *tbf;
+
+ llist_for_each_entry(tbf, tbf_list, list) {
+ if (tbf->tfi() != tfi)
+ continue;
+ if (!tbf->pdch[ts_no])
+ continue;
+ return tbf;
+ }
+ return NULL;
}
-struct gprs_rlcmac_tbf *gprs_rlcmac_pdch::dl_tbf_by_tfi(uint8_t tfi)
+gprs_rlcmac_tbf *gprs_rlcmac_pdch::ul_tbf_by_tfi(uint8_t tfi)
{
- if (tfi >= ARRAY_SIZE(dl_tbf))
- return NULL;
- return dl_tbf[tfi];
+ return tbf_from_list_by_tfi(&bts_data()->ul_tbfs, tfi);
+}
+
+gprs_rlcmac_tbf *gprs_rlcmac_pdch::dl_tbf_by_tfi(uint8_t tfi)
+{
+ return tbf_from_list_by_tfi(&bts_data()->dl_tbfs, tfi);
}
diff --git a/src/bts.h b/src/bts.h
index 578c63d..aa68ed7 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -71,8 +71,6 @@ struct gprs_rlcmac_pdch {
uint8_t next_ul_tfi; /* next uplink TBF/TFI to schedule (0..31) */
uint8_t next_dl_tfi; /* next downlink TBF/TFI to schedule (0..31) */
uint8_t next_ctrl_prio; /* next kind of ctrl message to schedule */
- struct gprs_rlcmac_tbf *ul_tbf[32]; /* array of UL TBF, by UL TFI */
- struct gprs_rlcmac_tbf *dl_tbf[32]; /* array of DL TBF, by DL TFI */
struct llist_head paging_list; /* list of paging messages */
uint32_t last_rts_fn; /* store last frame number of RTS */
@@ -89,6 +87,7 @@ private:
void rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *, uint32_t fn);
void rcv_resource_request(Packet_Resource_Request_t *t, uint32_t fn);
void rcv_measurement_report(Packet_Measurement_Report_t *t, uint32_t fn);
+ gprs_rlcmac_tbf *tbf_from_list_by_tfi(struct llist_head *tbf_list, uint8_t tfi);
#endif
};
diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp
index 13fc636..b070c2e 100644
--- a/src/gprs_rlcmac_ts_alloc.cpp
+++ b/src/gprs_rlcmac_ts_alloc.cpp
@@ -83,7 +83,7 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch)
/* make map of used USF */
for (tfi = 0; tfi < 32; tfi++) {
- tbf = pdch->ul_tbf[tfi];
+ tbf = pdch->ul_tbf_by_tfi(tfi);
if (!tbf)
continue;
usf_map |= (1 << tbf->dir.ul.usf[pdch->ts_no]);
@@ -121,7 +121,6 @@ static void assign_uplink_tbf_usf(
struct gprs_rlcmac_tbf *tbf, int8_t usf)
{
tbf->trx->ul_tbf[tbf->tfi()] = tbf;
- pdch->ul_tbf[tbf->tfi()] = tbf;
tbf->pdch[pdch->ts_no] = pdch;
tbf->dir.ul.usf[pdch->ts_no] = usf;
}
@@ -131,7 +130,6 @@ static void assign_dlink_tbf(
struct gprs_rlcmac_tbf *tbf)
{
tbf->trx->dl_tbf[tbf->tfi()] = tbf;
- pdch->dl_tbf[tbf->tfi()] = tbf;
tbf->pdch[pdch->ts_no] = pdch;
}
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 3a2ad73..5943674 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -250,25 +250,16 @@ struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts,
static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
{
- struct gprs_rlcmac_pdch *pdch;
int ts;
if (tbf->direction == GPRS_RLCMAC_UL_TBF) {
tbf->trx->ul_tbf[tbf->tfi()] = NULL;
- for (ts = 0; ts < 8; ts++) {
- pdch = tbf->pdch[ts];
- if (pdch)
- pdch->ul_tbf[tbf->tfi()] = NULL;
+ for (ts = 0; ts < 8; ts++)
tbf->pdch[ts] = NULL;
- }
} else {
tbf->trx->dl_tbf[tbf->tfi()] = NULL;
- for (ts = 0; ts < 8; ts++) {
- pdch = tbf->pdch[ts];
- if (pdch)
- pdch->dl_tbf[tbf->tfi()] = NULL;
+ for (ts = 0; ts < 8; ts++)
tbf->pdch[ts] = NULL;
- }
}
}
@@ -1472,10 +1463,10 @@ void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_pdch *pdch)
for (uint8_t tfi = 0; tfi < 32; tfi++) {
struct gprs_rlcmac_tbf *tbf;
- tbf = pdch->ul_tbf[tfi];
+ tbf = pdch->ul_tbf_by_tfi(tfi);
if (tbf)
tbf_free(tbf);
- tbf = pdch->dl_tbf[tfi];
+ tbf = pdch->dl_tbf_by_tfi(tfi);
if (tbf)
tbf_free(tbf);
}