diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-12-28 19:15:40 +0100 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2016-02-01 13:58:13 +0100 |
commit | ed2dbf6954b9883218f5ace1d801c0e316df912a (patch) | |
tree | 1f8a44144bacbad9ca3d7bd947a5a2c8d1cbd726 /src | |
parent | bf49f042d432780fe37c53aed5e4e3f34ac80793 (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.cpp | 31 | ||||
-rw-r--r-- | src/bts.h | 26 | ||||
-rw-r--r-- | src/gprs_rlcmac_sched.cpp | 14 | ||||
-rw-r--r-- | src/pcu_vty.c | 14 | ||||
-rw-r--r-- | src/pcu_vty_functions.cpp | 19 | ||||
-rw-r--r-- | src/pcu_vty_functions.h | 3 | ||||
-rw-r--r-- | src/poll_controller.cpp | 9 | ||||
-rw-r--r-- | src/rlc.h | 6 | ||||
-rw-r--r-- | src/tbf.cpp | 17 | ||||
-rw-r--r-- | src/tbf.h | 37 |
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]) @@ -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; @@ -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 @@ -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; |