From 42cdc5e3409335300c65470fe51ed1a138cb977f Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 30 Oct 2020 10:31:07 +0000 Subject: [PATCH] Allocate all the leftover bytes of the TBS to last allocated MAC SDU. Fix the way the RLC header is accounted for depending on the bearer id. For instance, the SRB0 does not require any RLC header. --- srsenb/hdr/stack/mac/scheduler_ue.h | 1 + srsenb/src/stack/mac/scheduler_ue.cc | 63 +++++++++++++++++--------- srsenb/test/mac/scheduler_test_rand.cc | 5 +- 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/srsenb/hdr/stack/mac/scheduler_ue.h b/srsenb/hdr/stack/mac/scheduler_ue.h index 2bc6855d7..a560f7340 100644 --- a/srsenb/hdr/stack/mac/scheduler_ue.h +++ b/srsenb/hdr/stack/mac/scheduler_ue.h @@ -117,6 +117,7 @@ public: bool is_bearer_ul(uint32_t lcid) const; bool is_bearer_dl(uint32_t lcid) const; + int get_dl_tx_total() const; int get_dl_tx_total(uint32_t lcid) const { return get_dl_tx(lcid) + get_dl_retx(lcid); } int get_dl_tx(uint32_t lcid) const; int get_dl_retx(uint32_t lcid) const; diff --git a/srsenb/src/stack/mac/scheduler_ue.cc b/srsenb/src/stack/mac/scheduler_ue.cc index 2475a2c18..6295e2cf6 100644 --- a/srsenb/src/stack/mac/scheduler_ue.cc +++ b/srsenb/src/stack/mac/scheduler_ue.cc @@ -36,8 +36,9 @@ namespace srsenb { * Helper Functions * ******************************************************/ -#define RLC_MAX_HEADER_SIZE 3 +#define RLC_MAX_HEADER_SIZE_NO_LI 3 #define MAC_MAX_HEADER_SIZE 3 +#define MAC_MIN_ALLOC_SIZE RLC_MAX_HEADER_SIZE_NO_LI + MAC_MAX_HEADER_SIZE namespace sched_utils { @@ -58,10 +59,14 @@ uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool use_tbs_index_ } //! TS 36.321 sec 7.1.2 - MAC PDU subheader is 2 bytes if L<=128 and 3 otherwise -uint32_t get_mac_subheader_sdu_size(uint32_t sdu_bytes) +uint32_t get_mac_subheader_size(uint32_t sdu_bytes) { return sdu_bytes == 0 ? 0 : (sdu_bytes > 128 ? 3 : 2); } +uint32_t get_mac_sdu_and_subheader_size(uint32_t sdu_bytes) +{ + return sdu_bytes + get_mac_subheader_size(sdu_bytes); +} /** * Count number of PRBs present in a DL RBG mask @@ -398,18 +403,16 @@ void sched_ue::tpc_dec() */ uint32_t sched_ue::allocate_mac_sdus(sched_interface::dl_sched_data_t* data, uint32_t total_tbs, uint32_t tbidx) { - // TS 36.321 sec 7.1.2 - MAC PDU subheader is 2 bytes if L<=128 and 3 otherwise - auto compute_subheader_size = [](uint32_t sdu_size) { return sdu_size > 128 ? 3 : 2; }; - uint32_t rem_tbs = total_tbs; + uint32_t rem_tbs = total_tbs; // if we do not have enough bytes to fit MAC subheader and RLC header, skip MAC SDU allocation - while (rem_tbs >= RLC_MAX_HEADER_SIZE + MAC_MAX_HEADER_SIZE) { - uint32_t max_sdu_bytes = rem_tbs - compute_subheader_size(rem_tbs - 2); + while (rem_tbs > MAC_MAX_HEADER_SIZE) { + uint32_t max_sdu_bytes = rem_tbs - sched_utils::get_mac_subheader_size(rem_tbs - 2); uint32_t alloc_sdu_bytes = lch_handler.alloc_rlc_pdu(&data->pdu[tbidx][data->nof_pdu_elems[tbidx]], max_sdu_bytes); if (alloc_sdu_bytes == 0) { break; } - rem_tbs -= (alloc_sdu_bytes + compute_subheader_size(alloc_sdu_bytes)); // account for MAC sub-header + rem_tbs -= sched_utils::get_mac_sdu_and_subheader_size(alloc_sdu_bytes); // account for MAC sub-header data->nof_pdu_elems[tbidx]++; } @@ -465,12 +468,12 @@ std::pair sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* da int mcs = ret.first; int tbs = ret.second; - /* Allocate MAC PDU (subheaders, CEs, and SDUS) */ + // Allocate MAC PDU (subheaders, CEs, and SDUS) int rem_tbs = tbs; rem_tbs -= allocate_mac_ces(data, rem_tbs, ue_cc_idx); rem_tbs -= allocate_mac_sdus(data, rem_tbs, tb); - /* Allocate DL UE Harq */ + // Allocate DL UE Harq if (rem_tbs != tbs) { h->new_tx(user_mask, tb, tti_tx_dl, mcs, tbs, data->dci.location.ncce); Debug("SCHED: Alloc DCI format%s new mcs=%d, tbs=%d, nof_prb=%d\n", dci_format, mcs, tbs, nof_prb); @@ -478,7 +481,7 @@ std::pair sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* da Warning("SCHED: Failed to allocate DL harq pid=%d\n", h->get_id()); } - return std::make_pair(tbs, mcs); + return {tbs, mcs}; } int sched_ue::generate_dl_dci_format(uint32_t pid, @@ -930,14 +933,13 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t ue_cc_idx) */ srslte::interval sched_ue::get_requested_dl_bytes(uint32_t ue_cc_idx) { - const uint32_t min_alloc_bytes = 5; // 2 for subheader, and 3 for RLC header // Convenience function to compute the number of bytes allocated for a given SDU - auto compute_sdu_total_bytes = [&min_alloc_bytes](uint32_t lcid, uint32_t buffer_bytes) { + auto compute_sdu_total_bytes = [](uint32_t lcid, uint32_t buffer_bytes) { if (buffer_bytes == 0) { return 0u; } - uint32_t subheader_and_sdu = buffer_bytes + sched_utils::get_mac_subheader_sdu_size(buffer_bytes); - return (lcid == 0) ? subheader_and_sdu : std::max(subheader_and_sdu, min_alloc_bytes); + uint32_t subheader_and_sdu = sched_utils::get_mac_sdu_and_subheader_size(buffer_bytes); + return (lcid == 0) ? subheader_and_sdu : std::max(subheader_and_sdu, (uint32_t)MAC_MIN_ALLOC_SIZE); }; /* Set Maximum boundary */ @@ -986,7 +988,7 @@ srslte::interval sched_ue::get_requested_dl_bytes(uint32_t ue_cc_idx) if (sum_ce_data > 0) { min_data = srslte::ce_total_size(pending_ces.front()); } else if (rb_data > 0) { - min_data = min_alloc_bytes; + min_data = MAC_MIN_ALLOC_SIZE; } } @@ -1661,6 +1663,12 @@ int lch_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int rem alloc_bytes = alloc_tx_bytes(lcid, rem_bytes); } + // If it is last PDU of the TBS, allocate all leftover bytes + int leftover_bytes = rem_bytes - alloc_bytes; + if (leftover_bytes > 0 and (leftover_bytes <= MAC_MIN_ALLOC_SIZE or get_dl_tx_total() == 0)) { + alloc_bytes += leftover_bytes; + } + if (alloc_bytes > 0) { rlc_pdu->nbytes = alloc_bytes; rlc_pdu->lcid = lcid; @@ -1671,28 +1679,30 @@ int lch_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int rem int lch_manager::alloc_retx_bytes(uint8_t lcid, int rem_bytes) { - if (rem_bytes <= RLC_MAX_HEADER_SIZE) { + 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_MAX_HEADER_SIZE; + int rem_bytes_no_header = rem_bytes - rlc_overhead; int alloc = std::min(rem_bytes_no_header, get_dl_retx(lcid)); lch[lcid].buf_retx -= alloc; - return alloc + (alloc > 0 ? RLC_MAX_HEADER_SIZE : 0); + return alloc + (alloc > 0 ? rlc_overhead : 0); } int lch_manager::alloc_tx_bytes(uint8_t lcid, int rem_bytes) { - if (rem_bytes <= RLC_MAX_HEADER_SIZE) { + 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_MAX_HEADER_SIZE; + int rem_bytes_no_header = rem_bytes - rlc_overhead; int alloc = std::min(rem_bytes_no_header, get_dl_tx(lcid)); lch[lcid].buf_tx -= alloc; if (alloc > 0 and lch[lcid].cfg.pbr != pbr_infinity) { // Update Bj lch[lcid].Bj -= alloc; } - return alloc + (alloc > 0 ? RLC_MAX_HEADER_SIZE : 0); + return alloc + (alloc > 0 ? rlc_overhead : 0); } bool lch_manager::is_bearer_active(uint32_t lcid) const @@ -1710,6 +1720,15 @@ bool lch_manager::is_bearer_dl(uint32_t lcid) const return is_bearer_active(lcid) and lch[lcid].cfg.direction != sched_interface::ue_bearer_cfg_t::UL; } +int lch_manager::get_dl_tx_total() const +{ + int sum = 0; + for (size_t lcid = 0; lcid < lch.size(); ++lcid) { + sum += get_dl_tx_total(lcid); + } + return sum; +} + int lch_manager::get_dl_tx(uint32_t lcid) const { return is_bearer_dl(lcid) ? lch[lcid].buf_tx : 0; diff --git a/srsenb/test/mac/scheduler_test_rand.cc b/srsenb/test/mac/scheduler_test_rand.cc index 2d693a58c..8c6210aab 100644 --- a/srsenb/test/mac/scheduler_test_rand.cc +++ b/srsenb/test/mac/scheduler_test_rand.cc @@ -63,9 +63,8 @@ using srslte::tti_point; * - DL adaptive retx/new tx <=> PDCCH alloc *******************************************************/ -uint32_t const seed = std::chrono::system_clock::now().time_since_epoch().count(); -// uint32_t const seed = 1581009287; // prb==25 -bool check_old_pids = false; +uint32_t const seed = std::chrono::system_clock::now().time_since_epoch().count(); +bool check_old_pids = false; struct ue_stats_t { uint64_t nof_dl_rbs = 0;