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
This commit is contained in:
Jacob Erlbeck 2015-12-23 16:29:07 +01:00
parent 2b3121eebf
commit 93c55d04e5
5 changed files with 39 additions and 29 deletions

View File

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

View File

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

View File

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

View File

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

View File

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