moved dl/ul scheduling to the a separate class carrier_sched

master
Francisco Paisana 5 years ago
parent 00d24872d9
commit 2019fec37a

@ -48,11 +48,6 @@ inline bool is_in_tti_interval(uint32_t tti, uint32_t tti1, uint32_t tti2)
return tti >= tti1 or tti <= tti2; return tti >= tti1 or tti <= tti2;
} }
inline uint32_t tti_subtract(uint32_t tti1, uint32_t tti2)
{
return (tti1 + 10240 - tti2) % 10240;
}
} // namespace sched_utils } // namespace sched_utils
/* Caution: User addition (ue_cfg) and removal (ue_rem) are not thread-safe /* Caution: User addition (ue_cfg) and removal (ue_rem) are not thread-safe
@ -152,8 +147,6 @@ public:
static uint32_t aggr_level(uint32_t aggr_idx) { return 1u << aggr_idx; } static uint32_t aggr_level(uint32_t aggr_idx) { return 1u << aggr_idx; }
protected: protected:
metric_dl* dl_metric;
metric_ul* ul_metric;
srslte::log* log_h; srslte::log* log_h;
rrc_interface_mac* rrc; rrc_interface_mac* rrc;
@ -166,8 +159,9 @@ protected:
// This is for computing DCI locations // This is for computing DCI locations
srslte_regs_t regs; srslte_regs_t regs;
class bc_sched_t; class carrier_sched;
class ra_sched_t; class ra_sched_t;
class bc_sched_t;
class tti_sched_result_t : public dl_tti_sched_t, public ul_tti_sched_t class tti_sched_result_t : public dl_tti_sched_t, public ul_tti_sched_t
{ {
@ -271,16 +265,6 @@ protected:
std::vector<ul_alloc_t> ul_data_allocs; std::vector<ul_alloc_t> ul_data_allocs;
}; };
std::array<tti_sched_result_t, 10> tti_scheds;
tti_sched_result_t* get_tti_sched(uint32_t tti_rx) { return &tti_scheds[tti_rx % tti_scheds.size()]; }
std::vector<uint8_t> tti_dl_mask;
tti_sched_result_t* new_tti(uint32_t tti_rx);
void generate_phich(tti_sched_result_t* tti_sched);
int generate_dl_sched(tti_sched_result_t* tti_sched);
int generate_ul_sched(tti_sched_result_t* tti_sched);
void dl_sched_data(tti_sched_result_t* tti_sched);
// Helper methods // Helper methods
template <typename Func> template <typename Func>
int ue_db_access(uint16_t rnti, Func); int ue_db_access(uint16_t rnti, Func);
@ -297,8 +281,8 @@ protected:
prbmask_t prach_mask; prbmask_t prach_mask;
prbmask_t pucch_mask; prbmask_t pucch_mask;
std::unique_ptr<bc_sched_t> bc_sched; // independent schedulers for each carrier
std::unique_ptr<ra_sched_t> rar_sched; std::vector<carrier_sched> carrier_schedulers;
std::array<uint32_t, 10> pdsch_re; std::array<uint32_t, 10> pdsch_re;
uint32_t current_tti; uint32_t current_tti;

@ -97,6 +97,41 @@ private:
uint32_t rar_aggr_level = 2; uint32_t rar_aggr_level = 2;
}; };
class sched::carrier_sched
{
public:
explicit carrier_sched(sched* sched_);
void init();
void reset();
void cell_cfg();
void set_metric(sched::metric_dl* dl_metric_, sched::metric_ul* ul_metric_);
void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs);
sched::tti_sched_result_t* generate_tti_result(uint32_t tti_rx);
// private:
void generate_phich(tti_sched_result_t* tti_sched);
//! Compute DL scheduler result for given TTI
int generate_dl_sched(tti_sched_result_t* tti_result);
//! Compute UL scheduler result for given TTI
int generate_ul_sched(tti_sched_result_t* tti_sched);
// args
sched* sched_ptr = nullptr;
srslte::log* log_h = nullptr;
cell_cfg_t* cfg = nullptr;
metric_dl* dl_metric = nullptr;
metric_ul* ul_metric = nullptr;
// TTI result storage and management
std::array<tti_sched_result_t, 10> tti_scheds;
tti_sched_result_t* get_tti_sched(uint32_t tti_rx) { return &tti_scheds[tti_rx % tti_scheds.size()]; }
std::vector<uint8_t> tti_dl_mask; ///< Some TTIs may be forbidden for DL sched due to MBMS
std::unique_ptr<sched::bc_sched_t> bc_sched;
std::unique_ptr<sched::ra_sched_t> ra_sched;
};
} // namespace srsenb } // namespace srsenb
#endif // SRSLTE_SCHEDULER_CTRL_H #endif // SRSLTE_SCHEDULER_CTRL_H

@ -34,6 +34,20 @@
namespace srsenb { namespace srsenb {
namespace sched_utils {
uint32_t tti_subtract(uint32_t tti1, uint32_t tti2)
{
return (tti1 + 10240 - tti2) % 10240;
}
uint32_t max_tti(uint32_t tti1, uint32_t tti2)
{
return ((tti1 - tti2) > 10240 / 2) ? SRSLTE_MIN(tti1, tti2) : SRSLTE_MAX(tti1, tti2);
}
} // namespace sched_utils
/******************************************************* /*******************************************************
* TTI resource Scheduling Methods * TTI resource Scheduling Methods
*******************************************************/ *******************************************************/
@ -356,7 +370,7 @@ void sched::tti_sched_result_t::set_rar_sched_result(const pdcch_grid_t::alloc_r
// Print RAR allocation result // Print RAR allocation result
for (uint32_t i = 0; i < rar->nof_grants; ++i) { for (uint32_t i = 0; i < rar->nof_grants; ++i) {
const auto& msg3_grant = rar->msg3_grant[i]; const auto& msg3_grant = rar->msg3_grant[i];
uint16_t expected_rnti = parent->rar_sched->find_pending_msg3(get_tti_tx_dl() + MSG3_DELAY_MS + TX_DELAY).rnti; uint16_t expected_rnti = parent->carrier_schedulers[0].ra_sched->find_pending_msg3(get_tti_tx_dl() + MSG3_DELAY_MS + TX_DELAY).rnti;
log_h->info("SCHED: RAR, temp_crnti=0x%x, ra-rnti=%d, rbgs=(%d,%d), dci=(%d,%d), rar_grant_rba=%d, " log_h->info("SCHED: RAR, temp_crnti=0x%x, ra-rnti=%d, rbgs=(%d,%d), dci=(%d,%d), rar_grant_rba=%d, "
"rar_grant_mcs=%d\n", "rar_grant_mcs=%d\n",
expected_rnti, expected_rnti,
@ -569,12 +583,10 @@ int sched::tti_sched_result_t::generate_format1a(
* Initialization and sched configuration functions * Initialization and sched configuration functions
* *
*******************************************************/ *******************************************************/
sched::sched() : P(0), nof_rbg(0), bc_sched(new bc_sched_t{&cfg}), rar_sched(new ra_sched_t{&cfg}) sched::sched() : P(0), nof_rbg(0)
{ {
current_tti = 0; current_tti = 0;
log_h = nullptr; log_h = nullptr;
dl_metric = nullptr;
ul_metric = nullptr;
rrc = nullptr; rrc = nullptr;
bzero(&cfg, sizeof(cfg)); bzero(&cfg, sizeof(cfg));
@ -582,7 +594,6 @@ sched::sched() : P(0), nof_rbg(0), bc_sched(new bc_sched_t{&cfg}), rar_sched(new
bzero(&sched_cfg, sizeof(sched_cfg)); bzero(&sched_cfg, sizeof(sched_cfg));
bzero(&common_locations, sizeof(common_locations)); bzero(&common_locations, sizeof(common_locations));
bzero(&pdsch_re, sizeof(pdsch_re)); bzero(&pdsch_re, sizeof(pdsch_re));
tti_dl_mask.resize(10, 0);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
bzero(rar_locations[i], sizeof(sched_ue::sched_dci_cce_t) * 10); bzero(rar_locations[i], sizeof(sched_ue::sched_dci_cce_t) * 10);
@ -590,6 +601,9 @@ sched::sched() : P(0), nof_rbg(0), bc_sched(new bc_sched_t{&cfg}), rar_sched(new
pthread_rwlock_init(&rwlock, nullptr); pthread_rwlock_init(&rwlock, nullptr);
// Initialize Independent carrier schedulers
carrier_schedulers.emplace_back(this);
reset(); reset();
} }
@ -612,18 +626,17 @@ void sched::init(rrc_interface_mac* rrc_, srslte::log* log)
log_h = log; log_h = log;
rrc = rrc_; rrc = rrc_;
bc_sched->init(rrc); for (carrier_sched& c : carrier_schedulers) {
rar_sched->init(log_h, ue_db); c.init();
}
reset(); reset();
} }
int sched::reset() int sched::reset()
{ {
configured = false; configured = false;
{ for (carrier_sched& c : carrier_schedulers) {
std::lock_guard<std::mutex> lock(sched_mutex); c.reset();
rar_sched->reset();
bc_sched->reset();
} }
pthread_rwlock_wrlock(&rwlock); pthread_rwlock_wrlock(&rwlock);
ue_db.clear(); ue_db.clear();
@ -640,10 +653,9 @@ void sched::set_sched_cfg(sched_interface::sched_args_t* sched_cfg_)
void sched::set_metric(sched::metric_dl* dl_metric_, sched::metric_ul* ul_metric_) void sched::set_metric(sched::metric_dl* dl_metric_, sched::metric_ul* ul_metric_)
{ {
dl_metric = dl_metric_; for (carrier_sched& c : carrier_schedulers) {
ul_metric = ul_metric_; c.set_metric(dl_metric_, ul_metric_);
dl_metric->set_log(log_h); }
ul_metric->set_log(log_h);
} }
int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg) int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg)
@ -685,8 +697,8 @@ int sched::cell_cfg(sched_interface::cell_cfg_t* cell_cfg)
} }
// Initiate the tti_scheduler for each TTI // Initiate the tti_scheduler for each TTI
for (tti_sched_result_t& tti_sched : tti_scheds) { for (carrier_sched& c : carrier_schedulers) {
tti_sched.init(this); c.cell_cfg();
} }
configured = true; configured = true;
@ -761,6 +773,7 @@ void sched::ue_needs_ta_cmd(uint16_t rnti, uint32_t nof_ta_cmd) {
void sched::phy_config_enabled(uint16_t rnti, bool enabled) void sched::phy_config_enabled(uint16_t rnti, bool enabled)
{ {
// FIXME: Check if correct use of current_tti
ue_db_access(rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(current_tti, enabled); }); ue_db_access(rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(current_tti, enabled); });
} }
@ -776,6 +789,7 @@ int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id)
uint32_t sched::get_dl_buffer(uint16_t rnti) uint32_t sched::get_dl_buffer(uint16_t rnti)
{ {
// FIXME: Check if correct use of current_tti
uint32_t ret = 0; uint32_t ret = 0;
ue_db_access(rnti, [this, &ret](sched_ue& ue) { ret = ue.get_pending_dl_new_data(current_tti); }); ue_db_access(rnti, [this, &ret](sched_ue& ue) { ret = ue.get_pending_dl_new_data(current_tti); });
return ret; return ret;
@ -783,6 +797,7 @@ uint32_t sched::get_dl_buffer(uint16_t rnti)
uint32_t sched::get_ul_buffer(uint16_t rnti) uint32_t sched::get_ul_buffer(uint16_t rnti)
{ {
// FIXME: Check if correct use of current_tti
uint32_t ret = 0; uint32_t ret = 0;
ue_db_access(rnti, [this, &ret](sched_ue& ue) { ret = ue.get_pending_ul_new_data(current_tti); }); ue_db_access(rnti, [this, &ret](sched_ue& ue) { ret = ue.get_pending_ul_new_data(current_tti); });
return ret; return ret;
@ -834,7 +849,7 @@ int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value)
int sched::dl_rach_info(dl_sched_rar_info_t rar_info) int sched::dl_rach_info(dl_sched_rar_info_t rar_info)
{ {
std::lock_guard<std::mutex> lock(sched_mutex); std::lock_guard<std::mutex> lock(sched_mutex);
return rar_sched->dl_rach_info(rar_info); return carrier_schedulers[0].ra_sched->dl_rach_info(rar_info);
} }
int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code) int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code)
@ -864,7 +879,7 @@ int sched::ul_sr_info(uint32_t tti, uint16_t rnti)
void sched::set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) void sched::set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs)
{ {
tti_dl_mask.assign(tti_mask, tti_mask + nof_sfs); carrier_schedulers[0].set_dl_tti_mask(tti_mask, nof_sfs);
} }
void sched::tpc_inc(uint16_t rnti) void sched::tpc_inc(uint16_t rnti)
@ -883,137 +898,6 @@ void sched::tpc_dec(uint16_t rnti)
* *
*******************************************************/ *******************************************************/
sched::tti_sched_result_t* sched::new_tti(uint32_t tti_rx)
{
tti_sched_result_t* tti_sched = get_tti_sched(tti_rx);
// if it is the first time tti is run, reset vars
if (tti_rx != tti_sched->get_tti_rx()) {
uint32_t start_cfi = sched_cfg.nof_ctrl_symbols;
tti_sched->new_tti(tti_rx, start_cfi);
// Protects access to pending_rar[], pending_msg3[], pending_sibs[], rlc buffers
std::lock_guard<std::mutex> lock(sched_mutex);
pthread_rwlock_rdlock(&rwlock);
/* Schedule PHICH */
generate_phich(tti_sched);
/* Schedule DL */
if (tti_dl_mask[tti_sched->get_tti_tx_dl() % tti_dl_mask.size()] == 0) {
generate_dl_sched(tti_sched);
}
/* Schedule UL */
generate_ul_sched(tti_sched);
/* Generate DCI */
tti_sched->generate_dcis();
/* reset PIDs with pending data or blocked */
for (auto& user : ue_db) {
user.second.reset_pending_pids(tti_rx);
}
pthread_rwlock_unlock(&rwlock);
}
return tti_sched;
}
void sched::dl_sched_data(tti_sched_result_t* tti_sched)
{
// NOTE: In case of 6 PRBs, do not transmit if there is going to be a PRACH in the UL to avoid collisions
uint32_t tti_rx_ack = TTI_RX_ACK(tti_sched->get_tti_rx());
bool msg3_enabled = rar_sched->find_pending_msg3(tti_rx_ack).enabled;
if (cfg.cell.nof_prb == 6 and
(srslte_prach_tti_opportunity_config_fdd(cfg.prach_config, tti_rx_ack, -1) or msg3_enabled)) {
tti_sched->get_dl_mask().fill(0, tti_sched->get_dl_mask().size());
}
// call scheduler metric to fill RB grid
dl_metric->sched_users(ue_db, tti_sched);
}
// Compute DL scheduler result
int sched::generate_dl_sched(tti_sched_result_t* tti_sched)
{
/* Initialize variables */
current_tti = tti_sched->get_tti_tx_dl();
/* Schedule Broadcast data (SIB and paging) */
bc_sched->dl_sched(tti_sched);
/* Schedule RAR */
rar_sched->dl_sched(tti_sched);
/* Schedule pending RLC data */
dl_sched_data(tti_sched);
return 0;
}
void sched::generate_phich(tti_sched_result_t* tti_sched)
{
// Allocate user PHICHs
uint32_t nof_phich_elems = 0;
for (auto& ue_pair : ue_db) {
sched_ue& user = ue_pair.second;
uint16_t rnti = ue_pair.first;
// user.has_pucch = false; // FIXME: What is this for?
ul_harq_proc* h = user.get_ul_harq(tti_sched->get_tti_rx());
/* Indicate PHICH acknowledgment if needed */
if (h->has_pending_ack()) {
tti_sched->ul_sched_result.phich[nof_phich_elems].phich =
h->get_pending_ack() ? ul_sched_phich_t::ACK : ul_sched_phich_t::NACK;
tti_sched->ul_sched_result.phich[nof_phich_elems].rnti = rnti;
log_h->debug("SCHED: Allocated PHICH for rnti=0x%x, value=%d\n",
rnti,
tti_sched->ul_sched_result.phich[nof_phich_elems].phich == ul_sched_phich_t::ACK);
nof_phich_elems++;
}
}
tti_sched->ul_sched_result.nof_phich_elems = nof_phich_elems;
}
// Compute UL scheduler result
int sched::generate_ul_sched(tti_sched_result_t* tti_sched)
{
/* Initialize variables */
current_tti = tti_sched->get_tti_tx_ul();
prbmask_t& ul_mask = tti_sched->get_ul_mask();
// reserve PRBs for PRACH
if (srslte_prach_tti_opportunity_config_fdd(cfg.prach_config, tti_sched->get_tti_tx_ul(), -1)) {
ul_mask = prach_mask;
log_h->debug("SCHED: Allocated PRACH RBs. Mask: 0x%s\n", prach_mask.to_hex().c_str());
}
// Update available allocation if there's a pending RAR
rar_sched->ul_sched(tti_sched);
// reserve PRBs for PUCCH
if (cfg.cell.nof_prb != 6 and (ul_mask & pucch_mask).any()) {
log_h->error("There was a collision with the PUCCH. current mask=0x%s, pucch_mask=0x%s\n",
ul_mask.to_hex().c_str(),
pucch_mask.to_hex().c_str());
}
ul_mask |= pucch_mask;
// Call scheduler for UL data
ul_metric->sched_users(ue_db, tti_sched);
// Update pending data counters after this TTI
for (auto& user : ue_db) {
user.second.get_ul_harq(tti_sched->get_tti_tx_ul())->reset_pending_data();
}
return SRSLTE_SUCCESS;
}
// Downlink Scheduler API // Downlink Scheduler API
int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result) int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result)
{ {
@ -1022,9 +906,10 @@ int sched::dl_sched(uint32_t tti, sched_interface::dl_sched_res_t* sched_result)
} }
uint32_t tti_rx = sched_utils::tti_subtract(tti, TX_DELAY); uint32_t tti_rx = sched_utils::tti_subtract(tti, TX_DELAY);
current_tti = sched_utils::max_tti(current_tti, tti_rx);
// Compute scheduling Result for tti_rx // Compute scheduling Result for tti_rx
tti_sched_result_t* tti_sched = new_tti(tti_rx); tti_sched_result_t* tti_sched = carrier_schedulers[0].generate_tti_result(tti_rx);
// copy result // copy result
*sched_result = tti_sched->dl_sched_result; *sched_result = tti_sched->dl_sched_result;
@ -1041,7 +926,7 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
// Compute scheduling Result for tti_rx // Compute scheduling Result for tti_rx
uint32_t tti_rx = sched_utils::tti_subtract(tti, 2 * FDD_HARQ_DELAY_MS); uint32_t tti_rx = sched_utils::tti_subtract(tti, 2 * FDD_HARQ_DELAY_MS);
tti_sched_result_t* tti_sched = new_tti(tti_rx); tti_sched_result_t* tti_sched = carrier_schedulers[0].generate_tti_result(tti_rx);
// Copy results // Copy results
*sched_result = tti_sched->ul_sched_result; *sched_result = tti_sched->ul_sched_result;

