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.
master
Francisco Paisana 4 years ago
parent 55d62a2baa
commit 42cdc5e340

@ -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;

@ -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<int, int> 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<int, int> 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<uint32_t> 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<uint32_t> 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;

@ -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;

Loading…
Cancel
Save