diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index f8e9b7b9f..3dde41198 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -15,6 +15,7 @@ #include "mac_metrics.h" #include "srslte/common/block_queue.h" +#include "srslte/adt/circular_array.h" #include "srslte/common/log.h" #include "srslte/common/mac_pcap.h" #include "srslte/interfaces/enb_interfaces.h" @@ -71,10 +72,10 @@ public: srslte_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti); bool process_pdus(); - uint8_t* request_buffer(const uint32_t len); + uint8_t* request_buffer(uint32_t tti, const uint32_t len); void process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel) override; - void push_pdu(const uint8_t* pdu_ptr, uint32_t len); - void deallocate_pdu(const uint8_t* pdu_ptr); + void push_pdu(uint32_t tti, const uint8_t* pdu_ptr, uint32_t len); + void deallocate_pdu(uint32_t tti, const uint8_t* pdu_ptr); void metrics_read(mac_ue_metrics_t* metrics_); void metrics_rx(bool crc, uint32_t tbs); @@ -122,6 +123,9 @@ private: std::vector, SRSLTE_FDD_NOF_HARQ> > tx_payload_buffer; + // Save 2 buffers per HARQ process + srslte::circular_array rx_used_buffers; + srslte::block_queue pending_ta_commands; ta ta_fsm; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 2b7abc3b4..0d7cd86cb 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -334,11 +334,11 @@ int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32 // push the pdu through the queue if received correctly if (crc) { Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); - ue_db[rnti]->push_pdu(pdu_ptr, nof_bytes); + ue_db[rnti]->push_pdu(tti_rx, pdu_ptr, nof_bytes); stack_task_queue.push([this]() { process_pdus(); }); } else { Debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); - ue_db[rnti]->deallocate_pdu(pdu_ptr); + ue_db[rnti]->deallocate_pdu(tti_rx, pdu_ptr); } return SRSLTE_SUCCESS; } @@ -906,7 +906,7 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) if (sched_result.pusch[n].current_tx_nb == 0) { srslte_softbuffer_rx_reset_tbs(phy_ul_sched_res->pusch[n].softbuffer_rx, sched_result.pusch[i].tbs * 8); } - phy_ul_sched_res->pusch[n].data = ue_db[rnti]->request_buffer(sched_result.pusch[i].tbs); + phy_ul_sched_res->pusch[n].data = ue_db[rnti]->request_buffer(tti_tx_ul, sched_result.pusch[i].tbs); if (phy_ul_sched_res->pusch[n].data) { phy_ul_sched_res->nof_grants++; } else { diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index d0e99c2a9..ef1b32041 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -161,14 +161,27 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con return &softbuffer_tx.at(ue_cc_idx).at((harq_process * SRSLTE_MAX_TB + tb_idx) % nof_tx_harq_proc); } -uint8_t* ue::request_buffer(const uint32_t len) +uint8_t* ue::request_buffer(uint32_t tti, const uint32_t len) { + uint8_t* pdu = nullptr; if (len > 0) { - return pdus.request(len); + pdu = pdus.request(len); + if (pdu) { + // Deallocate oldest buffer if we didn't deallocate it + if (rx_used_buffers[tti] != nullptr) { + pdus.deallocate(rx_used_buffers[tti]); + rx_used_buffers[tti] = nullptr; + log_h->warning("buffers: RX PDU of rnti=0x%x and pid=%d wasn't deallocated\n", rnti, tti % nof_rx_harq_proc); + } + rx_used_buffers[tti] = pdu; + log_h->info("RX PDU saved for pid=%d\n", tti % nof_rx_harq_proc); + } else { + log_h->error("buffers: Requesting buffer from pool\n"); + } } else { - log_h->warning("Requesting buffer for zero bytes\n"); - return nullptr; + printf("buffers: Requesting buffer for zero bytes\n"); } + return pdu; } bool ue::process_pdus() @@ -293,18 +306,28 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe Debug("MAC PDU processed\n"); } -void ue::deallocate_pdu(const uint8_t* pdu_ptr) +void ue::deallocate_pdu(uint32_t tti, const uint8_t* pdu_ptr) { if (pdu_ptr) { + if (rx_used_buffers[tti] == pdu_ptr) { + rx_used_buffers[tti] = nullptr; + } else { + Warning("buffers: Unexpected RX PDU pointer in deallocate_pdu for rnti=0x%x pid=%d\n", rnti, tti % nof_rx_harq_proc); + } pdus.deallocate(pdu_ptr); } else { Error("Error deallocating PDU: null ptr\n"); } } -void ue::push_pdu(const uint8_t* pdu_ptr, uint32_t len) +void ue::push_pdu(uint32_t tti, const uint8_t* pdu_ptr, uint32_t len) { if (pdu_ptr && len > 0) { + if (rx_used_buffers[tti] == pdu_ptr) { + rx_used_buffers[tti] = nullptr; + } else { + Warning("buffers: Unexpected RX PDU pointer in push_pdu for rnti=0x%x pid=%d\n", rnti, tti % nof_rx_harq_proc); + } pdus.push(pdu_ptr, len); } else { Error("Error pushing PDU: ptr=%p, len=%d\n", pdu_ptr, len);