From 0b6b62324f48e025d422567c3163895a15d23ac2 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 24 Feb 2021 09:38:33 +0000 Subject: [PATCH] convert rlc am retx_queue to circular buffer --- lib/include/srslte/upper/rlc_am_lte.h | 52 ++++++++++++++++++++++++--- lib/src/upper/rlc_am_lte.cc | 51 ++++++++++---------------- 2 files changed, 67 insertions(+), 36 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index 244b794de..f4926c7ed 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -170,6 +170,51 @@ private: uint32_t count = 0; }; +class pdu_retx_queue +{ +public: + rlc_amd_retx_t& push() + { + assert(not full()); + rlc_amd_retx_t& p = buffer[wpos]; + wpos = (wpos + 1) % RLC_AM_WINDOW_SIZE; + return p; + } + + void pop() { rpos = (rpos + 1) % RLC_AM_WINDOW_SIZE; } + + rlc_amd_retx_t& front() + { + assert(not empty()); + return buffer[rpos]; + } + + void clear() + { + wpos = 0; + rpos = 0; + } + + bool has_sn(uint32_t sn) const + { + for (size_t i = rpos; i != wpos; i = (i + 1) % RLC_AM_WINDOW_SIZE) { + if (buffer[i].sn == sn) { + return true; + } + } + return false; + } + + size_t size() const { return (wpos >= rpos) ? wpos - rpos : RLC_AM_WINDOW_SIZE + wpos - rpos; } + bool empty() const { return wpos == rpos; } + bool full() const { return size() == RLC_AM_WINDOW_SIZE - 1; } + +private: + std::array buffer; + size_t wpos = 0; + size_t rpos = 0; +}; + class rlc_am_lte : public rlc_common { public: @@ -242,7 +287,6 @@ private: void debug_state(); - bool retx_queue_has_sn(uint32_t sn); int required_buffer_size(rlc_amd_retx_t retx); void retransmit_pdu(); @@ -299,9 +343,9 @@ private: bsr_callback_t bsr_callback; // Tx windows - tx_window_t tx_window; - std::deque retx_queue; - std::vector notify_info_vec; + tx_window_t tx_window; + pdu_retx_queue retx_queue; + std::vector notify_info_vec; // Mutexes pthread_mutex_t mutex; diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index ded5b5d3f..fd298068a 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -172,7 +172,7 @@ rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) : status_prohibit_timer(parent_->timers->get_unique_timer()) { pthread_mutex_init(&mutex, NULL); - notify_info_vec.reserve(300); + notify_info_vec.reserve(RLC_AM_WINDOW_SIZE); } rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx() @@ -305,7 +305,7 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() // Bytes needed for retx if (not retx_queue.empty()) { - rlc_amd_retx_t retx = retx_queue.front(); + rlc_amd_retx_t& retx = retx_queue.front(); logger.debug("%s Buffer state - retx - SN=%d, Segment: %s, %d:%d", RB_NAME, retx.sn, @@ -316,7 +316,7 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() int req_bytes = required_buffer_size(retx); if (req_bytes < 0) { logger.error("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn); - retx_queue.pop_front(); + retx_queue.pop(); } else { n_bytes += req_bytes; logger.debug("Buffer state - retx: %d bytes", n_bytes); @@ -483,12 +483,11 @@ void rlc_am_lte::rlc_am_lte_tx::retransmit_pdu() // select PDU in tx window for retransmission rlc_amd_tx_pdu_t& pdu = tx_window.front(); logger.info("%s Schedule SN=%d for reTx.", RB_NAME, pdu.rlc_sn); - rlc_amd_retx_t retx = {}; - retx.is_segment = false; - retx.so_start = 0; - retx.so_end = pdu.buf->N_bytes; - retx.sn = pdu.rlc_sn; - retx_queue.push_back(retx); + rlc_amd_retx_t& retx = retx_queue.push(); + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = pdu.buf->N_bytes; + retx.sn = pdu.rlc_sn; } } @@ -574,7 +573,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt // Sanity check - drop any retx SNs not present in tx_window while (not tx_window.has_sn(retx.sn)) { - retx_queue.pop_front(); + retx_queue.pop(); if (!retx_queue.empty()) { retx = retx_queue.front(); } else { @@ -587,7 +586,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt int req_size = required_buffer_size(retx); if (req_size < 0) { logger.error("In build_retx_pdu(): Removing retx.sn=%d from queue", retx.sn); - retx_queue.pop_front(); + retx_queue.pop(); return -1; } @@ -620,7 +619,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt rlc_am_write_data_pdu_header(&new_header, &ptr); memcpy(ptr, tx_window[retx.sn].buf->msg, tx_window[retx.sn].buf->N_bytes); - retx_queue.pop_front(); + retx_queue.pop(); tx_window[retx.sn].retx_count++; if (tx_window[retx.sn].retx_count >= cfg.max_retx_thresh) { logger.warning("%s Signaling max number of reTx=%d for for SN=%d", RB_NAME, tx_window[retx.sn].retx_count, retx.sn); @@ -760,13 +759,13 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte // Update retx_queue if (tx_window[retx.sn].buf->N_bytes == retx.so_end) { - retx_queue.pop_front(); + retx_queue.pop(); new_header.lsf = 1; if (rlc_am_end_aligned(old_header.fi)) { new_header.fi &= RLC_FI_FIELD_NOT_START_ALIGNED; // segment is end aligned } } else if (retx_queue.front().so_end == retx.so_end) { - retx_queue.pop_front(); + retx_queue.pop(); } else { retx_queue.front().is_segment = true; retx_queue.front().so_start = retx.so_end; @@ -1030,12 +1029,12 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no update_vt_a = false; if (tx_window.has_sn(i)) { auto& pdu = tx_window[i]; - if (!retx_queue_has_sn(i)) { - rlc_amd_retx_t retx = {}; - retx.sn = i; - retx.is_segment = false; - retx.so_start = 0; - retx.so_end = pdu.buf->N_bytes; + if (!retx_queue.has_sn(i)) { + rlc_amd_retx_t& retx = retx_queue.push(); + retx.sn = i; + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = pdu.buf->N_bytes; if (status.nacks[j].has_so) { // sanity check @@ -1065,7 +1064,6 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no pdu.buf->N_bytes); } } - retx_queue.push_back(retx); } } } @@ -1225,17 +1223,6 @@ int rlc_am_lte::rlc_am_lte_tx::required_buffer_size(rlc_amd_retx_t retx) return rlc_am_packed_length(&new_header) + (retx.so_end - retx.so_start); } -bool rlc_am_lte::rlc_am_lte_tx::retx_queue_has_sn(uint32_t sn) -{ - std::deque::iterator q_it; - for (q_it = retx_queue.begin(); q_it != retx_queue.end(); ++q_it) { - if (q_it->sn == sn) { - return true; - } - } - return false; -} - /**************************************************************************** * Rx subclass implementation ***************************************************************************/