diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index 6512d76a7..f032cd6b3 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -375,6 +375,7 @@ private: bool has_data(); uint32_t get_buffer_state(); + void get_buffer_state(uint32_t& new_tx, uint32_t& prio_tx); // Timeout callback interface void timer_expired(uint32_t timeout_id); diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index 3638c04b1..133b5ff1a 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -436,9 +436,18 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() { + uint32_t newtx = 0, priotx = 0; + get_buffer_state(newtx, priotx); + return newtx + priotx; +} + +void rlc_am_lte::rlc_am_lte_tx::get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) +{ + n_bytes_newtx = 0; + n_bytes_prio = 0; + uint32_t n_sdus = 0; + std::lock_guard lock(mutex); - uint32_t n_bytes = 0; - uint32_t n_sdus = 0; logger.debug("%s Buffer state - do_status=%s, status_prohibit_running=%s (%d/%d)", RB_NAME, @@ -449,8 +458,8 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() // Bytes needed for status report if (do_status() && not status_prohibit_timer.is_running()) { - n_bytes += parent->rx.get_status_pdu_length(); - logger.debug("%s Buffer state - total status report: %d bytes", RB_NAME, n_bytes); + n_bytes_prio += parent->rx.get_status_pdu_length(); + logger.debug("%s Buffer state - total status report: %d bytes", RB_NAME, n_bytes_prio); } // Bytes needed for retx @@ -468,8 +477,8 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() logger.error("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn); retx_queue.pop(); } else { - n_bytes += req_bytes; - logger.debug("Buffer state - retx: %d bytes", n_bytes); + n_bytes_prio += req_bytes; + logger.debug("Buffer state - retx: %d bytes", n_bytes_prio); } } } @@ -477,25 +486,23 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() // Bytes needed for tx SDUs if (tx_window.size() < 1024) { n_sdus = tx_sdu_queue.get_n_sdus(); - n_bytes += tx_sdu_queue.size_bytes(); + n_bytes_newtx += tx_sdu_queue.size_bytes(); if (tx_sdu != NULL) { n_sdus++; - n_bytes += tx_sdu->N_bytes; + n_bytes_newtx += tx_sdu->N_bytes; } } // Room needed for header extensions? (integer rounding) if (n_sdus > 1) { - n_bytes += ((n_sdus - 1) * 1.5) + 0.5; + n_bytes_newtx += ((n_sdus - 1) * 1.5) + 0.5; } // Room needed for fixed header of data PDUs - if (n_bytes > 0 && n_sdus > 0) { - n_bytes += 2; // Two bytes for fixed header with SN length = 10 - logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes); + if (n_bytes_newtx > 0 && n_sdus > 0) { + n_bytes_newtx += 2; // Two bytes for fixed header with SN length = 10 + logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes_newtx); } - - return n_bytes; } int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) @@ -613,7 +620,9 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) lock.unlock(); if (bsr_callback) { - bsr_callback(parent->lcid, get_buffer_state(), 0); + uint32_t newtx = 0, priotx = 0; + get_buffer_state(newtx, priotx); + bsr_callback(parent->lcid, newtx, priotx); } } diff --git a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h index 3e9e828f0..14261ba43 100644 --- a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h +++ b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h @@ -43,7 +43,7 @@ public: // Buffer Status update void ul_bsr(uint32_t lcg_id, uint32_t val); - void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue); + void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue); // Configuration getters bool is_bearer_active(uint32_t lcid) const { return get_cfg(lcid).is_active(); } @@ -58,13 +58,13 @@ public: /// DL newtx buffer status for given LCID (no RLC overhead included) int get_dl_tx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_tx : 0; } - /// DL retx buffer status for given LCID (no RLC overhead included) - int get_dl_retx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_retx : 0; } + /// DL high prio tx buffer status for given LCID (no RLC overhead included) + int get_dl_prio_tx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_prio_tx : 0; } - /// Sum of DL RLC newtx and retx buffer status for given LCID (no RLC overhead included) - int get_dl_tx_total(uint32_t lcid) const { return get_dl_tx(lcid) + get_dl_retx(lcid); } + /// Sum of DL RLC newtx and high prio tx buffer status for given LCID (no RLC overhead included) + int get_dl_tx_total(uint32_t lcid) const { return get_dl_tx(lcid) + get_dl_prio_tx(lcid); } - /// Sum of DL RLC newtx and retx buffer status for all LCIDS + /// Sum of DL RLC newtx and high prio buffer status for all LCIDS int get_dl_tx_total() const; // UL BSR methods @@ -82,7 +82,7 @@ protected: struct logical_channel { mac_lc_ch_cfg_t cfg; int buf_tx = 0; - int buf_retx = 0; + int buf_prio_tx = 0; int Bj = 0; int bucket_size = 0; }; diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index 36fa3f8a6..4e0ab9c68 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -53,7 +53,7 @@ public: uint32_t get_ul_buffer(uint16_t rnti) final; uint32_t get_dl_buffer(uint16_t rnti) final; - int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) final; + int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t prio_tx_queue) final; int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code, uint32_t nof_cmds = 1) final; int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) final; diff --git a/srsenb/hdr/stack/mac/sched_interface.h b/srsenb/hdr/stack/mac/sched_interface.h index 0401deee4..7e40e0a9a 100644 --- a/srsenb/hdr/stack/mac/sched_interface.h +++ b/srsenb/hdr/stack/mac/sched_interface.h @@ -46,30 +46,30 @@ public: } cell_cfg_sib_t; struct sched_args_t { - std::string sched_policy = "time_pf"; - std::string sched_policy_args = "2"; - int pdsch_mcs = -1; - int pdsch_max_mcs = 28; - int pusch_mcs = -1; - int pusch_max_mcs = 28; - uint32_t min_nof_ctrl_symbols = 1; - uint32_t max_nof_ctrl_symbols = 3; - int min_aggr_level = 0; - int max_aggr_level = 3; - bool adaptive_aggr_level = false; - bool pucch_mux_enabled = false; - int pucch_harq_max_rb = 0; - float target_bler = 0.05; - float max_delta_dl_cqi = 5; - float max_delta_ul_snr = 5; + std::string sched_policy = "time_pf"; + std::string sched_policy_args = "2"; + int pdsch_mcs = -1; + int pdsch_max_mcs = 28; + int pusch_mcs = -1; + int pusch_max_mcs = 28; + uint32_t min_nof_ctrl_symbols = 1; + uint32_t max_nof_ctrl_symbols = 3; + int min_aggr_level = 0; + int max_aggr_level = 3; + bool adaptive_aggr_level = false; + bool pucch_mux_enabled = false; + int pucch_harq_max_rb = 0; + float target_bler = 0.05; + float max_delta_dl_cqi = 5; + float max_delta_ul_snr = 5; float adaptive_dl_mcs_step_size = 0.001; float adaptive_ul_mcs_step_size = 0.001; - uint32_t min_tpc_tti_interval = 1; - float ul_snr_avg_alpha = 0.05; - int init_ul_snr_value = 5; - int init_dl_cqi = 5; - float max_sib_coderate = 0.8; - int pdcch_cqi_offset = 0; + uint32_t min_tpc_tti_interval = 1; + float ul_snr_avg_alpha = 0.05; + int init_ul_snr_value = 5; + int init_dl_cqi = 5; + float max_sib_coderate = 0.8; + int pdcch_cqi_offset = 0; }; struct cell_cfg_t { @@ -267,10 +267,10 @@ public: * @param rnti user rnti * @param lc_id logical channel id for which the buffer update is concerned * @param tx_queue number of pending bytes for new DL RLC transmissions - * @param retx_queue number of pending bytes concerning RLC retransmissions + * @param prio_tx_queue number of pending bytes concerning RLC retransmissions and status PDUs * @return error code */ - virtual int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0; + virtual int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t prio_tx_queue) = 0; /** * Enqueue MAC CEs for DL transmission diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h index c4ce54b77..0892bf8d9 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -35,7 +35,7 @@ public: using base_type::dl_buffer_state; using base_type::get_bsr; using base_type::get_bsr_state; - using base_type::get_dl_retx; + using base_type::get_dl_prio_tx; using base_type::get_dl_tx; using base_type::get_dl_tx_total; using base_type::is_bearer_active; @@ -51,7 +51,7 @@ public: bool has_pending_dl_txs() const; int get_dl_tx_total_with_overhead(uint32_t lcid) const; int get_dl_tx_with_overhead(uint32_t lcid) const; - int get_dl_retx_with_overhead(uint32_t lcid) const; + int get_dl_prio_tx_with_overhead(uint32_t lcid) const; int get_bsr_with_overhead(uint32_t lcid) const; int get_max_prio_lcid() const; @@ -61,7 +61,7 @@ public: srsran::deque pending_ces; private: - int alloc_retx_bytes(uint8_t lcid, int rem_bytes); + int alloc_prio_tx_bytes(uint8_t lcid, int rem_bytes); int alloc_tx_bytes(uint8_t lcid, int rem_bytes); size_t prio_idx = 0; diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index c0a2cdcae..9bf260230 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -112,20 +112,20 @@ void ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val) } template -void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue) +void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue) { if (not is_lcid_valid(lcid)) { logger.warning("The provided lcid=%d is not valid", lcid); return; } if (lcid <= MAX_SRB_LC_ID and - (channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_retx != (int)retx_queue)) { - logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue); + (channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_prio_tx != (int)prio_tx_queue)) { + logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, prio_tx_queue); } else { - logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue); + logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, prio_tx_queue); } - channels[lcid].buf_retx = retx_queue; - channels[lcid].buf_tx = tx_queue; + channels[lcid].buf_prio_tx = prio_tx_queue; + channels[lcid].buf_tx = tx_queue; } // Explicit instantiation diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index f01a209fe..d836fdbd2 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -165,9 +165,9 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) return ret; } -int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) +int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t prio_tx_queue) { - return ue_db_access_locked(rnti, [&](sched_ue& ue) { ue.dl_buffer_state(lc_id, tx_queue, retx_queue); }); + return ue_db_access_locked(rnti, [&](sched_ue& ue) { ue.dl_buffer_state(lc_id, tx_queue, prio_tx_queue); }); } int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code, uint32_t nof_cmds) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index 3bd85f603..be2f492fe 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -94,9 +94,9 @@ int lch_ue_manager::get_max_prio_lcid() const { int min_prio_val = std::numeric_limits::max(), prio_lcid = -1; - // Prioritize retxs + // Prioritized Txs first (e.g. Retxs, status PDUs) for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) { - if (get_dl_retx(lcid) > 0 and channels[lcid].cfg.priority < min_prio_val) { + if (get_dl_prio_tx(lcid) > 0 and channels[lcid].cfg.priority < min_prio_val) { min_prio_val = channels[lcid].cfg.priority; prio_lcid = lcid; } @@ -147,10 +147,10 @@ int lch_ue_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int return alloc_bytes; } - // try first to allocate retxs - alloc_bytes = alloc_retx_bytes(lcid, rem_bytes); + // try first to allocate high priority txs (e.g. retxs, status pdus) + alloc_bytes = alloc_prio_tx_bytes(lcid, rem_bytes); - // if no retx alloc, try newtx + // if no prio tx alloc, try newtx if (alloc_bytes == 0) { alloc_bytes = alloc_tx_bytes(lcid, rem_bytes); } @@ -168,15 +168,15 @@ int lch_ue_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int return alloc_bytes; } -int lch_ue_manager::alloc_retx_bytes(uint8_t lcid, int rem_bytes) +int lch_ue_manager::alloc_prio_tx_bytes(uint8_t lcid, int rem_bytes) { const int rlc_overhead = (lcid == 0) ? 0 : RLC_MAX_HEADER_SIZE_NO_LI; if (rem_bytes <= rlc_overhead) { return 0; } int rem_bytes_no_header = rem_bytes - rlc_overhead; - int alloc = std::min(rem_bytes_no_header, get_dl_retx(lcid)); - channels[lcid].buf_retx -= alloc; + int alloc = std::min(rem_bytes_no_header, get_dl_prio_tx(lcid)); + channels[lcid].buf_prio_tx -= alloc; return alloc + (alloc > 0 ? rlc_overhead : 0); } @@ -211,7 +211,7 @@ bool lch_ue_manager::has_pending_dl_txs() const int lch_ue_manager::get_dl_tx_total_with_overhead(uint32_t lcid) const { - return get_dl_retx_with_overhead(lcid) + get_dl_tx_with_overhead(lcid); + return get_dl_prio_tx_with_overhead(lcid) + get_dl_tx_with_overhead(lcid); } int lch_ue_manager::get_dl_tx_with_overhead(uint32_t lcid) const @@ -219,9 +219,9 @@ int lch_ue_manager::get_dl_tx_with_overhead(uint32_t lcid) const return get_dl_mac_sdu_size_with_overhead(lcid, get_dl_tx(lcid)); } -int lch_ue_manager::get_dl_retx_with_overhead(uint32_t lcid) const +int lch_ue_manager::get_dl_prio_tx_with_overhead(uint32_t lcid) const { - return get_dl_mac_sdu_size_with_overhead(lcid, get_dl_retx(lcid)); + return get_dl_mac_sdu_size_with_overhead(lcid, get_dl_prio_tx(lcid)); } int lch_ue_manager::get_bsr_with_overhead(uint32_t lcg) const diff --git a/srsenb/test/mac/sched_lc_ch_test.cc b/srsenb/test/mac/sched_lc_ch_test.cc index d321bb144..106d38581 100644 --- a/srsenb/test/mac/sched_lc_ch_test.cc +++ b/srsenb/test/mac/sched_lc_ch_test.cc @@ -44,7 +44,7 @@ int test_pdu_alloc_successful(srsenb::lch_ue_manager& lch_handler, int test_retx_until_empty(srsenb::lch_ue_manager& lch_handler, int lcid, uint32_t rlc_payload_size) { - int start_rlc_bytes = lch_handler.get_dl_retx(lcid); + int start_rlc_bytes = lch_handler.get_dl_prio_tx(lcid); int nof_pdus = ceil(static_cast(start_rlc_bytes) / static_cast(rlc_payload_size)); int rem_rlc_bytes = start_rlc_bytes; @@ -53,7 +53,7 @@ int test_retx_until_empty(srsenb::lch_ue_manager& lch_handler, int lcid, uint32_ uint32_t expected_payload_size = std::min(rlc_payload_size, (uint32_t)rem_rlc_bytes); TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, lcid, expected_payload_size) == SRSRAN_SUCCESS); rem_rlc_bytes -= expected_payload_size; - TESTASSERT(lch_handler.get_dl_retx(lcid) == rem_rlc_bytes); + TESTASSERT(lch_handler.get_dl_prio_tx(lcid) == rem_rlc_bytes); } return start_rlc_bytes; } @@ -97,15 +97,15 @@ int test_lc_ch_pbr_infinity() lch_handler.dl_buffer_state(drb_to_lcid(lte_drb::drb2), 5000, 10000); // TEST1 - retx of SRB1 is prioritized. Do not transmit other bearers until there are no SRB1 retxs - int nof_pending_bytes = lch_handler.get_dl_retx(srb_to_lcid(lte_srb::srb1)); + int nof_pending_bytes = lch_handler.get_dl_prio_tx(srb_to_lcid(lte_srb::srb1)); TESTASSERT(test_retx_until_empty(lch_handler, srb_to_lcid(lte_srb::srb1), 500) == nof_pending_bytes); // TEST2 - the DRB2 has lower prio level than SRB1, but has retxs - nof_pending_bytes = lch_handler.get_dl_retx(drb_to_lcid(lte_drb::drb2)); + nof_pending_bytes = lch_handler.get_dl_prio_tx(drb_to_lcid(lte_drb::drb2)); TESTASSERT(test_retx_until_empty(lch_handler, drb_to_lcid(lte_drb::drb2), 500) == nof_pending_bytes); // TEST3 - the DRB1 has lower prio level, but has retxs - nof_pending_bytes = lch_handler.get_dl_retx(drb_to_lcid(lte_drb::drb1)); + nof_pending_bytes = lch_handler.get_dl_prio_tx(drb_to_lcid(lte_drb::drb1)); TESTASSERT(test_retx_until_empty(lch_handler, drb_to_lcid(lte_drb::drb1), 500) == nof_pending_bytes); // TEST4 - The SRB1 newtx buffer is emptied before other bearers newtxs @@ -154,11 +154,11 @@ int test_lc_ch_pbr_finite() lch_handler.dl_buffer_state(drb_to_lcid(lte_drb::drb2), 50000, 0); // TEST1 - SRB1 retxs are emptied first - int nof_pending_bytes = lch_handler.get_dl_retx(srb_to_lcid(lte_srb::srb1)); + int nof_pending_bytes = lch_handler.get_dl_prio_tx(srb_to_lcid(lte_srb::srb1)); TESTASSERT(test_retx_until_empty(lch_handler, srb_to_lcid(lte_srb::srb1), 500) == nof_pending_bytes); // TEST2 - DRB1 retxs are emptied - nof_pending_bytes = lch_handler.get_dl_retx(drb_to_lcid(lte_drb::drb1)); + nof_pending_bytes = lch_handler.get_dl_prio_tx(drb_to_lcid(lte_drb::drb1)); TESTASSERT(test_retx_until_empty(lch_handler, drb_to_lcid(lte_drb::drb1), 500) == nof_pending_bytes); // TEST3 - SRB1 newtxs are emptied (PBR==infinity)