implementation of pdcp discard timers using a vector for efficiency

master
Francisco 4 years ago committed by Francisco Paisana
parent 40d7934267
commit 82bb0a7d81

@ -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<uint32_t, timer_handler::unique_timer> discard_timers_map;
std::vector<unique_timer> discard_timers;
// TX Queue
uint32_t maximum_allocated_sns_window = 2048;

@ -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<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>& 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<uint32_t, srslte::unique_byte_buffer_t> 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
***************************************************************************/

Loading…
Cancel
Save