From 1ede82bb307f8ed8b2b7e4447061054f3ed9c76a Mon Sep 17 00:00:00 2001 From: Francisco Date: Mon, 22 Feb 2021 18:45:52 +0000 Subject: [PATCH] use circular array for buffered PDCP SNs in RLC AM to limit memory allocations --- lib/include/srslte/upper/rlc_am_lte.h | 26 +++++++++++++++++--------- lib/src/upper/rlc_am_lte.cc | 8 +++++--- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lib/include/srslte/upper/rlc_am_lte.h b/lib/include/srslte/upper/rlc_am_lte.h index c5c6176eb..e8536f42a 100644 --- a/lib/include/srslte/upper/rlc_am_lte.h +++ b/lib/include/srslte/upper/rlc_am_lte.h @@ -129,33 +129,41 @@ public: void add_pdcp_sdu(uint32_t sn) { assert(not has_pdcp_sn(sn)); - uint32_t sn_idx = get_idx(sn); - buffered_pdus[sn_idx].sn = sn_idx; + buffered_pdus[get_idx(sn)].sn = sn; count++; } void clear_pdcp_sdu(uint32_t sn) { uint32_t sn_idx = get_idx(sn); buffered_pdus[sn_idx].rlc_sn_info_list.clear(); - buffered_pdus[sn_idx].sn = -1; + buffered_pdus[sn_idx].sn = invalid_sn; count--; } pdcp_sdu_info_t& operator[](uint32_t sn) { assert(has_pdcp_sn(sn)); - uint32_t sn_idx = get_idx(sn); - return buffered_pdus[sn_idx]; + return buffered_pdus[get_idx(sn)]; + } + bool has_pdcp_sn(uint32_t pdcp_sn) const + { + assert(pdcp_sn <= max_pdcp_sn or pdcp_sn == status_report_sn); + return buffered_pdus[get_idx(pdcp_sn)].sn == pdcp_sn; } - bool has_pdcp_sn(uint32_t pdcp_sn) const { return buffered_pdus[get_idx(pdcp_sn)].sn < max_pdcp_sn; } uint32_t nof_sdus() const { return count; } private: - // TODO: Set size based on PDCP config - const static size_t max_pdcp_sn = 262143; + const static size_t max_pdcp_sn = 262143u; + const static size_t max_buffer_idx = 4096u; + const static uint32_t status_report_sn = std::numeric_limits::max(); + const static uint32_t invalid_sn = std::numeric_limits::max() - 1; - uint32_t get_idx(uint32_t sn) const { return std::min(sn, static_cast(buffered_pdus.size() - 1)); } + size_t get_idx(uint32_t sn) const + { + return (sn != status_report_sn) ? static_cast(sn % max_buffer_idx) : max_buffer_idx; + } + // size equal to buffer_size + 1 (last element for Status Report) std::vector buffered_pdus; uint32_t count = 0; }; diff --git a/lib/src/upper/rlc_am_lte.cc b/lib/src/upper/rlc_am_lte.cc index a2a9d8865..397f9b0c4 100644 --- a/lib/src/upper/rlc_am_lte.cc +++ b/lib/src/upper/rlc_am_lte.cc @@ -2013,10 +2013,12 @@ void rlc_am_lte::rlc_am_lte_rx::debug_state() logger.debug("%s vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d", RB_NAME, vr_r, vr_mr, vr_x, vr_ms, vr_h); } -buffered_pdcp_pdu_list::buffered_pdcp_pdu_list() : buffered_pdus(max_pdcp_sn + 2) +const size_t buffered_pdcp_pdu_list::max_buffer_idx; + +buffered_pdcp_pdu_list::buffered_pdcp_pdu_list() : buffered_pdus(max_buffer_idx + 1) { for (size_t i = 0; i < buffered_pdus.size(); ++i) { - buffered_pdus[i].sn = -1; + buffered_pdus[i].sn = invalid_sn; buffered_pdus[i].rlc_sn_info_list.reserve(5); } } @@ -2024,7 +2026,7 @@ buffered_pdcp_pdu_list::buffered_pdcp_pdu_list() : buffered_pdus(max_pdcp_sn + 2 void buffered_pdcp_pdu_list::clear() { for (auto& b : buffered_pdus) { - b.sn = -1; + b.sn = invalid_sn; b.rlc_sn_info_list.clear(); } }