simplified sched_ue pending DL bytes calculation API

This commit is contained in:
Francisco 2020-11-20 16:34:37 +00:00 committed by Andre Puschmann
parent 0ffea62411
commit a348508072
7 changed files with 73 additions and 68 deletions

View File

@ -48,10 +48,14 @@ public:
bool is_bearer_ul(uint32_t lcid) const;
bool is_bearer_dl(uint32_t lcid) const;
bool has_pending_dl_txs() 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_total_with_overhead(uint32_t lcid) const;
int get_dl_tx(uint32_t lcid) const;
int get_dl_tx_with_overhead(uint32_t lcid) const;
int get_dl_retx(uint32_t lcid) const;
int get_dl_retx_with_overhead(uint32_t lcid) const;
int get_bsr(uint32_t lcid) const;
int get_bsr_with_overhead(uint32_t lcid) const;
int get_max_prio_lcid() const;

View File

@ -152,8 +152,7 @@ public:
rbg_interval get_required_dl_rbgs(uint32_t ue_cc_idx);
srslte::interval<uint32_t> get_requested_dl_bytes(uint32_t ue_cc_idx);
uint32_t get_pending_dl_new_data();
uint32_t get_pending_dl_new_data_total();
uint32_t get_pending_dl_rlc_data() const;
uint32_t get_pending_ul_data_total(uint32_t tti, int this_ue_cc_idx);
uint32_t get_pending_ul_new_data(uint32_t tti, int this_ue_cc_idx);
@ -217,8 +216,7 @@ private:
uint32_t tti_tx_dl,
uint32_t ue_cc_idx,
uint32_t cfi,
uint32_t tb,
const char* dci_format);
uint32_t tb);
std::pair<int, int> compute_mcs_and_tbs(uint32_t ue_cc_idx,
uint32_t tti_tx_dl,

View File

@ -255,9 +255,8 @@ int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id)
uint32_t sched::get_dl_buffer(uint16_t rnti)
{
// TODO: Check if correct use of last_tti
uint32_t ret = SRSLTE_ERROR;
ue_db_access(rnti, [&ret](sched_ue& ue) { ret = ue.get_pending_dl_new_data(); }, __PRETTY_FUNCTION__);
ue_db_access(rnti, [&ret](sched_ue& ue) { ret = ue.get_pending_dl_rlc_data(); }, __PRETTY_FUNCTION__);
return ret;
}

View File

@ -1035,7 +1035,7 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_
}
sched_ue* user = &ue_it->second;
uint32_t cell_index = user->get_active_cell_index(cc_cfg->enb_cc_idx).second;
uint32_t data_before = user->get_pending_dl_new_data();
uint32_t data_before = user->get_requested_dl_bytes(cell_index).stop();
const dl_harq_proc& dl_harq = user->get_dl_harq(data_alloc.pid, cell_index);
bool is_newtx = dl_harq.is_empty();
@ -1049,7 +1049,7 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_
data_alloc.pid,
data_alloc.user_mask.to_hex().c_str(),
tbs,
user->get_pending_dl_new_data());
user->get_requested_dl_bytes(cell_index).stop());
continue;
}
@ -1065,7 +1065,7 @@ void sf_sched::set_dl_data_sched_result(const pdcch_grid_t::alloc_result_t& dci_
dl_harq.nof_retx(0) + dl_harq.nof_retx(1),
tbs,
data_before,
user->get_pending_dl_new_data());
user->get_requested_dl_bytes(cell_index).stop());
dl_result->nof_data_elems++;
}

View File

