fixed the building of MAC SDUs in the scheduler. Now, we ensure there is always space for the MAC subheader and RLC header. The MAC subheader is correctly discounted from the remaining bytes in a TB.

master
Francisco Paisana 5 years ago
parent 089f72d573
commit 87038375d5

@ -222,9 +222,10 @@ private:
void set_bearer_cfg_unlocked(uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg_); void set_bearer_cfg_unlocked(uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg_);
bool is_sr_triggered(); bool is_sr_triggered();
int alloc_pdu(int tbs, sched_interface::dl_sched_pdu_t* pdu);
uint32_t format1_count_prb(const rbgmask_t& bitmask, uint32_t cc_idx); uint32_t format1_count_prb(const rbgmask_t& bitmask, uint32_t cc_idx);
int alloc_mac_sdu(sched_interface::dl_sched_pdu_t* pdu, int rem_tbs);
uint32_t allocate_mac_sdus(sched_interface::dl_sched_data_t* data, uint32_t total_tbs);
static bool bearer_is_ul(ue_bearer_t* lch); static bool bearer_is_ul(ue_bearer_t* lch);
static bool bearer_is_dl(const ue_bearer_t* lch); static bool bearer_is_dl(const ue_bearer_t* lch);

@ -33,7 +33,6 @@
#define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__) #define Debug(fmt, ...) log_h->debug(fmt, ##__VA_ARGS__)
#define MCS_FIRST_DL 4 #define MCS_FIRST_DL 4
#define MIN_DATA_TBS 4
/****************************************************** /******************************************************
* UE class * * UE class *
@ -43,6 +42,19 @@ namespace srsenb {
constexpr uint32_t conres_ce_size = 6; constexpr uint32_t conres_ce_size = 6;
/******************************************************
* Helper Functions *
******************************************************/
namespace sched_utils {
uint32_t get_tbs_bytes(uint32_t mcs, uint32_t nof_alloc_prb, bool is_ul)
{
return srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs, is_ul), nof_alloc_prb);
}
} // namespace sched_utils
/******************************************************* /*******************************************************
* *
* Initialization and configuration functions * Initialization and configuration functions
@ -349,8 +361,28 @@ void sched_ue::tpc_dec()
* *
*******************************************************/ *******************************************************/
uint32_t sched_ue::allocate_mac_sdus(sched_interface::dl_sched_data_t* data, uint32_t total_tbs)
{
auto compute_subheader_size = [](uint32_t sdu_size) { return sdu_size > 128 ? 3 : 2; };
constexpr uint32_t min_mac_sdu_size = 5; // accounts for MAC SDU subheader and RLC header
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 >= min_mac_sdu_size) {
uint32_t max_sdu_bytes = rem_tbs - compute_subheader_size(rem_tbs - 2);
uint32_t alloc_sdu_bytes = alloc_mac_sdu(&data->pdu[0][data->nof_pdu_elems[0]], 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
data->nof_pdu_elems[0]++;
}
return total_tbs - rem_tbs;
}
// Generates a Format1 dci // Generates a Format1 dci
// > return 0 if TBS<MIN_DATA_TBS // > return 0 if allocation is invalid
int sched_ue::generate_format1(dl_harq_proc* h, int sched_ue::generate_format1(dl_harq_proc* h,
sched_interface::dl_sched_data_t* data, sched_interface::dl_sched_data_t* data,
uint32_t tti_tx_dl, uint32_t tti_tx_dl,
@ -391,25 +423,14 @@ int sched_ue::generate_format1(dl_harq_proc* h,
if (mcs0 < 0) { // dynamic MCS if (mcs0 < 0) { // dynamic MCS
tbs = carriers[cc_idx].alloc_tbs_dl(nof_prb, nof_re, req_bytes, &mcs); tbs = carriers[cc_idx].alloc_tbs_dl(nof_prb, nof_re, req_bytes, &mcs);
} else { } else {
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs0, false), nof_prb) / 8;
mcs = mcs0; mcs = mcs0;
} tbs = sched_utils::get_tbs_bytes(mcs, nof_prb, false);
// Ensure tbs >= MIN_DATA_TBS
while (tbs < MIN_DATA_TBS and mcs != carriers[cc_idx].max_mcs_dl) {
mcs++;
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(mcs, false), nof_prb) / 8;
}
if (tbs < MIN_DATA_TBS) {
log_h->warning("SCHED: Allocation of TBS=%d that does not account header\n", tbs);
return 0;
} }
// Allocate DL Harq // Allocate DL Harq
h->new_tx(user_mask, 0, tti_tx_dl, mcs, tbs, data->dci.location.ncce); h->new_tx(user_mask, 0, tti_tx_dl, mcs, tbs, data->dci.location.ncce);
int rem_tbs = tbs; int rem_tbs = tbs;
int x = 0;
// Allocate MAC ConRes CE // Allocate MAC ConRes CE
if (need_conres_ce) { if (need_conres_ce) {
@ -426,14 +447,8 @@ int sched_ue::generate_format1(dl_harq_proc* h,
rem_tbs -= 2; rem_tbs -= 2;
} }
// Allocate PDUs // Allocate MAC SDU and respective subheaders
do { allocate_mac_sdus(data, rem_tbs);
x = alloc_pdu(rem_tbs, &data->pdu[0][data->nof_pdu_elems[0]]);
if (x) {
rem_tbs -= x + 2; // count 2-byte header
data->nof_pdu_elems[0]++;
}
} while (rem_tbs >= MIN_DATA_TBS && x > 0);
Debug("SCHED: Alloc format1 new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes); Debug("SCHED: Alloc format1 new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes);
} else { } else {
@ -538,17 +553,10 @@ int sched_ue::generate_format2a_unlocked(dl_harq_proc* h,
8; 8;
mcs = carriers[cc_idx].fixed_mcs_dl; mcs = carriers[cc_idx].fixed_mcs_dl;
} }
h->new_tx(user_mask, tb, tti, mcs, tbs, data->dci.location.ncce); h->new_tx(user_mask, tb, tti, mcs, tbs, data->dci.location.ncce);
int rem_tbs = tbs; allocate_mac_sdus(data, tbs);
int x = 0;
do {
x = alloc_pdu(rem_tbs, &data->pdu[tb][data->nof_pdu_elems[tb]]);
rem_tbs -= x;
if (x) {
data->nof_pdu_elems[tb]++;
}
} while (rem_tbs >= MIN_DATA_TBS && x > 0);
Debug("SCHED: Alloc format2/2a new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes); Debug("SCHED: Alloc format2/2a new mcs=%d, tbs=%d, nof_prb=%d, req_bytes=%d\n", mcs, tbs, nof_prb, req_bytes);
} }
@ -1006,26 +1014,26 @@ sched_ue_carrier* sched_ue::get_ue_carrier(uint32_t enb_cc_idx)
} }
/* Allocates first available RLC PDU */ /* Allocates first available RLC PDU */
int sched_ue::alloc_pdu(int tbs_bytes, sched_interface::dl_sched_pdu_t* pdu) int sched_ue::alloc_mac_sdu(sched_interface::dl_sched_pdu_t* mac_sdu, int rem_tbs)
{ {
// TODO: Implement lcid priority (now lowest index is lowest priority) // TODO: Implement lcid priority (now lowest index is lowest priority)
int x = 0; int alloc_bytes = 0;
int i = 0; int i = 0;
for (i = 0; i < sched_interface::MAX_LC && !x; i++) { for (i = 0; i < sched_interface::MAX_LC and alloc_bytes == 0; i++) {
if (lch[i].buf_retx) { if (lch[i].buf_retx > 0) {
x = SRSLTE_MIN(lch[i].buf_retx, tbs_bytes); alloc_bytes = SRSLTE_MIN(lch[i].buf_retx, rem_tbs);
lch[i].buf_retx -= x; lch[i].buf_retx -= alloc_bytes;
} else if (lch[i].buf_tx) { } else if (lch[i].buf_tx > 0) {
x = SRSLTE_MIN(lch[i].buf_tx, tbs_bytes); alloc_bytes = SRSLTE_MIN(lch[i].buf_tx, rem_tbs);
lch[i].buf_tx -= x; lch[i].buf_tx -= alloc_bytes;
} }
} }
if (x) { if (alloc_bytes > 0) {
pdu->lcid = i - 1; mac_sdu->lcid = i - 1;
pdu->nbytes = x; mac_sdu->nbytes = alloc_bytes;
Debug("SCHED: Allocated lcid=%d, nbytes=%d, tbs_bytes=%d\n", pdu->lcid, pdu->nbytes, tbs_bytes); Debug("SCHED: Allocated lcid=%d, nbytes=%d, tbs_bytes=%d\n", mac_sdu->lcid, mac_sdu->nbytes, rem_tbs);
} }
return x; return alloc_bytes;
} }
uint32_t sched_ue::format1_count_prb(const rbgmask_t& bitmask, uint32_t cc_idx) uint32_t sched_ue::format1_count_prb(const rbgmask_t& bitmask, uint32_t cc_idx)