@ -264,4 +264,182 @@ const sched::ra_sched_t::pending_msg3_t& sched::ra_sched_t::find_pending_msg3(ui
return pending_msg3[pending_tti]; return pending_msg3[pending_tti];
} }
/*******************************************************
* Carrier scheduling
*******************************************************/
sched::carrier_sched::carrier_sched(sched* sched_) : sched_ptr(sched_), cfg(&sched_->cfg) {}
void sched::carrier_sched::init()
{
log_h = sched_ptr->log_h;
tti_dl_mask.resize(10, 0);
// FIXME check cfg
bc_sched.reset(new bc_sched_t{cfg});
ra_sched.reset(new ra_sched_t{cfg});
bc_sched->init(sched_ptr->rrc);
ra_sched->init(log_h, sched_ptr->ue_db);
}
void sched::carrier_sched::reset()
{
std::lock_guard<std::mutex> lock(sched_ptr->sched_mutex);
if (ra_sched != nullptr) {
ra_sched->reset();
}
if (bc_sched != nullptr) {
bc_sched->reset();
}
}
void sched::carrier_sched::cell_cfg()
{
// sched::cfg is now fully set
// Initiate the tti_scheduler for each TTI
for (tti_sched_result_t& tti_sched : tti_scheds) {
tti_sched.init(sched_ptr);
}
}
void sched::carrier_sched::set_metric(sched::metric_dl* dl_metric_, sched::metric_ul* ul_metric_)
{
dl_metric = dl_metric_;
ul_metric = ul_metric_;
dl_metric->set_log(log_h);
ul_metric->set_log(log_h);
}
void sched::carrier_sched::set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs)
{
tti_dl_mask.assign(tti_mask, tti_mask + nof_sfs);
}
sched::tti_sched_result_t* sched::carrier_sched::generate_tti_result(uint32_t tti_rx)
{
tti_sched_result_t* tti_sched = get_tti_sched(tti_rx);
// if it is the first time tti is run, reset vars
if (tti_rx != tti_sched->get_tti_rx()) {
uint32_t start_cfi = sched_ptr->sched_cfg.nof_ctrl_symbols - ((cfg->cell.nof_prb >= 10) ? 0 : 1);
tti_sched->new_tti(tti_rx, start_cfi);
// Protects access to pending_rar[], pending_msg3[], pending_sibs[], rlc buffers
std::lock_guard<std::mutex> lock(sched_ptr->sched_mutex);
pthread_rwlock_rdlock(&sched_ptr->rwlock);
/* Schedule PHICH */
generate_phich(tti_sched);
/* Schedule DL */
if (tti_dl_mask[tti_sched->get_tti_tx_dl() % tti_dl_mask.size()] == 0) {
generate_dl_sched(tti_sched);
}
/* Schedule UL */
generate_ul_sched(tti_sched);
/* Generate DCI */
tti_sched->generate_dcis();
/* reset PIDs with pending data or blocked */
for (auto& user : sched_ptr->ue_db) {
user.second.reset_pending_pids(tti_rx);
}
pthread_rwlock_unlock(&sched_ptr->rwlock);
}
return tti_sched;
}
void sched::carrier_sched::generate_phich(tti_sched_result_t* tti_sched)
{
// Allocate user PHICHs
uint32_t nof_phich_elems = 0;
for (auto& ue_pair : sched_ptr->ue_db) {
sched_ue& user = ue_pair.second;
uint16_t rnti = ue_pair.first;
// user.has_pucch = false; // FIXME: What is this for?
ul_harq_proc* h = user.get_ul_harq(tti_sched->get_tti_rx());
/* Indicate PHICH acknowledgment if needed */
if (h->has_pending_ack()) {
tti_sched->ul_sched_result.phich[nof_phich_elems].phich =
h->get_pending_ack() ? ul_sched_phich_t::ACK : ul_sched_phich_t::NACK;
tti_sched->ul_sched_result.phich[nof_phich_elems].rnti = rnti;
log_h->debug("SCHED: Allocated PHICH for rnti=0x%x, value=%d\n",
rnti,
tti_sched->ul_sched_result.phich[nof_phich_elems].phich);
nof_phich_elems++;
}
}
tti_sched->ul_sched_result.nof_phich_elems = nof_phich_elems;
}
int sched::carrier_sched::generate_dl_sched(tti_sched_result_t* tti_result)
{
/* Schedule Broadcast data (SIB and paging) */
if (bc_sched != nullptr) {
bc_sched->dl_sched(tti_result);
}
/* Schedule RAR */
ra_sched->dl_sched(tti_result);
/* Schedule pending RLC data */
// NOTE: In case of 6 PRBs, do not transmit if there is going to be a PRACH in the UL to avoid collisions
if (cfg->cell.nof_prb == 6) {
uint32_t tti_rx_ack = TTI_RX_ACK(tti_result->get_tti_rx());
bool msg3_enabled = false;
if (ra_sched != nullptr and ra_sched->find_pending_msg3(tti_rx_ack).enabled) {
msg3_enabled = true;
}
if (srslte_prach_tti_opportunity_config_fdd(cfg->prach_config, tti_rx_ack, -1) or msg3_enabled) {
tti_result->get_dl_mask().fill(0, tti_result->get_dl_mask().size());
}
}
// call scheduler metric to fill RB grid
dl_metric->sched_users(sched_ptr->ue_db, tti_result);
return LIBLTE_SUCCESS;
}
int sched::carrier_sched::generate_ul_sched(srsenb::sched::tti_sched_result_t* tti_result)
{
uint32_t tti_tx_ul = tti_result->get_tti_tx_ul();
prbmask_t& ul_mask = tti_result->get_ul_mask();
/* reserve PRBs for PRACH */
if (srslte_prach_tti_opportunity_config_fdd(cfg->prach_config, tti_tx_ul, -1)) {
ul_mask = sched_ptr->prach_mask;
log_h->debug("SCHED: Allocated PRACH RBs. Mask: 0x%s\n", sched_ptr->prach_mask.to_hex().c_str());
}
/* Allocate Msg3 if there's a pending RAR */
ra_sched->ul_sched(tti_result);
/* reserve PRBs for PUCCH */
if (cfg->cell.nof_prb != 6 and (ul_mask & sched_ptr->pucch_mask).any()) {
log_h->error("There was a collision with the PUCCH. current mask=0x%s, pucch_mask=0x%s\n",
ul_mask.to_hex().c_str(),
sched_ptr->pucch_mask.to_hex().c_str());
}
ul_mask |= sched_ptr->pucch_mask;
/* Call scheduler for UL data */
ul_metric->sched_users(sched_ptr->ue_db, tti_result);
/* Update pending data counters after this TTI */
for (auto& user : sched_ptr->ue_db) {
user.second.get_ul_harq(tti_tx_ul)->reset_pending_data();
}
return SRSLTE_SUCCESS;
}
} // namespace srsenb } // namespace srsenb