@ -32,7 +32,7 @@ namespace srsenb {
#define RLC_MAX_HEADER_SIZE_NO_LI 3
#define MAC_MAX_HEADER_SIZE 3
#define MAC_MIN_HEADER_SIZE 2
#define MAC_MIN_ALLOC_SIZE RLC_MAX_HEADER_SIZE_NO_LI + MAC_MAX_HEADER_SIZE
#define MAC_MIN_ALLOC_SIZE RLC_MAX_HEADER_SIZE_NO_LI + MAC_MIN_HEADER_SIZE
/// TS 36.321 sec 7.1.2 - MAC PDU subheader is 2 bytes if L<=128 and 3 otherwise
uint32_t get_mac_subheader_size(uint32_t sdu_bytes)
@ -44,6 +44,19 @@ uint32_t get_mac_sdu_and_subheader_size(uint32_t sdu_bytes)
return sdu_bytes + get_mac_subheader_size(sdu_bytes);
}
uint32_t get_rlc_header_size_est(uint32_t lcid, uint32_t rlc_pdu_bytes)
{
return (lcid == 0 or rlc_pdu_bytes == 0) ? 0 : RLC_MAX_HEADER_SIZE_NO_LI;
}
uint32_t get_rlc_mac_overhead(uint32_t lcid, uint32_t rlc_pdu_bytes)
{
return get_mac_subheader_size(rlc_pdu_bytes) + get_rlc_header_size_est(lcid, rlc_pdu_bytes);
}
uint32_t get_mac_sdu_size_with_overhead(uint32_t lcid, uint32_t rlc_pdu_bytes)
{
return rlc_pdu_bytes + get_rlc_mac_overhead(lcid, rlc_pdu_bytes);
}
/*******************************************************
*
* Logical Channel Management
@ -267,6 +280,19 @@ 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;
}
bool lch_manager::has_pending_dl_txs() const
{
if(not pending_ces.empty()) {
return true;
}
for(uint32_t lcid = 0; lcid < lch.size(); ++lcid) {
if(get_dl_tx_total(lcid) > 0) {
return true;
}
}
return false;
}
int lch_manager::get_dl_tx_total() const
{
int sum = 0;
@ -276,14 +302,29 @@ int lch_manager::get_dl_tx_total() const
return sum;
}
int lch_manager::get_dl_tx_total_with_overhead(uint32_t lcid) const
{
return get_dl_retx_with_overhead(lcid) + get_dl_tx_with_overhead(lcid);
}
int lch_manager::get_dl_tx(uint32_t lcid) const
{
return is_bearer_dl(lcid) ? lch[lcid].buf_tx : 0;
}
int lch_manager::get_dl_tx_with_overhead(uint32_t lcid) const
{
return get_mac_sdu_size_with_overhead(lcid, get_dl_tx(lcid));
}
int lch_manager::get_dl_retx(uint32_t lcid) const
{
return is_bearer_dl(lcid) ? lch[lcid].buf_retx : 0;
}
int lch_manager::get_dl_retx_with_overhead(uint32_t lcid) const
{
return get_mac_sdu_size_with_overhead(lcid, get_dl_retx(lcid));
}
int lch_manager::get_bsr(uint32_t lcid) const
{
return is_bearer_ul(lcid) ? lcg_bsr[lch[lcid].cfg.group] : 0;
@ -291,7 +332,7 @@ int lch_manager::get_bsr(uint32_t lcid) const
int lch_manager::get_bsr_with_overhead(uint32_t lcid) const
{
int bsr = get_bsr(lcid);
return bsr == 0 ? 0 : bsr + RLC_MAX_HEADER_SIZE_NO_LI;
return bsr + (bsr == 0 ? 0 : ((lcid == 0) ? 0 : RLC_MAX_HEADER_SIZE_NO_LI));
}
std::string lch_manager::get_bsr_text() const

View File

@ -36,7 +36,7 @@ namespace srsenb {
* Helper Functions *
******************************************************/
#define MAC_MIN_ALLOC_SIZE 6
#define MAC_MIN_ALLOC_SIZE 5
namespace sched_utils {
@ -454,7 +454,7 @@ void sched_ue::tpc_dec()
*******************************************************/
/**
* Allocate space
* Allocate MAC PDU for a UE HARQ pid
* @param data
* @param total_tbs
* @param ue_cc_idx
@ -466,8 +466,7 @@ std::pair<int, int> sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* da
uint32_t tti_tx_dl,
uint32_t ue_cc_idx,
uint32_t cfi,
uint32_t tb,
const char* dci_format)
uint32_t tb)
{
srslte_dci_dl_t* dci = &data->dci;
uint32_t nof_prb = sched_utils::count_prb_per_tb(*carriers[ue_cc_idx].get_cell_cfg(), user_mask);
@ -553,7 +552,7 @@ int sched_ue::generate_format1(uint32_t pid,
}
if (h->is_empty(0)) {
auto ret = allocate_new_dl_mac_pdu(data, h, user_mask, tti_tx_dl, ue_cc_idx, cfi, 0, "1");
auto ret = allocate_new_dl_mac_pdu(data, h, user_mask, tti_tx_dl, ue_cc_idx, cfi, 0);
tbs = ret.first;
mcs = ret.second;
} else {
@ -666,14 +665,13 @@ int sched_ue::generate_format2a(uint32_t pid,
}
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
uint32_t req_bytes = get_pending_dl_new_data_total();
int mcs = 0;
int tbs = 0;
int mcs = 0;
int tbs = 0;
if (!h->is_empty(tb)) {
h->new_retx(user_mask, tb, tti_tx_dl, &mcs, &tbs, data->dci.location.ncce);
} else if (tb_en[tb] && req_bytes > 0 && no_retx) {
auto ret = allocate_new_dl_mac_pdu(data, h, user_mask, tti_tx_dl, ue_cc_idx, cfi, tb, "2/2a");
} else if (tb_en[tb] && no_retx) {
auto ret = allocate_new_dl_mac_pdu(data, h, user_mask, tti_tx_dl, ue_cc_idx, cfi, tb);
tbs = ret.first;
mcs = ret.second;
}
@ -862,7 +860,8 @@ bool sched_ue::needs_cqi(uint32_t tti, uint32_t cc_idx, bool will_be_sent)
bool sched_ue::needs_cqi_unlocked(uint32_t tti, uint32_t cc_idx, bool will_be_sent)
{
bool ret = false;
if (phy_config_dedicated_enabled && cfg.supported_cc_list[0].aperiodic_cqi_period && get_pending_dl_new_data() > 0) {
if (phy_config_dedicated_enabled && cfg.supported_cc_list[0].aperiodic_cqi_period &&
lch_handler.has_pending_dl_txs() && scell_activation_mask().any()) {
uint32_t interval = srslte_tti_interval(tti, carriers[cc_idx].dl_cqi_tti);
bool needscqi = interval >= cfg.supported_cc_list[0].aperiodic_cqi_period;
if (needscqi) {
@ -879,18 +878,6 @@ bool sched_ue::needs_cqi_unlocked(uint32_t tti, uint32_t cc_idx, bool will_be_se
return ret;
}
/// Use this function in the dl-metric to get the bytes to be scheduled. It accounts for the UE data,
/// the RAR resources, and headers
/// \return number of bytes to be allocated
uint32_t sched_ue::get_pending_dl_new_data_total()
{
uint32_t req_bytes = get_pending_dl_new_data();
if (req_bytes > 0) {
req_bytes += (req_bytes < 128) ? 2 : 3; // consider the header
}
return req_bytes;
}
/**
* Compute the range of RBGs that avoids segmentation of TM and MAC subheader data. Always computed for highest CFI
* @param ue_cc_idx carrier of the UE
@ -937,15 +924,6 @@ 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)
{
// Convenience function to compute the number of bytes allocated for a given SDU
auto compute_sdu_total_bytes = [](uint32_t lcid, uint32_t buffer_bytes) {
if (buffer_bytes == 0) {
return 0u;
}
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 */
// Ensure there is space for ConRes and RRC Setup
// SRB0 is a special case due to being RLC TM (no segmentation possible)
@ -959,14 +937,12 @@ srslte::interval<uint32_t> sched_ue::get_requested_dl_bytes(uint32_t ue_cc_idx)
uint32_t max_data = 0, min_data = 0;
uint32_t srb0_data = 0, rb_data = 0, sum_ce_data = 0;
bool is_dci_format1 = get_dci_format() == SRSLTE_DCI_FORMAT1;
if (is_dci_format1) {
srb0_data += compute_sdu_total_bytes(0, lch_handler.get_dl_retx(0));
srb0_data += compute_sdu_total_bytes(0, lch_handler.get_dl_tx(0));
}
srb0_data = lch_handler.get_dl_tx_total_with_overhead(0);
// Add pending CEs
if (ue_cc_idx == 0) {
if (srb0_data == 0 and not lch_handler.pending_ces.empty() and lch_handler.pending_ces.front() == srslte::dl_sch_lcid::CON_RES_ID) {
if (srb0_data == 0 and not lch_handler.pending_ces.empty() and
lch_handler.pending_ces.front() == srslte::dl_sch_lcid::CON_RES_ID) {
// Wait for SRB0 data to be available for Msg4 before scheduling the ConRes CE
return {};
}
@ -976,10 +952,7 @@ srslte::interval<uint32_t> sched_ue::get_requested_dl_bytes(uint32_t ue_cc_idx)
}
// Add pending data in remaining RLC buffers
for (int i = 1; i < sched_interface::MAX_LC; i++) {
if (lch_handler.is_bearer_dl(i)) {
rb_data += compute_sdu_total_bytes(i, lch_handler.get_dl_retx(i));
rb_data += compute_sdu_total_bytes(i, lch_handler.get_dl_tx(i));
}
rb_data += lch_handler.get_dl_tx_total_with_overhead(i);
}
max_data = srb0_data + sum_ce_data + rb_data;
@ -1000,24 +973,14 @@ srslte::interval<uint32_t> sched_ue::get_requested_dl_bytes(uint32_t ue_cc_idx)
}
/**
* Get pending DL data in RLC buffers + CEs
* Get pending RLC DL data in RLC buffers. Header sizes not accounted
* @return
*/
uint32_t sched_ue::get_pending_dl_new_data()
uint32_t sched_ue::get_pending_dl_rlc_data() const
{
if (std::none_of(
carriers.begin(), carriers.end(), [](const cc_sched_ue& cc) { return cc.cc_state() == cc_st::active; })) {
return 0;
}
uint32_t pending_data = 0;
for (int i = 0; i < sched_interface::MAX_LC; i++) {
if (lch_handler.is_bearer_dl(i)) {
pending_data += lch_handler.get_dl_tx(i) + lch_handler.get_dl_retx(i);
}
}
for (auto& ce : lch_handler.pending_ces) {
pending_data += srslte::ce_total_size(ce);
pending_data += lch_handler.get_dl_tx_total(i);
}
return pending_data;
}

View File

@ -488,7 +488,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
reconf_user(user->rnti, generate_setup_ue_cfg(sim_args0.default_ue_sim_cfg.ue_cfg));
// Schedule RRC Setup and ConRes CE
uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_new_data();
uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data();
if (pending_dl_new_data == 0) {
uint32_t lcid = RB_ID_SRB0; // Use SRB0 to schedule Msg4
dl_rlc_buffer_state(ue_ev.rnti, lcid, 50, 0);
@ -506,7 +506,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
if (ue_ev.buffer_ev->dl_data > 0 and ue_sim_ctxt.msg4_tti_rx.is_valid()) {
// If Msg4 has already been tx and there DL data to transmit
uint32_t lcid = RB_ID_DRB1;
uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_new_data();
uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data();
if (user->drb_cfg_flag or pending_dl_new_data == 0) {
// If RRCSetup finished
if (not user->drb_cfg_flag) {