@ -23,6 +23,7 @@
#include "srsenb/hdr/stack/mac/scheduler_carrier.h" #include "srsenb/hdr/stack/mac/scheduler_carrier.h"
#include "srsenb/hdr/stack/mac/scheduler_ue.h" #include "srsenb/hdr/stack/mac/scheduler_ue.h"
#include <algorithm> #include <algorithm>
#include <chrono>
#include <random> #include <random>
#include <set> #include <set>
#include <srslte/srslte.h> #include <srslte/srslte.h>
@ -70,8 +71,8 @@
/*************************** /***************************
* Setup Random generators * Setup Random generators
**************************/ **************************/
uint32_t const seed = time(nullptr); uint32_t const seed = std::chrono::system_clock::now().time_since_epoch().count();
// uint32_t const seed = 2452071795; // [{3054, 1656}, {5970, 1595}, ... {204, 3}] // uint32_t const seed = 2452071795;
// uint32_t const seed = 1581009287; // prb==25 // uint32_t const seed = 1581009287; // prb==25
std::default_random_engine rand_gen(seed); std::default_random_engine rand_gen(seed);
std::uniform_real_distribution<float> unif_dist(0, 1.0); std::uniform_real_distribution<float> unif_dist(0, 1.0);
@ -910,16 +911,17 @@ int sched_tester::ack_txs()
srsenb::sched_interface::cell_cfg_t generate_cell_cfg() srsenb::sched_interface::cell_cfg_t generate_cell_cfg()
{ {
srsenb::sched_interface::cell_cfg_t cell_cfg; srsenb::sched_interface::cell_cfg_t cell_cfg = {};
srslte_cell_t& cell_cfg_phy = cell_cfg.cell; srslte_cell_t& cell_cfg_phy = cell_cfg.cell;
bzero(&cell_cfg, sizeof(srsenb::sched_interface::cell_cfg_t)); std::uniform_int_distribution<uint32_t> dist_prb_idx(0, 5);
uint32_t prb_idx = dist_prb_idx(rand_gen);
/* Set PHY cell configuration */ /* Set PHY cell configuration */
cell_cfg_phy.id = 1; cell_cfg_phy.id = 1;
cell_cfg_phy.cp = SRSLTE_CP_NORM; cell_cfg_phy.cp = SRSLTE_CP_NORM;
cell_cfg_phy.nof_ports = 1; cell_cfg_phy.nof_ports = 1;
cell_cfg_phy.nof_prb = 6; cell_cfg_phy.nof_prb = std::array<uint32_t, 6>({6, 15, 25, 50, 75, 100})[prb_idx];
cell_cfg_phy.phich_length = SRSLTE_PHICH_NORM; cell_cfg_phy.phich_length = SRSLTE_PHICH_NORM;
cell_cfg_phy.phich_resources = SRSLTE_PHICH_R_1; cell_cfg_phy.phich_resources = SRSLTE_PHICH_R_1;

Loading…
Cancel
Save