mirror of https://github.com/PentHertz/srsLTE.git
Use a reverse lookup to avoid iteration over a std::map (#2363)
* reuse vector capacity for pdcp sn notification * use an extra lookup data structure to find PDCP SNs that an RLC SN contains * fix rlc sn->pdcp sn lookup datastructure in rlc * fix rlc failing test
This commit is contained in:
parent
d947a0bccf
commit
cd8ee37f74
|
@ -134,7 +134,7 @@ private:
|
||||||
int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes);
|
int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes);
|
||||||
int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx);
|
int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx);
|
||||||
int build_data_pdu(uint8_t* payload, uint32_t nof_bytes);
|
int build_data_pdu(uint8_t* payload, uint32_t nof_bytes);
|
||||||
void update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu, std::vector<uint32_t>& notify_info_vec);
|
void update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu);
|
||||||
|
|
||||||
void debug_state();
|
void debug_state();
|
||||||
|
|
||||||
|
@ -189,7 +189,9 @@ private:
|
||||||
srslte::timer_handler::unique_timer status_prohibit_timer;
|
srslte::timer_handler::unique_timer status_prohibit_timer;
|
||||||
|
|
||||||
// SDU info for PDCP notifications
|
// SDU info for PDCP notifications
|
||||||
std::map<uint32_t, pdcp_sdu_info_t> undelivered_sdu_info_queue = {};
|
std::unordered_map<uint32_t, pdcp_sdu_info_t> undelivered_sdu_info_queue;
|
||||||
|
std::unordered_map<uint32_t, std::vector<uint32_t> > rlc_sn_to_pdcp_sn_map;
|
||||||
|
std::vector<uint32_t> notify_info_vec;
|
||||||
|
|
||||||
// Callback function for buffer status report
|
// Callback function for buffer status report
|
||||||
bsr_callback_t bsr_callback;
|
bsr_callback_t bsr_callback;
|
||||||
|
|
|
@ -245,6 +245,7 @@ void rlc_am_lte::rlc_am_lte_tx::stop()
|
||||||
|
|
||||||
// Drop all SDU info in queue
|
// Drop all SDU info in queue
|
||||||
undelivered_sdu_info_queue.clear();
|
undelivered_sdu_info_queue.clear();
|
||||||
|
rlc_sn_to_pdcp_sn_map.clear();
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
}
|
}
|
||||||
|
@ -874,6 +875,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
undelivered_sdu_info_queue.at(tx_sdu->md.pdcp_sn).rlc_sn_info_list.push_back({header.sn, false});
|
undelivered_sdu_info_queue.at(tx_sdu->md.pdcp_sn).rlc_sn_info_list.push_back({header.sn, false});
|
||||||
|
rlc_sn_to_pdcp_sn_map[header.sn].push_back(tx_sdu->md.pdcp_sn);
|
||||||
if (tx_sdu->N_bytes == 0) {
|
if (tx_sdu->N_bytes == 0) {
|
||||||
logger.debug("%s Complete SDU scheduled for tx.", RB_NAME);
|
logger.debug("%s Complete SDU scheduled for tx.", RB_NAME);
|
||||||
undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn].fully_txed = true;
|
undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn].fully_txed = true;
|
||||||
|
@ -920,9 +922,10 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
info_it->second.rlc_sn_info_list.push_back({header.sn, false});
|
info_it->second.rlc_sn_info_list.push_back({header.sn, false});
|
||||||
|
rlc_sn_to_pdcp_sn_map[header.sn].push_back(tx_sdu->md.pdcp_sn);
|
||||||
if (tx_sdu->N_bytes == 0) {
|
if (tx_sdu->N_bytes == 0) {
|
||||||
logger.debug("%s Complete SDU scheduled for tx. PDCP SN=%d", RB_NAME, tx_sdu->md.pdcp_sn);
|
logger.debug("%s Complete SDU scheduled for tx. PDCP SN=%d", RB_NAME, tx_sdu->md.pdcp_sn);
|
||||||
undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn].fully_txed = true;
|
info_it->second.fully_txed = true;
|
||||||
tx_sdu.reset();
|
tx_sdu.reset();
|
||||||
}
|
}
|
||||||
if (pdu_space > to_move) {
|
if (pdu_space > to_move) {
|
||||||
|
@ -1017,7 +1020,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
|
||||||
std::map<uint32_t, rlc_amd_tx_pdu_t>::iterator it;
|
std::map<uint32_t, rlc_amd_tx_pdu_t>::iterator it;
|
||||||
bool update_vt_a = true;
|
bool update_vt_a = true;
|
||||||
uint32_t i = vt_a;
|
uint32_t i = vt_a;
|
||||||
std::vector<uint32_t> notify_info_vec = {};
|
notify_info_vec.clear();
|
||||||
|
|
||||||
while (TX_MOD_BASE(i) < TX_MOD_BASE(status.ack_sn) && TX_MOD_BASE(i) < TX_MOD_BASE(vt_s)) {
|
while (TX_MOD_BASE(i) < TX_MOD_BASE(status.ack_sn) && TX_MOD_BASE(i) < TX_MOD_BASE(vt_s)) {
|
||||||
bool nack = false;
|
bool nack = false;
|
||||||
|
@ -1075,7 +1078,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
|
||||||
if (tx_window.count(i) > 0) {
|
if (tx_window.count(i) > 0) {
|
||||||
it = tx_window.find(i);
|
it = tx_window.find(i);
|
||||||
if (it != tx_window.end()) {
|
if (it != tx_window.end()) {
|
||||||
update_notification_ack_info(it->second, notify_info_vec);
|
update_notification_ack_info(it->second);
|
||||||
if (update_vt_a) {
|
if (update_vt_a) {
|
||||||
tx_window.erase(it);
|
tx_window.erase(it);
|
||||||
vt_a = (vt_a + 1) % MOD;
|
vt_a = (vt_a + 1) % MOD;
|
||||||
|
@ -1110,18 +1113,21 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
|
||||||
* @tx_pdu: RLC PDU that was ack'ed.
|
* @tx_pdu: RLC PDU that was ack'ed.
|
||||||
* @notify_info_vec: Vector which will keep track of the PDCP PDU SNs that have been fully ack'ed.
|
* @notify_info_vec: Vector which will keep track of the PDCP PDU SNs that have been fully ack'ed.
|
||||||
*/
|
*/
|
||||||
void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu,
|
void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pdu_t& tx_pdu)
|
||||||
std::vector<uint32_t>& notify_info_vec)
|
|
||||||
{
|
{
|
||||||
logger.debug("Updating ACK info: RLC SN=%d, number of notified SDU=%ld, number of undelivered SDUs=%ld",
|
logger.debug("Updating ACK info: RLC SN=%d, number of notified SDU=%ld, number of undelivered SDUs=%ld",
|
||||||
tx_pdu.header.sn,
|
tx_pdu.header.sn,
|
||||||
notify_info_vec.size(),
|
notify_info_vec.size(),
|
||||||
undelivered_sdu_info_queue.size());
|
undelivered_sdu_info_queue.size());
|
||||||
// Iterate over all undelivered SDUs
|
// Iterate over all undelivered SDUs
|
||||||
for (auto& info_it : undelivered_sdu_info_queue) {
|
auto it = rlc_sn_to_pdcp_sn_map.find(tx_pdu.header.sn);
|
||||||
|
if (it == rlc_sn_to_pdcp_sn_map.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<uint32_t>& pdcp_sns = it->second;
|
||||||
|
for (uint32_t pdcp_sn : pdcp_sns) {
|
||||||
// Iterate over all SNs that were TX'ed
|
// Iterate over all SNs that were TX'ed
|
||||||
uint32_t pdcp_sn = info_it.first;
|
auto& info = undelivered_sdu_info_queue[pdcp_sn];
|
||||||
auto& info = info_it.second;
|
|
||||||
for (auto& rlc_sn_info : info.rlc_sn_info_list) {
|
for (auto& rlc_sn_info : info.rlc_sn_info_list) {
|
||||||
// Mark this SN as acked, if necessary
|
// Mark this SN as acked, if necessary
|
||||||
if (rlc_sn_info.is_acked == false && rlc_sn_info.sn == tx_pdu.header.sn) {
|
if (rlc_sn_info.is_acked == false && rlc_sn_info.sn == tx_pdu.header.sn) {
|
||||||
|
@ -1139,6 +1145,7 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(const rlc_amd_tx_pd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rlc_sn_to_pdcp_sn_map.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rlc_am_lte::rlc_am_lte_tx::debug_state()
|
void rlc_am_lte::rlc_am_lte_tx::debug_state()
|
||||||
|
|
Loading…
Reference in New Issue