@ -281,7 +281,7 @@ void sched_tester::new_test_tti(uint32_t tti_)
} else { } else {
tti_data.ul_sf_idx = (tti_data.tti_tx_ul + 10240 - FDD_HARQ_DELAY_MS) % 10; tti_data.ul_sf_idx = (tti_data.tti_tx_ul + 10240 - FDD_HARQ_DELAY_MS) % 10;
} }
tti_data.ul_pending_msg3 = rar_sched->find_pending_msg3(tti_data.tti_tx_ul); tti_data.ul_pending_msg3 = carrier_schedulers[0].ra_sched->find_pending_msg3(tti_data.tti_tx_ul);
tti_data.current_cfi = sched_cfg.nof_ctrl_symbols; tti_data.current_cfi = sched_cfg.nof_ctrl_symbols;
tti_data.used_cce.resize(srslte_regs_pdcch_ncce(&regs, tti_data.current_cfi)); tti_data.used_cce.resize(srslte_regs_pdcch_ncce(&regs, tti_data.current_cfi));
tti_data.used_cce.reset(); tti_data.used_cce.reset();
@ -494,7 +494,7 @@ void sched_tester::assert_no_empty_allocs()
*/ */
void sched_tester::test_tti_result() void sched_tester::test_tti_result()
{ {
tti_sched_result_t* tti_sched = get_tti_sched(tti_data.tti_rx); tti_sched_result_t* tti_sched = carrier_schedulers[0].get_tti_sched(tti_data.tti_rx);
// Helper Function: checks if there is any collision. If not, fills the mask // Helper Function: checks if there is any collision. If not, fills the mask
auto try_cce_fill = [&](const srslte_dci_location_t& dci_loc, const char* ch) { auto try_cce_fill = [&](const srslte_dci_location_t& dci_loc, const char* ch) {
@ -546,7 +546,7 @@ void sched_tester::test_tti_result()
for (uint32_t j = 0; j < rar.nof_grants; ++j) { for (uint32_t j = 0; j < rar.nof_grants; ++j) {
const auto& msg3_grant = rar.msg3_grant[j]; const auto& msg3_grant = rar.msg3_grant[j];
const ra_sched_t::pending_msg3_t& p = const ra_sched_t::pending_msg3_t& p =
rar_sched->find_pending_msg3(tti_sched->get_tti_tx_dl() + MSG3_DELAY_MS + TX_DELAY); carrier_schedulers[0].ra_sched->find_pending_msg3(tti_sched->get_tti_tx_dl() + MSG3_DELAY_MS + TX_DELAY);
CondError(not p.enabled, "Pending Msg3 should have been set\n"); CondError(not p.enabled, "Pending Msg3 should have been set\n");
uint32_t rba = srslte_ra_type2_to_riv(p.L, p.n_prb, cfg.cell.nof_prb); uint32_t rba = srslte_ra_type2_to_riv(p.L, p.n_prb, cfg.cell.nof_prb);
CondError(msg3_grant.grant.rba != rba, "Pending Msg3 RBA is not valid\n"); CondError(msg3_grant.grant.rba != rba, "Pending Msg3 RBA is not valid\n");
@ -554,7 +554,7 @@ void sched_tester::test_tti_result()
} }
/* verify if sched_result "used_cce" coincide with sched "used_cce" */ /* verify if sched_result "used_cce" coincide with sched "used_cce" */
auto* tti_alloc = get_tti_sched(tti_data.tti_rx); auto* tti_alloc = carrier_schedulers[0].get_tti_sched(tti_data.tti_rx);
if (tti_data.used_cce != tti_alloc->get_pdcch_mask()) { if (tti_data.used_cce != tti_alloc->get_pdcch_mask()) {
std::string mask_str = tti_alloc->get_pdcch_mask().to_string(); std::string mask_str = tti_alloc->get_pdcch_mask().to_string();
TestError("[TESTER] The used_cce do not match: (%s!=%s)\n", mask_str.c_str(), tti_data.used_cce.to_hex().c_str()); TestError("[TESTER] The used_cce do not match: (%s!=%s)\n", mask_str.c_str(), tti_data.used_cce.to_hex().c_str());
@ -751,7 +751,7 @@ void sched_tester::test_sibs()
void sched_tester::test_collisions() void sched_tester::test_collisions()
{ {
tti_sched_result_t* tti_sched = get_tti_sched(tti_data.tti_rx); tti_sched_result_t* tti_sched = carrier_schedulers[0].get_tti_sched(tti_data.tti_rx);
srsenb::prbmask_t ul_allocs(cfg.cell.nof_prb); srsenb::prbmask_t ul_allocs(cfg.cell.nof_prb);
@ -892,7 +892,7 @@ void sched_tester::test_collisions()
rbgmask.reset(i); rbgmask.reset(i);
} }
} }
if (rbgmask != get_tti_sched(tti_data.tti_rx)->get_dl_mask()) { if (rbgmask != carrier_schedulers[0].get_tti_sched(tti_data.tti_rx)->get_dl_mask()) {
TestError("[TESTER] The UL PRB mask and the scheduler result UL mask are not consistent\n"); TestError("[TESTER] The UL PRB mask and the scheduler result UL mask are not consistent\n");
} }
} }

Loading…
Cancel
Save