From 93c55d04e5917aa54ce37a9e997d0af87cc8be85 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Wed, 23 Dec 2015 16:29:07 +0100 Subject: [PATCH] rlc: Add and use mod_sns(bsn) method Currently there is only a mod_sns() method which is being used in expression like bsn_expr & win.mod_sns(). This only works, because it is known that mod_sns() is (sns() - 1) where sns() in turn is always 2^n. This is error prone, hard to read, and relies on window specifics that should be kept inside the respective module. This commit adds a mod_sns(uint bsn) method to gprs_rlc_ul_window and gprs_rlc_dl_window, that encapsulates and hides this optimized computation. Sponsored-by: On-Waves ehf --- src/encoding.cpp | 2 +- src/rlc.cpp | 22 +++++++++++----------- src/rlc.h | 20 ++++++++++++++++---- src/tbf_dl.cpp | 15 +++++++-------- src/tbf_ul.cpp | 9 ++++----- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/encoding.cpp b/src/encoding.cpp index d05177fb..6d66a725 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -441,7 +441,7 @@ static void write_packet_uplink_ack_egprs(struct gprs_rlcmac_bts *bts, int bow = 1; int eow = 1; - int ssn = (tbf->m_window.v_q() + 1) & tbf->m_window.mod_sns(); + int ssn = tbf->m_window.mod_sns(tbf->m_window.v_q() + 1); tbf->m_window.update_rbb(rbb); diff --git a/src/rlc.cpp b/src/rlc.cpp index 227fa362..c7336670 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -57,7 +57,7 @@ void gprs_rlc_dl_window::reset() int gprs_rlc_dl_window::resend_needed() { - for (uint16_t bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) { + for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { if (m_v_b.is_nacked(bsn) || m_v_b.is_resend(bsn)) return bsn; } @@ -69,7 +69,7 @@ int gprs_rlc_dl_window::mark_for_resend() { int resend = 0; - for (uint16_t bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) { + for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { if (m_v_b.is_unacked(bsn)) { /* mark to be re-send */ m_v_b.mark_resend(bsn); @@ -85,7 +85,7 @@ int gprs_rlc_dl_window::count_unacked() uint16_t unacked = 0; uint16_t bsn; - for (bsn = v_a(); bsn != v_s(); bsn = (bsn + 1) & mod_sns()) { + for (bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { if (!m_v_b.is_acked(bsn)) unacked += 1; } @@ -93,9 +93,9 @@ int gprs_rlc_dl_window::count_unacked() return unacked; } -static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns) +static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) { - return (ssn - 1 - bitnum) & mod_sns; + return (ssn - 1 - bitnum); } void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint8_t ssn, @@ -103,9 +103,9 @@ void gprs_rlc_dl_window::update(BTS *bts, char *show_rbb, uint8_t ssn, { /* SSN - 1 is in range V(A)..V(S)-1 */ for (int bitpos = 0; bitpos < ws(); bitpos++) { - uint16_t bsn = bitnum_to_bsn(bitpos, ssn, mod_sns()); + uint16_t bsn = mod_sns(bitnum_to_bsn(bitpos, ssn)); - if (bsn == ((v_a() - 1) & mod_sns())) + if (bsn == mod_sns(v_a() - 1)) break; if (show_rbb[ws() - 1 - bitpos] == 'R') { @@ -128,7 +128,7 @@ int gprs_rlc_dl_window::move_window() uint16_t bsn; int moved = 0; - for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = (bsn + 1) & mod_sns()) { + for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = mod_sns(bsn + 1)) { if (m_v_b.is_acked(bsn)) { m_v_b.mark_invalid(bsn); moved += 1; @@ -144,7 +144,7 @@ void gprs_rlc_dl_window::show_state(char *show_v_b) int i; uint16_t bsn; - for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = (bsn + 1) & mod_sns()) { + for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = mod_sns(bsn + 1)) { uint16_t index = bsn & mod_sns_half(); switch(m_v_b.get_state(index)) { case GPRS_RLC_DL_BSN_INVALID: @@ -188,7 +188,7 @@ void gprs_rlc_ul_window::update_rbb(char *rbb) void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn) { uint16_t offset_v_r; - offset_v_r = (bsn + 1 - v_r()) & mod_sns(); + offset_v_r = mod_sns(bsn + 1 - v_r()); /* Positive offset, so raise. */ if (offset_v_r < (sns() >> 1)) { while (offset_v_r--) { @@ -212,7 +212,7 @@ uint16_t gprs_rlc_ul_window::raise_v_q() if (!m_v_n.is_received(v_q())) break; LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising " - "V(Q) to %d\n", v_q(), (v_q() + 1) & mod_sns()); + "V(Q) to %d\n", v_q(), mod_sns(v_q() + 1)); raise_v_q(1); count += 1; } diff --git a/src/rlc.h b/src/rlc.h index f2acb98a..4905aa1f 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -140,6 +140,7 @@ private: struct gprs_rlc_dl_window { void reset(); const uint16_t mod_sns() const; + const uint16_t mod_sns(uint16_t bsn) const; const uint16_t sns() const; const uint16_t ws() const; @@ -186,6 +187,7 @@ private: struct gprs_rlc_ul_window { const uint16_t mod_sns() const; + const uint16_t mod_sns(uint16_t bsn) const; const uint16_t sns() const; const uint16_t ws() const; @@ -353,6 +355,11 @@ inline const uint16_t gprs_rlc_dl_window::mod_sns() const return sns() - 1; } +inline const uint16_t gprs_rlc_dl_window::mod_sns(uint16_t bsn) const +{ + return bsn & mod_sns(); +} + inline const uint16_t gprs_rlc_dl_window::v_s() const { return m_v_s; @@ -360,7 +367,7 @@ inline const uint16_t gprs_rlc_dl_window::v_s() const inline const uint16_t gprs_rlc_dl_window::v_s_mod(int offset) const { - return (m_v_s + offset) & mod_sns(); + return mod_sns(m_v_s + offset); } inline const uint16_t gprs_rlc_dl_window::v_a() const @@ -370,7 +377,7 @@ inline const uint16_t gprs_rlc_dl_window::v_a() const inline bool gprs_rlc_dl_window::window_stalled() const { - return ((m_v_s - m_v_a) & mod_sns()) == ws(); + return (mod_sns(m_v_s - m_v_a)) == ws(); } inline bool gprs_rlc_dl_window::window_empty() const @@ -428,6 +435,11 @@ inline const uint16_t gprs_rlc_ul_window::mod_sns() const return sns() - 1; } +inline const uint16_t gprs_rlc_ul_window::mod_sns(uint16_t bsn) const +{ + return bsn & mod_sns(); +} + inline const uint16_t gprs_rlc_ul_window::v_r() const { return m_v_r; @@ -445,12 +457,12 @@ inline const uint16_t gprs_rlc_ul_window::ssn() const inline void gprs_rlc_ul_window::raise_v_r_to(int moves) { - m_v_r = (m_v_r + moves) & mod_sns(); + m_v_r = mod_sns(m_v_r + moves); } inline void gprs_rlc_ul_window::raise_v_q(int incr) { - m_v_q = (m_v_q + incr) & mod_sns(); + m_v_q = mod_sns(m_v_q + incr); } inline void gprs_rlc_v_n::mark_received(int bsn) diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 70194f7c..8bac99f3 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -703,9 +703,9 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( return dl_msg; } -static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns) +static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) { - return (ssn - 1 - bitnum) & mod_sns; + return ssn - 1 - bitnum; } int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, @@ -724,9 +724,9 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn, for (int bitpos = 0; bitpos < m_window.ws(); bitpos++) { bool is_received = show_rbb[m_window.ws() - 1 - bitpos] == 'R'; - bsn = bitnum_to_bsn(bitpos, ssn, m_window.mod_sns()); + bsn = m_window.mod_sns(bitnum_to_bsn(bitpos, ssn)); - if (bsn == ((m_window.v_a() - 1) & m_window.mod_sns())) { + if (bsn == m_window.mod_sns(m_window.v_a() - 1)) { info[bitpos] = '$'; break; } @@ -794,19 +794,18 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb) uint16_t lost = 0, received = 0; char show_rbb[65]; char show_v_b[RLC_MAX_SNS + 1]; - const uint16_t mod_sns = m_window.mod_sns(); int error_rate; struct ana_result ana_res; Decoding::extract_rbb(rbb, show_rbb); /* show received array in debug (bit 64..1) */ LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" - "(BSN=%d) R=ACK I=NACK\n", (ssn - 64) & mod_sns, - show_rbb, (ssn - 1) & mod_sns); + "(BSN=%d) R=ACK I=NACK\n", m_window.mod_sns(ssn - 64), + show_rbb, m_window.mod_sns(ssn - 1)); /* apply received array to receive state (SSN-64..SSN-1) */ /* calculate distance of ssn from V(S) */ - dist = (m_window.v_s() - ssn) & mod_sns; + dist = m_window.mod_sns(m_window.v_s() - ssn); /* check if distance is less than distance V(A)..V(S) */ if (dist >= m_window.distance()) { /* this might happpen, if the downlink assignment diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 271f87aa..cde361f9 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -145,7 +145,6 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( { int8_t rssi = meas->have_rssi ? meas->rssi : 0; - const uint16_t mod_sns = m_window.mod_sns(); const uint16_t ws = m_window.ws(); this->state_flags |= (1 << GPRS_RLCMAC_FLAG_UL_DATA); @@ -194,7 +193,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d out of window " "%d..%d (it's normal)\n", rdbi->bsn, m_window.v_q(), - (m_window.v_q() + ws - 1) & mod_sns); + m_window.mod_sns(m_window.v_q() + ws - 1)); } else if (m_window.is_received(rdbi->bsn)) { LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d already received\n", rdbi->bsn); @@ -219,7 +218,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d storing in window (%d..%d)\n", rdbi->bsn, m_window.v_q(), - (m_window.v_q() + ws - 1) & mod_sns); + m_window.mod_sns(m_window.v_q() + ws - 1)); block = m_rlc.block(rdbi->bsn); block->block_info = *rdbi; block->cs = rlc->cs; @@ -296,7 +295,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( /* Retrieve LLC frames from blocks that are ready */ for (uint16_t i = 0; i < count; ++i) { - uint16_t index = (v_q_beg + i) & mod_sns; + uint16_t index = m_window.mod_sns(v_q_beg + i); assemble_forward_llc(m_rlc.block(index)); } @@ -304,7 +303,7 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( if (this->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */ && this->m_window.v_q() == this->m_window.v_r()) { /* if complete */ struct gprs_rlc_data *block = - m_rlc.block((m_window.v_r() - 1) & mod_sns); + m_rlc.block(m_window.mod_sns(m_window.v_r() - 1)); const struct gprs_rlc_ul_data_block_info *rdbi = &block->block_info;