diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index d50e2ffe7..ccbf4a67d 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -73,7 +73,7 @@ public: void set_bearer_state(const pdcp_lte_state_t& state) override; // Getter for the number of discard timers. Used for debugging. - uint32_t nof_discard_timers() { return discard_timers_map.size(); } + uint32_t nof_discard_timers() const; // Metrics helpers pdcp_bearer_metrics_t get_metrics() override; @@ -92,7 +92,7 @@ private: // Discard callback (discardTimer) class discard_callback; - std::map discard_timers_map; + std::vector discard_timers; // TX Queue uint32_t maximum_allocated_sns_window = 2048; diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index 9e58cabed..42f3292f4 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -46,6 +46,16 @@ pdcp_entity_lte::pdcp_entity_lte(srsue::rlc_interface_pdcp* rlc_, maximum_pdcp_sn = (1 << cfg.sn_len) - 1; st.last_submitted_pdcp_rx_sn = maximum_pdcp_sn; + uint32_t discard_time_value = static_cast(cfg.discard_timer); + if (discard_time_value > 0) { + discard_timers.reserve(maximum_pdcp_sn + 2); // the last SN is for status report + for (uint32_t sn = 0; sn < discard_timers.size(); ++sn) { + discard_timers.emplace_back(task_sched.get_unique_timer()); + discard_callback discard_fnc(this, sn); + discard_timers[sn].set(discard_time_value, discard_fnc); + } + } + // Queue Helpers maximum_allocated_sns_window = (1 << cfg.sn_len) / 2; @@ -144,12 +154,9 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) } // Start discard timer - if (cfg.discard_timer != pdcp_discard_timer_t::infinity) { - timer_handler::unique_timer discard_timer = task_sched.get_unique_timer(); - discard_callback discard_fnc(this, used_sn); - discard_timer.set(static_cast(cfg.discard_timer), discard_fnc); - discard_timer.run(); - discard_timers_map.insert(std::make_pair(used_sn, std::move(discard_timer))); + if (cfg.discard_timer != pdcp_discard_timer_t::infinity and not discard_timers.empty()) { + uint32_t sn_idx = std::min(used_sn, (uint32_t)(discard_timers.size() - 1)); + discard_timers[sn_idx].run(); logger.debug("Discard Timer set for SN %u. Timeout: %ums", used_sn, static_cast(cfg.discard_timer)); } } @@ -531,7 +538,10 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu) // Remove all SDUs with SN smaller than FMS for (auto it = undelivered_sdus_queue.begin(); it != undelivered_sdus_queue.end();) { if (it->first < fms) { - discard_timers_map.erase(it->first); + if (not discard_timers.empty()) { + uint32_t sn = std::min(it->first, (uint32_t)(discard_timers.size() - 1)); + discard_timers[sn].stop(); + } it = undelivered_sdus_queue.erase(it); } else { ++it; @@ -553,7 +563,10 @@ void pdcp_entity_lte::handle_status_report_pdu(unique_byte_buffer_t pdu) for (uint32_t sn : acked_sns) { logger.debug("Status report ACKed SN=%d.", sn); undelivered_sdus_queue.erase(sn); - discard_timers_map.erase(sn); + if (not discard_timers.empty()) { + uint32_t sn_idx = std::min(sn, (uint32_t)(discard_timers.size() - 1)); + discard_timers[sn_idx].stop(); + } } } /**************************************************************************** @@ -629,7 +642,8 @@ void pdcp_entity_lte::discard_callback::operator()(uint32_t timer_id) // Remove timer from map // NOTE: this will delete the callback. It *must* be the last instruction. - parent->discard_timers_map.erase(discard_sn); + uint32_t sn_idx = std::min(discard_sn, (uint32_t)(parent->discard_timers.size() - 1)); + parent->discard_timers[sn_idx].stop(); } /**************************************************************************** @@ -657,7 +671,10 @@ void pdcp_entity_lte::notify_delivery(const std::vector& pdcp_sns) // If ACK'ed bytes are equal to (or exceed) PDU size, remove PDU and disarm timer. undelivered_sdus_queue.erase(sn); - discard_timers_map.erase(sn); + if (not discard_timers.empty()) { + uint32_t sn_idx = std::min(sn, (uint32_t)(discard_timers.size() - 1)); + discard_timers[sn].stop(); + } } } @@ -714,6 +731,12 @@ std::map pdcp_entity_lte::get_buffered_p return cpy; } +uint32_t pdcp_entity_lte::nof_discard_timers() const +{ + return std::count_if( + discard_timers.begin(), discard_timers.end(), [](const unique_timer& t) { return t.is_running(); }); +} + /**************************************************************************** * Metrics helpers ***************************************************************************/