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
This commit is contained in:
Daniel Willmann 2014-05-30 20:21:30 +02:00 committed by Holger Hans Peter Freyther
parent 1e0c61032f
commit 17a1d5e162
4 changed files with 24 additions and 26 deletions

View File

@ -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);
}

View File

@ -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
};

View File

@ -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;
}

View File

@ -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);
}