added test for DL sched logical channel prioritization. At the moment only PBR=infinity is tested

master
Francisco Paisana 4 years ago
parent 9b10acff06
commit 2d3681699a

@ -1563,15 +1563,30 @@ void lch_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx
int lch_manager::get_max_prio_lcid() const int lch_manager::get_max_prio_lcid() const
{ {
int min_prio_val = std::numeric_limits<int>::max(), prio_lcid = -1; int min_prio_val = std::numeric_limits<int>::max(), prio_lcid = -1;
// Prioritize retxs
for (uint32_t lcid = 0; lcid < MAX_LC; ++lcid) {
if (get_dl_retx(lcid) > 0 and lch[lcid].cfg.priority < min_prio_val) {
min_prio_val = lch[lcid].cfg.priority;
prio_lcid = lcid;
}
}
if (prio_lcid >= 0) {
return prio_lcid;
}
// Select lcid with new txs using Bj
for (uint32_t lcid = 0; lcid < MAX_LC; ++lcid) { for (uint32_t lcid = 0; lcid < MAX_LC; ++lcid) {
if (get_dl_tx_total(lcid) > 0 and lch[lcid].Bj > 0 and lch[lcid].cfg.priority < min_prio_val) { if (get_dl_tx(lcid) > 0 and lch[lcid].Bj > 0 and lch[lcid].cfg.priority < min_prio_val) {
min_prio_val = lch[lcid].cfg.priority; min_prio_val = lch[lcid].cfg.priority;
prio_lcid = lcid; prio_lcid = lcid;
} }
} }
if (prio_lcid >= 0) {
return prio_lcid;
}
if (prio_lcid < 0) { // Disregard Bj
// disregard Bj value in selection of lcid
size_t nof_lcids = 0; size_t nof_lcids = 0;
std::array<uint32_t, MAX_LC> chosen_lcids = {}; std::array<uint32_t, MAX_LC> chosen_lcids = {};
for (uint32_t lcid = 0; lcid < MAX_LC; ++lcid) { for (uint32_t lcid = 0; lcid < MAX_LC; ++lcid) {
@ -1589,7 +1604,6 @@ int lch_manager::get_max_prio_lcid() const
if (nof_lcids > 0) { if (nof_lcids > 0) {
prio_lcid = chosen_lcids[prio_idx % nof_lcids]; prio_lcid = chosen_lcids[prio_idx % nof_lcids];
} }
}
return prio_lcid; return prio_lcid;
} }

@ -56,3 +56,6 @@ target_link_libraries(scheduler_ca_test srsenb_mac
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${Boost_LIBRARIES}) ${Boost_LIBRARIES})
add_test(scheduler_ca_test scheduler_ca_test) add_test(scheduler_ca_test scheduler_ca_test)
add_executable(sched_lc_ch_test sched_lc_ch_test.cc scheduler_test_common.cc)
target_link_libraries(sched_lc_ch_test srsenb_mac srslte_common srslte_mac scheduler_test_common)

@ -0,0 +1,117 @@
/*
* Copyright 2013-2020 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "scheduler_test_common.h"
#include "scheduler_test_utils.h"
#include "srsenb/hdr/stack/mac/scheduler_ue.h"
#include "srslte/common/test_common.h"
using namespace srsenb;
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)
{
uint32_t nof_pdus = lch_handler.get_dl_retx(lcid) / pdu_size;
sched_interface::dl_sched_pdu_t pdu;
for (uint32_t i = 0; i < nof_pdus; ++i) {
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);
TESTASSERT(lch_handler.get_dl_retx(lcid) == (int)((nof_pdus - i - 1) * pdu_size));
}
return nof_pdus * pdu_size;
}
int test_newtx_prb_inf(srsenb::lch_manager& lch_handler, int lcid, uint32_t pdu_size)
{
uint32_t nof_pdus = lch_handler.get_dl_tx(lcid) / pdu_size;
sched_interface::dl_sched_pdu_t pdu;
for (uint32_t i = 0; i < nof_pdus; ++i) {
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);
TESTASSERT(lch_handler.get_dl_tx(lcid) == (int)((nof_pdus - i - 1) * pdu_size));
}
return nof_pdus * pdu_size;
}
int test_lc_ch_pbr_infinity()
{
srsenb::lch_manager lch_handler;
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].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].priority = 3;
lch_handler.set_cfg(ue_cfg);
lch_handler.new_tti();
lch_handler.dl_buffer_state(srsenb::RB_ID_SRB1, 50000, 10000);
lch_handler.dl_buffer_state(srsenb::RB_ID_DRB1, 5000, 10000);
lch_handler.dl_buffer_state(srsenb::RB_ID_DRB2, 5000, 10000);
// 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);
TESTASSERT(test_retx_prb_inf(lch_handler, srsenb::RB_ID_SRB1, 500) == nof_pending_bytes);
// TEST2 - the DRB2 has lower prio level than SRB1, but has retxs
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);
// TEST3 - the DRB1 has lower prio level, but has retxs
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);
// TEST4 - The SRB1 newtx buffer is emptied before other bearers newtxs
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);
// TEST5 - The DRB2 newtx buffer is emptied before DRB1 newtxs
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);
// TEST6 - The DRB1 buffer is emptied
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);
return SRSLTE_SUCCESS;
}
int main()
{
srsenb::set_randseed(seed);
srslte::console("This is the chosen seed: %u\n", seed);
srslte::logmap::get("TEST")->set_level(srslte::LOG_LEVEL_INFO);
TESTASSERT(test_lc_ch_pbr_infinity() == SRSLTE_SUCCESS);
srslte::console("Success\n");
}

@ -116,7 +116,7 @@ inline srsenb::sched_interface::ue_cfg_t generate_setup_ue_cfg(const srsenb::sch
inline srsenb::sched_interface::ue_cfg_t generate_reconf_ue_cfg(const srsenb::sched_interface::ue_cfg_t& final_cfg) inline srsenb::sched_interface::ue_cfg_t generate_reconf_ue_cfg(const srsenb::sched_interface::ue_cfg_t& final_cfg)
{ {
srsenb::sched_interface::ue_cfg_t cfg = final_cfg; srsenb::sched_interface::ue_cfg_t cfg = generate_setup_ue_cfg(final_cfg);
cfg.supported_cc_list.resize(1); cfg.supported_cc_list.resize(1);
cfg.ue_bearers = {}; cfg.ue_bearers = {};

Loading…
Cancel
Save