implemented DL logical channel prioritization test for finite PBRs

master
Francisco Paisana 4 years ago
parent 2d3681699a
commit c5c7700cb7

@ -32,7 +32,7 @@ namespace srsenb {
* Constants * Constants
**********************/ **********************/
constexpr uint32_t tti_duration_ms = 1000; constexpr float tti_duration_ms = 1;
/*********************** /***********************
* Helper Types * Helper Types

@ -1626,11 +1626,6 @@ int lch_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int rem
} }
if (alloc_bytes > 0) { if (alloc_bytes > 0) {
// Update Bj
if (lch[lcid].cfg.pbr != pbr_infinity) {
lch[lcid].Bj -= alloc_bytes;
}
rlc_pdu->nbytes = alloc_bytes; rlc_pdu->nbytes = alloc_bytes;
rlc_pdu->lcid = lcid; rlc_pdu->lcid = lcid;
Debug("SCHED: Allocated lcid=%d, nbytes=%d, tbs_bytes=%d\n", rlc_pdu->lcid, rlc_pdu->nbytes, rem_bytes); Debug("SCHED: Allocated lcid=%d, nbytes=%d, tbs_bytes=%d\n", rlc_pdu->lcid, rlc_pdu->nbytes, rem_bytes);
@ -1649,6 +1644,10 @@ int lch_manager::alloc_tx_bytes(uint8_t lcid, uint32_t rem_bytes)
{ {
int alloc = std::min((int)rem_bytes, get_dl_tx(lcid)); int alloc = std::min((int)rem_bytes, get_dl_tx(lcid));
lch[lcid].buf_tx -= alloc; lch[lcid].buf_tx -= alloc;
if (alloc > 0 and lch[lcid].cfg.pbr != pbr_infinity) {
// Update Bj
lch[lcid].Bj -= alloc;
}
return alloc; return alloc;
} }

@ -27,31 +27,38 @@
using namespace srsenb; using namespace srsenb;
const uint32_t seed = std::chrono::system_clock::now().time_since_epoch().count(); const uint32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
int test_retx_prb_inf(srsenb::lch_manager& lch_handler, int lcid, uint32_t pdu_size) /// Tests if a PDU was allocated with lcid and pdu_size bytes
int test_pdu_alloc_successful(srsenb::lch_manager& lch_handler,
sched_interface::dl_sched_pdu_t& pdu,
int lcid,
uint32_t pdu_size)
{
TESTASSERT(lch_handler.get_max_prio_lcid() == lcid);
TESTASSERT(lch_handler.alloc_rlc_pdu(&pdu, pdu_size) == (int)pdu_size);
TESTASSERT(pdu.lcid == (uint32_t)lcid);
TESTASSERT(pdu.nbytes == pdu_size);
return SRSLTE_SUCCESS;
}
int test_retx_until_empty(srsenb::lch_manager& lch_handler, int lcid, uint32_t pdu_size)
{ {
uint32_t nof_pdus = lch_handler.get_dl_retx(lcid) / pdu_size; uint32_t nof_pdus = lch_handler.get_dl_retx(lcid) / pdu_size;
sched_interface::dl_sched_pdu_t pdu; sched_interface::dl_sched_pdu_t pdu;
for (uint32_t i = 0; i < nof_pdus; ++i) { for (uint32_t i = 0; i < nof_pdus; ++i) {
TESTASSERT(lch_handler.get_max_prio_lcid() == lcid); TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, lcid, pdu_size) == SRSLTE_SUCCESS);
TESTASSERT(lch_handler.alloc_rlc_pdu(&pdu, pdu_size) == (int)pdu_size);
TESTASSERT(pdu.lcid == (uint32_t)lcid);
TESTASSERT(pdu.nbytes == pdu_size);
TESTASSERT(lch_handler.get_dl_retx(lcid) == (int)((nof_pdus - i - 1) * pdu_size)); TESTASSERT(lch_handler.get_dl_retx(lcid) == (int)((nof_pdus - i - 1) * pdu_size));
} }
return nof_pdus * pdu_size; return nof_pdus * pdu_size;
} }
int test_newtx_prb_inf(srsenb::lch_manager& lch_handler, int lcid, uint32_t pdu_size) int test_newtx_until_empty(srsenb::lch_manager& lch_handler, int lcid, uint32_t pdu_size)
{ {
uint32_t nof_pdus = lch_handler.get_dl_tx(lcid) / pdu_size; uint32_t nof_pdus = lch_handler.get_dl_tx(lcid) / pdu_size;
sched_interface::dl_sched_pdu_t pdu; sched_interface::dl_sched_pdu_t pdu;
for (uint32_t i = 0; i < nof_pdus; ++i) { for (uint32_t i = 0; i < nof_pdus; ++i) {
TESTASSERT(lch_handler.get_max_prio_lcid() == lcid); TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, lcid, pdu_size) == SRSLTE_SUCCESS);
TESTASSERT(lch_handler.alloc_rlc_pdu(&pdu, pdu_size) == (int)pdu_size);
TESTASSERT(pdu.lcid == (uint32_t)lcid);
TESTASSERT(pdu.nbytes == pdu_size);
TESTASSERT(lch_handler.get_dl_tx(lcid) == (int)((nof_pdus - i - 1) * pdu_size)); TESTASSERT(lch_handler.get_dl_tx(lcid) == (int)((nof_pdus - i - 1) * pdu_size));
} }
return nof_pdus * pdu_size; return nof_pdus * pdu_size;
@ -81,27 +88,92 @@ int test_lc_ch_pbr_infinity()
// TEST1 - retx of SRB1 is prioritized. Do not transmit other bearers until there are no SRB1 retxs // 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(srsenb::RB_ID_SRB1); int nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_SRB1);
TESTASSERT(test_retx_prb_inf(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes); TESTASSERT(test_retx_until_empty(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes);
// TEST2 - the DRB2 has lower prio level than SRB1, but has retxs // TEST2 - the DRB2 has lower prio level than SRB1, but has retxs
nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_DRB2); nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_DRB2);
TESTASSERT(test_retx_prb_inf(lch_handler, srsenb::RB_ID_DRB2, 500) == nof_pending_bytes); TESTASSERT(test_retx_until_empty(lch_handler, srsenb::RB_ID_DRB2, 500) == nof_pending_bytes);
// TEST3 - the DRB1 has lower prio level, but has retxs // TEST3 - the DRB1 has lower prio level, but has retxs
nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_DRB1); nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_DRB1);
TESTASSERT(test_retx_prb_inf(lch_handler, srsenb::RB_ID_DRB1, 500) == nof_pending_bytes); TESTASSERT(test_retx_until_empty(lch_handler, srsenb::RB_ID_DRB1, 500) == nof_pending_bytes);
// TEST4 - The SRB1 newtx buffer is emptied before other bearers newtxs // TEST4 - The SRB1 newtx buffer is emptied before other bearers newtxs
nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_SRB1); nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_SRB1);
TESTASSERT(test_newtx_prb_inf(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes); TESTASSERT(test_newtx_until_empty(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes);
// TEST5 - The DRB2 newtx buffer is emptied before DRB1 newtxs // TEST5 - The DRB2 newtx buffer is emptied before DRB1 newtxs
nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_DRB2); nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_DRB2);
TESTASSERT(test_newtx_prb_inf(lch_handler, srsenb::RB_ID_DRB2, 500) == nof_pending_bytes); TESTASSERT(test_newtx_until_empty(lch_handler, srsenb::RB_ID_DRB2, 500) == nof_pending_bytes);
// TEST6 - The DRB1 buffer is emptied // TEST6 - The DRB1 buffer is emptied
nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_DRB1); nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_DRB1);
TESTASSERT(test_newtx_prb_inf(lch_handler, srsenb::RB_ID_DRB1, 500) == nof_pending_bytes); TESTASSERT(test_newtx_until_empty(lch_handler, srsenb::RB_ID_DRB1, 500) == nof_pending_bytes);
return SRSLTE_SUCCESS;
}
int test_lc_ch_pbr_finite()
{
srsenb::lch_manager lch_handler;
sched_interface::dl_sched_pdu_t pdu;
srsenb::sched_interface::ue_cfg_t ue_cfg = generate_default_ue_cfg();
ue_cfg = generate_setup_ue_cfg(ue_cfg);
ue_cfg.ue_bearers[srsenb::RB_ID_SRB1] = {};
ue_cfg.ue_bearers[srsenb::RB_ID_SRB1].direction = sched_interface::ue_bearer_cfg_t::BOTH;
ue_cfg.ue_bearers[srsenb::RB_ID_DRB1] = {};
ue_cfg.ue_bearers[srsenb::RB_ID_DRB1].direction = sched_interface::ue_bearer_cfg_t::BOTH;
ue_cfg.ue_bearers[srsenb::RB_ID_DRB1].pbr = 256; // kBps
ue_cfg.ue_bearers[srsenb::RB_ID_DRB1].bsd = 50; // msec
ue_cfg.ue_bearers[srsenb::RB_ID_DRB1].priority = 5;
ue_cfg.ue_bearers[srsenb::RB_ID_DRB2] = {};
ue_cfg.ue_bearers[srsenb::RB_ID_DRB2].direction = sched_interface::ue_bearer_cfg_t::BOTH;
ue_cfg.ue_bearers[srsenb::RB_ID_DRB2].pbr = 8; // kBps
ue_cfg.ue_bearers[srsenb::RB_ID_DRB2].bsd = 50; // msec
ue_cfg.ue_bearers[srsenb::RB_ID_DRB2].priority = 3;
lch_handler.set_cfg(ue_cfg);
for (uint32_t i = 0; i < 50; ++i) {
lch_handler.new_tti();
}
// Bj={0, infinity, 0, 12800, 400}
lch_handler.dl_buffer_state(srsenb::RB_ID_SRB1, 50000, 1000);
lch_handler.dl_buffer_state(srsenb::RB_ID_DRB1, 50000, 1000);
lch_handler.dl_buffer_state(srsenb::RB_ID_DRB2, 50000, 0);
// TEST1 - SRB1 retxs are emptied first
int nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_SRB1);
TESTASSERT(test_retx_until_empty(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes);
// TEST2 - DRB1 retxs are emptied
nof_pending_bytes = lch_handler.get_dl_retx(srsenb::RB_ID_DRB1);
TESTASSERT(test_retx_until_empty(lch_handler, srsenb::RB_ID_DRB1, 500) == nof_pending_bytes);
// TEST3 - SRB1 newtxs are emptied (PBR==infinity)
nof_pending_bytes = lch_handler.get_dl_tx(srsenb::RB_ID_SRB1);
TESTASSERT(test_newtx_until_empty(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes);
// TEST4 - DRB2 has higher priority so it gets allocated until Bj <= 0
TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, srsenb::RB_ID_DRB2, 200) == SRSLTE_SUCCESS);
// Bj={0, infinity, 0, 12800, 200}
TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, srsenb::RB_ID_DRB2, 600) == SRSLTE_SUCCESS);
// Bj={0, infinity, 0, 256000, -400}
// TEST5 - DRB1 has lower prio, but DRB2 Bj <= 0.
for (uint32_t i = 0; i < 50; ++i) {
lch_handler.new_tti();
TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, srsenb::RB_ID_DRB1, 50) == SRSLTE_SUCCESS);
}
// TEST6 - new tti restores DRB2 Bj>=0, and DRB2 gets allocated
lch_handler.new_tti();
// Bj={0, infinity, 0, 256000, 8}
TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, srsenb::RB_ID_DRB2, 50) == SRSLTE_SUCCESS);
// Bj={0, infinity, 0, 256000, -42}
lch_handler.new_tti();
TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, srsenb::RB_ID_DRB1, 50) == SRSLTE_SUCCESS);
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -113,5 +185,6 @@ int main()
srslte::logmap::get("TEST")->set_level(srslte::LOG_LEVEL_INFO); srslte::logmap::get("TEST")->set_level(srslte::LOG_LEVEL_INFO);
TESTASSERT(test_lc_ch_pbr_infinity() == SRSLTE_SUCCESS); TESTASSERT(test_lc_ch_pbr_infinity() == SRSLTE_SUCCESS);
TESTASSERT(test_lc_ch_pbr_finite() == SRSLTE_SUCCESS);
srslte::console("Success\n"); srslte::console("Success\n");
} }

Loading…
Cancel
Save