aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-12-28 19:15:40 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-01 13:58:13 +0100
commited2dbf6954b9883218f5ace1d801c0e316df912a (patch)
tree1f8a44144bacbad9ca3d7bd947a5a2c8d1cbd726 /src
parentbf49f042d432780fe37c53aed5e4e3f34ac80793 (diff)
tbf: Use LListHead instead of llist_pods
LListHead does basically the same like llist_pods, but more C++ish and with type safety. This commit turns the former list field of gprs_rlcmac_tbf into a private field, provides accessors, moves the related code from pcu_vty.c to pcu_vty_functions.cpp, and removes the llist_pods type and related code. Sponsored-by: On-Waves ehf
Diffstat (limited to 'src')
-rw-r--r--src/bts.cpp31
-rw-r--r--src/bts.h26
-rw-r--r--src/gprs_rlcmac_sched.cpp14
-rw-r--r--src/pcu_vty.c14
-rw-r--r--src/pcu_vty_functions.cpp19
-rw-r--r--src/pcu_vty_functions.h3
-rw-r--r--src/poll_controller.cpp9
-rw-r--r--src/rlc.h6
-rw-r--r--src/tbf.cpp17
-rw-r--r--src/tbf.h37
10 files changed, 91 insertions, 85 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 1eea0824..52811c2c 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -127,8 +127,6 @@ BTS::BTS()
, m_ms_store(this)
{
memset(&m_bts, 0, sizeof(m_bts));
- INIT_LLIST_HEAD(&m_bts.ul_tbfs);
- INIT_LLIST_HEAD(&m_bts.dl_tbfs);
m_bts.bts = this;
/* initialize back pointers */
@@ -214,14 +212,14 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv)
{
uint8_t l, trx, ts, any_tbf = 0;
struct gprs_rlcmac_tbf *tbf;
- struct llist_pods *lpods;
+ LListHead<gprs_rlcmac_tbf> *pos;
struct gprs_rlcmac_paging *pag;
uint8_t slot_mask[8];
int8_t first_ts; /* must be signed */
- llist_head *tbfs_lists[] = {
- &m_bts.ul_tbfs,
- &m_bts.dl_tbfs,
+ LListHead<gprs_rlcmac_tbf> *tbfs_lists[] = {
+ &m_ul_tbfs,
+ &m_dl_tbfs,
NULL
};
@@ -235,7 +233,8 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv)
* Don't mark, if TBF uses a different slot that is already marked. */
memset(slot_mask, 0, sizeof(slot_mask));
for (l = 0; tbfs_lists[l]; l++) {
- llist_pods_for_each_entry(tbf, tbfs_lists[l], list, lpods) {
+ llist_for_each(pos, tbfs_lists[l]) {
+ tbf = pos->entry();
first_ts = -1;
for (ts = 0; ts < 8; ts++) {
if (tbf->pdch[ts]) {
@@ -296,11 +295,12 @@ int BTS::add_paging(uint8_t chan_needed, uint8_t *identity_lv)
gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)
{
struct gprs_rlcmac_dl_tbf *tbf;
- struct llist_pods *lpods;
+ LListHead<gprs_rlcmac_tbf> *pos;
/* only one TBF can poll on specific TS/FN, because scheduler can only
* schedule one downlink control block (with polling) at a FN per TS */
- llist_pods_for_each_entry(tbf, &m_bts.dl_tbfs, list, lpods) {
+ llist_for_each(pos, &m_dl_tbfs) {
+ tbf = as_dl_tbf(pos->entry());
if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)
&& tbf->poll_state == GPRS_RLCMAC_POLL_SCHED
&& tbf->poll_fn == fn && tbf->trx->trx_no == trx
@@ -313,11 +313,12 @@ gprs_rlcmac_dl_tbf *BTS::dl_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)
gprs_rlcmac_ul_tbf *BTS::ul_tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts)
{
struct gprs_rlcmac_ul_tbf *tbf;
- struct llist_pods *lpods;
+ LListHead<gprs_rlcmac_tbf> *pos;
/* only one TBF can poll on specific TS/FN, because scheduler can only
* schedule one downlink control block (with polling) at a FN per TS */
- llist_pods_for_each_entry(tbf, &m_bts.ul_tbfs, list, lpods) {
+ llist_for_each(pos, &m_ul_tbfs) {
+ tbf = as_ul_tbf(pos->entry());
if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)
&& tbf->poll_state == GPRS_RLCMAC_POLL_SCHED
&& tbf->poll_fn == fn && tbf->trx->trx_no == trx
@@ -1241,13 +1242,15 @@ int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint32_t fn,
return rc;
}
-gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi(struct llist_head *tbf_list, uint8_t tfi,
+gprs_rlcmac_tbf *gprs_rlcmac_pdch::tbf_from_list_by_tfi(
+ LListHead<gprs_rlcmac_tbf> *tbf_list, uint8_t tfi,
enum gprs_rlcmac_tbf_direction dir)
{
gprs_rlcmac_tbf *tbf;
- struct llist_pods *lpods;
+ LListHead<gprs_rlcmac_tbf> *pos;
- llist_pods_for_each_entry(tbf, tbf_list, list, lpods) {
+ llist_for_each(pos, tbf_list) {
+ tbf = pos->entry();
if (tbf->tfi() != tfi)
continue;
if (!tbf->pdch[ts_no])
diff --git a/src/bts.h b/src/bts.h
index 45432eaa..704a5bec 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -109,7 +109,8 @@ 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,
+ gprs_rlcmac_tbf *tbf_from_list_by_tfi(
+ LListHead<gprs_rlcmac_tbf> *tbf_list, uint8_t tfi,
enum gprs_rlcmac_tbf_direction dir);
gprs_rlcmac_tbf *tbf_by_tfi(uint8_t tfi,
enum gprs_rlcmac_tbf_direction dir);
@@ -185,12 +186,6 @@ struct gprs_rlcmac_bts {
struct {int16_t low; int16_t high;} cs_lqual_ranges[4];
uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */
- /* TBF handling, make private or move into TBFController */
- /* list of uplink TBFs */
- struct llist_head ul_tbfs;
- /* list of downlink TBFs */
- struct llist_head dl_tbfs;
-
/* State for dynamic algorithm selection */
int multislot_disabled;
@@ -319,6 +314,8 @@ public:
struct rate_ctr_group *rate_counters() const;
struct osmo_stat_item_group *stat_items() const;
+ LListHead<gprs_rlcmac_tbf>& ul_tbfs();
+ LListHead<gprs_rlcmac_tbf>& dl_tbfs();
private:
int m_cur_fn;
int m_cur_blk_fn;
@@ -330,6 +327,11 @@ private:
GprsMsStorage m_ms_store;
+ /* list of uplink TBFs */
+ LListHead<gprs_rlcmac_tbf> m_ul_tbfs;
+ /* list of downlink TBFs */
+ LListHead<gprs_rlcmac_tbf> m_dl_tbfs;
+
private:
/* disable copying to avoid slicing */
BTS(const BTS&);
@@ -361,6 +363,16 @@ inline GprsMs *BTS::ms_by_imsi(const char *imsi)
return ms_store().get_ms(0, 0, imsi);
}
+inline LListHead<gprs_rlcmac_tbf>& BTS::ul_tbfs()
+{
+ return m_ul_tbfs;
+}
+
+inline LListHead<gprs_rlcmac_tbf>& BTS::dl_tbfs()
+{
+ return m_dl_tbfs;
+}
+
inline BTS *gprs_rlcmac_pdch::bts() const
{
return trx->bts;
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index 8bf25734..4939efd8 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -25,7 +25,7 @@
#include "pcu_utils.h"
-static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,
+static uint32_t sched_poll(BTS *bts,
uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr,
struct gprs_rlcmac_tbf **poll_tbf,
struct gprs_rlcmac_tbf **ul_ass_tbf,
@@ -34,7 +34,7 @@ static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,
{
struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_dl_tbf *dl_tbf;
- struct llist_pods *lpods;
+ LListHead<gprs_rlcmac_tbf> *pos;
uint32_t poll_fn;
/* check special TBF for events */
@@ -42,7 +42,9 @@ static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,
if ((block_nr % 3) == 2)
poll_fn ++;
poll_fn = poll_fn % 2715648;
- llist_pods_for_each_entry(ul_tbf, &bts->ul_tbfs, list, lpods) {
+ llist_for_each(pos, &bts->ul_tbfs()) {
+ ul_tbf = as_ul_tbf(pos->entry());
+ OSMO_ASSERT(ul_tbf);
/* this trx, this ts */
if (ul_tbf->trx->trx_no != trx || ul_tbf->control_ts != ts)
continue;
@@ -58,7 +60,9 @@ static uint32_t sched_poll(struct gprs_rlcmac_bts *bts,
*ul_ass_tbf = ul_tbf;
#warning "Is this supposed to be fair? The last TBF for each wins? Maybe use llist_add_tail and skip once we have all states?"
}
- llist_pods_for_each_entry(dl_tbf, &bts->dl_tbfs, list, lpods) {
+ llist_for_each(pos, &bts->dl_tbfs()) {
+ dl_tbf = as_dl_tbf(pos->entry());
+ OSMO_ASSERT(dl_tbf);
/* this trx, this ts */
if (dl_tbf->trx->trx_no != trx || dl_tbf->control_ts != ts)
continue;
@@ -292,7 +296,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
/* store last frame number of RTS */
pdch->last_rts_fn = fn;
- poll_fn = sched_poll(bts, trx, ts, fn, block_nr, &poll_tbf, &ul_ass_tbf,
+ poll_fn = sched_poll(bts->bts, trx, ts, fn, block_nr, &poll_tbf, &ul_ass_tbf,
&dl_ass_tbf, &ul_ack_tbf);
/* check uplink resource for polling */
if (poll_tbf)
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index aa29b4c6..ce9db29a 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -775,19 +775,7 @@ DEFUN(show_tbf,
SHOW_STR "information about TBFs\n" "All TBFs\n")
{
struct gprs_rlcmac_bts *bts = bts_main_data();
- struct llist_head *tbf;
-
- vty_out(vty, "UL TBFs%s", VTY_NEWLINE);
- llist_for_each(tbf, &bts->ul_tbfs) {
- tbf_print_vty_info(vty, tbf);
- }
-
- vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE);
- llist_for_each(tbf, &bts->dl_tbfs) {
- tbf_print_vty_info(vty, tbf);
- }
-
- return CMD_SUCCESS;
+ return pcu_vty_show_tbf_all(vty, bts);
}
DEFUN(show_ms_all,
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index 74780c2c..7082d990 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -39,9 +39,8 @@ int pcu_vty_config_write_pcu_ext(struct vty *vty)
return CMD_SUCCESS;
}
-void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf)
+static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf)
{
- gprs_rlcmac_tbf *tbf = llist_pods_entry(ltbf, gprs_rlcmac_tbf);
vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(),
tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid",
tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL",
@@ -60,6 +59,22 @@ void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf)
VTY_NEWLINE, VTY_NEWLINE);
}
+int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data)
+{
+ BTS *bts = bts_data->bts;
+ LListHead<gprs_rlcmac_tbf> *ms_iter;
+
+ vty_out(vty, "UL TBFs%s", VTY_NEWLINE);
+ llist_for_each(ms_iter, &bts->ul_tbfs())
+ tbf_print_vty_info(vty, ms_iter->entry());
+
+ vty_out(vty, "%sDL TBFs%s", VTY_NEWLINE, VTY_NEWLINE);
+ llist_for_each(ms_iter, &bts->dl_tbfs())
+ tbf_print_vty_info(vty, ms_iter->entry());
+
+ return CMD_SUCCESS;
+}
+
int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data)
{
BTS *bts = bts_data->bts;
diff --git a/src/pcu_vty_functions.h b/src/pcu_vty_functions.h
index 170ad2e2..35acf64c 100644
--- a/src/pcu_vty_functions.h
+++ b/src/pcu_vty_functions.h
@@ -28,14 +28,13 @@ struct vty;
struct gprs_rlcmac_bts;
int pcu_vty_config_write_pcu_ext(struct vty *vty);
+int pcu_vty_show_tbf_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data);
int pcu_vty_show_ms_all(struct vty *vty, struct gprs_rlcmac_bts *bts_data);
int pcu_vty_show_ms_by_tlli(struct vty *vty, struct gprs_rlcmac_bts *bts_data,
uint32_t tlli);
int pcu_vty_show_ms_by_imsi(struct vty *vty, struct gprs_rlcmac_bts *bts_data,
const char *imsi);
-void tbf_print_vty_info(struct vty *vty, struct llist_head *tbf);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/poll_controller.cpp b/src/poll_controller.cpp
index 8108f742..54e3bc76 100644
--- a/src/poll_controller.cpp
+++ b/src/poll_controller.cpp
@@ -30,14 +30,14 @@ PollController::PollController(BTS& bts)
void PollController::expireTimedout(int frame_number, unsigned max_delay)
{
- struct gprs_rlcmac_bts *bts = m_bts.bts_data();
struct gprs_rlcmac_dl_tbf *dl_tbf;
struct gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_sba *sba, *sba2;
- struct llist_pods *lpods;
+ LListHead<gprs_rlcmac_tbf> *pos;
uint32_t elapsed;
- llist_pods_for_each_entry(ul_tbf, &bts->ul_tbfs, list, lpods) {
+ llist_for_each(pos, &m_bts.ul_tbfs()) {
+ ul_tbf = as_ul_tbf(pos->entry());
if (ul_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) {
elapsed = (frame_number + 2715648 - ul_tbf->poll_fn)
% 2715648;
@@ -45,7 +45,8 @@ void PollController::expireTimedout(int frame_number, unsigned max_delay)
ul_tbf->poll_timeout();
}
}
- llist_pods_for_each_entry(dl_tbf, &bts->dl_tbfs, list, lpods) {
+ llist_for_each(pos, &m_bts.dl_tbfs()) {
+ dl_tbf = as_dl_tbf(pos->entry());
if (dl_tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) {
elapsed = (frame_number + 2715648 - dl_tbf->poll_fn)
% 2715648;
diff --git a/src/rlc.h b/src/rlc.h
index c7bb98dc..46d821d3 100644
--- a/src/rlc.h
+++ b/src/rlc.h
@@ -136,11 +136,7 @@ private:
/**
- * TODO: The UL/DL code could/should share a baseclass but
- * we are using llist_for_each_entry for the TBF which
- * requires everything which creates a requirement for a POD
- * type and in < C++11 something that is using even if the
- * most simple form of inheritance is not a POD anymore.
+ * TODO: The UL/DL code could/should share a base class.
*/
struct gprs_rlc_dl_window {
void reset();
diff --git a/src/tbf.cpp b/src/tbf.cpp
index b3d0c0dd..185f0bd7 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -74,12 +74,12 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) :
m_ms(NULL),
m_ta(0),
m_ms_class(0),
+ m_list(this),
m_ms_list(this),
m_egprs_enabled(false)
{
/* The classes of these members do not have proper constructors yet.
* Just set them to 0 like talloc_zero did */
- memset(&list, 0, sizeof(list));
memset(&pdch, 0, sizeof(pdch));
memset(&timer, 0, sizeof(timer));
memset(&m_rlc, 0, sizeof(m_rlc));
@@ -88,9 +88,6 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) :
m_llc.init();
m_name_buf[0] = '\0';
-
- /* Back pointer for PODS llist compatibility */
- list.back = this;
}
gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const
@@ -336,7 +333,7 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf)
tbf->stop_timer();
#warning "TODO: Could/Should generate bssgp_tx_llc_discarded"
tbf_unlink_pdch(tbf);
- llist_del(&tbf->list.list);
+ llist_del(&tbf->list());
if (tbf->direction == GPRS_RLCMAC_UL_TBF)
tbf->bts->tbf_ul_freed();
@@ -633,7 +630,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
return NULL;
}
- llist_add(&tbf->list.list, &bts->ul_tbfs);
+ llist_add(&tbf->list(), &bts->bts->ul_tbfs());
tbf->bts->tbf_ul_created();
return tbf;
@@ -694,7 +691,7 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
return NULL;
}
- llist_add(&tbf->list.list, &bts->dl_tbfs);
+ llist_add(&tbf->list(), &bts->bts->dl_tbfs());
tbf->bts->tbf_dl_created();
tbf->m_last_dl_poll_fn = -1;
@@ -1093,11 +1090,11 @@ const char *gprs_rlcmac_tbf::name() const
void gprs_rlcmac_tbf::rotate_in_list()
{
- llist_del(&list.list);
+ llist_del(&list());
if (direction == GPRS_RLCMAC_UL_TBF)
- llist_add(&list.list, &bts->bts_data()->ul_tbfs);
+ llist_add(&list(), &bts->ul_tbfs());
else
- llist_add(&list.list, &bts->bts_data()->dl_tbfs);
+ llist_add(&list(), &bts->dl_tbfs());
}
uint8_t gprs_rlcmac_tbf::tsc() const
diff --git a/src/tbf.h b/src/tbf.h
index de7063da..8ba65756 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -88,28 +88,6 @@ enum gprs_rlcmac_tbf_direction {
#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7
#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */
-struct llist_pods {
- struct llist_head list;
- void *back;
-};
-
-#define llist_pods_entry(ptr, type) \
- ((type *)(container_of(ptr, struct llist_pods, list)->back))
-
-/**
- * llist_pods_for_each_entry - like llist_for_each_entry, but uses
- * struct llist_pods ->back to access the entry.
- * This is necessary for non-PODS classes because container_of is
- * not guaranteed to work anymore. */
-#define llist_pods_for_each_entry(pos, head, member, lpods) \
- for (lpods = llist_entry((head)->next, typeof(struct llist_pods), list), \
- pos = ((typeof(pos))lpods->back), \
- prefetch(pos->member.list.next); \
- &lpods->list != (head); \
- lpods = llist_entry(lpods->list.next, typeof(struct llist_pods), list), \
- pos = ((typeof(pos))lpods->back),\
- prefetch(pos->member.list.next))
-
struct gprs_rlcmac_tbf {
gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir);
@@ -175,7 +153,9 @@ struct gprs_rlcmac_tbf {
LListHead<gprs_rlcmac_tbf>& ms_list() {return this->m_ms_list;}
const LListHead<gprs_rlcmac_tbf>& ms_list() const {return this->m_ms_list;}
- struct llist_pods list;
+ LListHead<gprs_rlcmac_tbf>& list();
+ const LListHead<gprs_rlcmac_tbf>& list() const;
+
uint32_t state_flags;
enum gprs_rlcmac_tbf_direction direction;
struct gprs_rlcmac_trx *trx;
@@ -251,6 +231,7 @@ protected:
uint8_t m_ms_class;
private:
+ LListHead<gprs_rlcmac_tbf> m_list;
LListHead<gprs_rlcmac_tbf> m_ms_list;
bool m_egprs_enabled;
@@ -302,6 +283,16 @@ inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state)
state = new_state;
}
+inline LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list()
+{
+ return this->m_list;
+}
+
+inline const LListHead<gprs_rlcmac_tbf>& gprs_rlcmac_tbf::list() const
+{
+ return this->m_list;
+}
+
inline GprsMs *gprs_rlcmac_tbf::ms() const
{
return m_ms;