From d2ef5419578f0942ad2e5c277fb5c5871196de40 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 5 Mar 2021 18:45:11 +0000 Subject: [PATCH] Changed the structure to store rx_counts info to std::vector, to reduce memory allocations. Update the rx_count_info queue if the queue size is too large. --- lib/include/srslte/upper/pdcp_entity_lte.h | 9 ++-- lib/src/upper/pdcp_entity_lte.cc | 44 ++++++++++++------- lib/test/upper/pdcp_lte_test_status_report.cc | 12 ++++- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index b1b2f4c9d..81db900d3 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -21,8 +21,6 @@ #include "srslte/interfaces/ue_rrc_interfaces.h" #include "srslte/upper/pdcp_entity_base.h" -#include - namespace srsue { class gw_interface_pdcp; @@ -172,9 +170,10 @@ private: std::unique_ptr undelivered_sdus; // Rx info queue - uint32_t fmc = 0; - std::set rx_counts_info; // Keeps the RX_COUNT for generation of the stauts report - void update_rx_counts_queue(uint32_t rx_count); + uint32_t fmc = 0; + uint32_t largest_rx_count = 0; + std::vector rx_counts_info; // Keeps the RX_COUNT for generation of the stauts report + void update_rx_counts_queue(uint32_t rx_count); /* * Helper function to see if an SN is larger diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 6d9eac2f1..792d6e8bc 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -74,6 +74,7 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, if (is_drb() and not rlc->rb_is_um(lcid)) { undelivered_sdus = std::unique_ptr(new undelivered_sdus_queue(task_sched)); + rx_counts_info.reserve(reordering_window); } // Check supported config @@ -413,16 +414,33 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) void pdcp_entity_lte::update_rx_counts_queue(uint32_t rx_count) { + std::sort(rx_counts_info.begin(), rx_counts_info.end(), std::greater()); + + // Update largest RX_COUNT + if (rx_count > largest_rx_count) { + largest_rx_count = rx_count; + } + // The received COUNT is the first missing COUNT if (rx_count == fmc) { fmc++; - // Update the queue for the Status report bitmap, if NEXT_PDCP_RX_SN changed - while (not rx_counts_info.empty() && *rx_counts_info.begin() == fmc) { - rx_counts_info.erase(fmc); + // Update the queue for the Status report bitmap, if first missing count changed + while (not rx_counts_info.empty() && rx_counts_info.back() == fmc) { + rx_counts_info.pop_back(); fmc++; } } else { - rx_counts_info.insert(rx_count); + rx_counts_info.push_back(rx_count); + } + + // If the size of the rx_vector_info is getting very large + // Consider the FMC as lost and update the vector. + if (rx_counts_info.size() > reordering_window) { + fmc++; + while (not rx_counts_info.empty() && rx_counts_info.back() == fmc) { + rx_counts_info.pop_back(); + fmc++; + } } } /**************************************************************************** @@ -488,23 +506,19 @@ void pdcp_entity_lte::send_status_report() // Add bitmap of missing PDUs, if necessary if (not rx_counts_info.empty()) { // First check size of bitmap - uint32_t lms = *rx_counts_info.rbegin(); - int32_t diff = lms - (fms - 1); + int32_t diff = largest_rx_count - (fmc - 1); uint32_t nof_sns = 1u << cfg.sn_len; - if (diff > (int32_t)(nof_sns / 2)) { - logger.info("FMS and LMS are very far apart. Not generating status report. LMS=%d FMS=%d", lms, fms); - return; - } - if (diff <= 0 && diff > -((int32_t)(nof_sns / 2))) { - logger.info("FMS and LMS are very far apart. Not generating status report. LMS=%d FMS=%d", lms, fms); + if (diff < 0) { + logger.info("FMS and LMS are very far apart. Not generating status report. Largest RX COUNT=%d FMS=%d", + largest_rx_count, + fms); return; } - uint32_t sn_diff = (diff > 0) ? diff : nof_sns + diff; - uint32_t bitmap_sz = std::ceil((float)(sn_diff) / 8); + uint32_t bitmap_sz = std::ceil((float)(diff) / 8); memset(&pdu->msg[pdu->N_bytes], 0, bitmap_sz); logger.debug( "Setting status report bitmap. Last missing SN=%d, Last SN acked in sequence=%d, Bitmap size in bytes=%d", - lms, + largest_rx_count, fms - 1, bitmap_sz); for (uint32_t rx_count : rx_counts_info) { diff --git a/lib/test/upper/pdcp_lte_test_status_report.cc b/lib/test/upper/pdcp_lte_test_status_report.cc index d2509ea4d..7bb1c2c2b 100644 --- a/lib/test/upper/pdcp_lte_test_status_report.cc +++ b/lib/test/upper/pdcp_lte_test_status_report.cc @@ -159,6 +159,10 @@ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, for (uint32_t i = 0; i < 4080; i++) { srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + if (sdu == nullptr or pdu == nullptr) { + logger.error("Could not allocate byte buffer"); + return SRSLTE_ERROR; + } sdu->append_bytes(sdu1, sizeof(sdu1)); pdcp_tx->write_sdu(std::move(sdu)); pdcp_tx->notify_delivery({i}); @@ -187,6 +191,10 @@ int test_tx_wraparound_status_report(const srslte::pdcp_lte_state_t& init_state, for (uint32_t i = 4080; i < 4112; i++) { srslte::unique_byte_buffer_t sdu = srslte::make_byte_buffer(); srslte::unique_byte_buffer_t pdu = srslte::make_byte_buffer(); + if (sdu == nullptr or pdu == nullptr) { + logger.error("Could not allocate byte buffer"); + return SRSLTE_ERROR; + } sdu->append_bytes(sdu1, sizeof(sdu1)); pdcp_tx->write_sdu(std::move(sdu)); if (i != 4080 && i != 4081 && i != 4110 && i != 4111) { @@ -292,8 +300,8 @@ int run_all_tests() logger.set_hex_dump_max_size(128); // This is the normal initial state. All state variables are set to zero - srslte::pdcp_lte_state_t normal_init_state = { - .next_pdcp_tx_sn = 0, .tx_hfn = 0, .rx_hfn = 0, .next_pdcp_rx_sn = 0, .last_submitted_pdcp_rx_sn = 4095}; + srslte::pdcp_lte_state_t normal_init_state = {}; + normal_init_state.last_submitted_pdcp_rx_sn = 4095; TESTASSERT(test_tx_status_report(normal_init_state, logger) == 0); TESTASSERT(test_tx_wraparound_status_report(normal_init_state, logger) == 0);