refactored sf result resetting to avoid realloc of memory

This commit is contained in:
Francisco 2021-03-17 13:09:39 +00:00 committed by Francisco Paisana
parent 875773556e
commit c0a90c5aa8
7 changed files with 82 additions and 81 deletions

View File

@ -97,11 +97,11 @@ protected:
std::vector<std::unique_ptr<carrier_sched> > carrier_schedulers; std::vector<std::unique_ptr<carrier_sched> > carrier_schedulers;
// Storage of past scheduling results // Storage of past scheduling results
sched_result_list sched_results; sched_result_ringbuffer sched_results;
srslte::tti_point last_tti; srslte::tti_point last_tti;
std::mutex sched_mutex; std::mutex sched_mutex;
std::atomic<bool> configured; bool configured;
}; };
} // namespace srsenb } // namespace srsenb

View File

@ -28,7 +28,7 @@ public:
explicit carrier_sched(rrc_interface_mac* rrc_, explicit carrier_sched(rrc_interface_mac* rrc_,
std::map<uint16_t, std::unique_ptr<sched_ue> >* ue_db_, std::map<uint16_t, std::unique_ptr<sched_ue> >* ue_db_,
uint32_t enb_cc_idx_, uint32_t enb_cc_idx_,
sched_result_list* sched_results_); sched_result_ringbuffer* sched_results_);
~carrier_sched(); ~carrier_sched();
void reset(); void reset();
void carrier_cfg(const sched_cell_params_t& sched_params_); void carrier_cfg(const sched_cell_params_t& sched_params_);
@ -57,10 +57,10 @@ private:
const uint32_t enb_cc_idx; const uint32_t enb_cc_idx;
// Subframe scheduling logic // Subframe scheduling logic
std::array<sf_sched, TTIMOD_SZ> sf_scheds; srslte::circular_array<sf_sched, TTIMOD_SZ> sf_scheds;
// scheduling results // scheduling results
sched_result_list* prev_sched_results; sched_result_ringbuffer* prev_sched_results;
std::vector<uint8_t> sf_dl_mask; ///< Some TTIs may be forbidden for DL sched due to MBMS std::vector<uint8_t> sf_dl_mask; ///< Some TTIs may be forbidden for DL sched due to MBMS

View File

@ -17,6 +17,7 @@
#include "sched_phy_ch/sf_cch_allocator.h" #include "sched_phy_ch/sf_cch_allocator.h"
#include "sched_ue.h" #include "sched_ue.h"
#include "srslte/adt/bounded_bitset.h" #include "srslte/adt/bounded_bitset.h"
#include "srslte/adt/circular_array.h"
#include "srslte/srslog/srslog.h" #include "srslte/srslog/srslog.h"
#include <deque> #include <deque>
#include <vector> #include <vector>
@ -50,43 +51,61 @@ struct alloc_outcome_t {
//! Result of a Subframe sched computation //! Result of a Subframe sched computation
struct cc_sched_result { struct cc_sched_result {
tti_point tti_rx; bool generated = false;
sched_interface::dl_sched_res_t dl_sched_result = {};
sched_interface::ul_sched_res_t ul_sched_result = {};
rbgmask_t dl_mask = {}; ///< Accumulation of all DL RBG allocations rbgmask_t dl_mask = {}; ///< Accumulation of all DL RBG allocations
prbmask_t ul_mask = {}; ///< Accumulation of all UL PRB allocations prbmask_t ul_mask = {}; ///< Accumulation of all UL PRB allocations
pdcch_mask_t pdcch_mask = {}; ///< Accumulation of all CCE allocations pdcch_mask_t pdcch_mask = {}; ///< Accumulation of all CCE allocations
sched_interface::dl_sched_res_t dl_sched_result = {};
bool is_generated(tti_point tti_rx_) const { return tti_rx == tti_rx_; } sched_interface::ul_sched_res_t ul_sched_result = {};
}; };
struct sf_sched_result { struct sf_sched_result {
srslte::tti_point tti_rx; tti_point tti_rx;
std::vector<cc_sched_result> enb_cc_list; std::vector<cc_sched_result> enb_cc_list;
cc_sched_result* new_cc(uint32_t enb_cc_idx); void new_tti(tti_point tti_rx);
bool is_generated(uint32_t enb_cc_idx) const
{
return enb_cc_list.size() > enb_cc_idx and enb_cc_list[enb_cc_idx].generated;
}
const cc_sched_result* get_cc(uint32_t enb_cc_idx) const const cc_sched_result* get_cc(uint32_t enb_cc_idx) const
{ {
return enb_cc_idx < enb_cc_list.size() ? &enb_cc_list[enb_cc_idx] : nullptr; assert(enb_cc_idx < enb_cc_list.size());
return &enb_cc_list[enb_cc_idx];
} }
cc_sched_result* get_cc(uint32_t enb_cc_idx) cc_sched_result* get_cc(uint32_t enb_cc_idx)
{ {
return enb_cc_idx < enb_cc_list.size() ? &enb_cc_list[enb_cc_idx] : nullptr; assert(enb_cc_idx < enb_cc_list.size());
return &enb_cc_list[enb_cc_idx];
} }
bool is_ul_alloc(uint16_t rnti) const; bool is_ul_alloc(uint16_t rnti) const;
bool is_dl_alloc(uint16_t rnti) const; bool is_dl_alloc(uint16_t rnti) const;
}; };
struct sched_result_list { struct sched_result_ringbuffer {
public: public:
sf_sched_result* new_tti(srslte::tti_point tti_rx); void set_nof_carriers(uint32_t nof_carriers);
sf_sched_result* get_sf(srslte::tti_point tti_rx); void new_tti(srslte::tti_point tti_rx);
const sf_sched_result* get_sf(srslte::tti_point tti_rx) const; bool has_sf(srslte::tti_point tti_rx) const { return results[tti_rx.to_uint()].tti_rx == tti_rx; }
const cc_sched_result* get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const; sf_sched_result* get_sf(srslte::tti_point tti_rx)
cc_sched_result* get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx); {
assert(has_sf(tti_rx));
return &results[tti_rx.to_uint()];
}
const sf_sched_result* get_sf(srslte::tti_point tti_rx) const
{
assert(has_sf(tti_rx));
return &results[tti_rx.to_uint()];
}
const cc_sched_result* get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const
{
return get_sf(tti_rx)->get_cc(enb_cc_idx);
}
cc_sched_result* get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx) { return get_sf(tti_rx)->get_cc(enb_cc_idx); }
private: private:
std::array<sf_sched_result, TTIMOD_SZ> results; uint32_t nof_carriers = 1;
srslte::circular_array<sf_sched_result, TTIMOD_SZ> results;
}; };
/// manages a subframe grid resources, namely CCE and DL/UL RB allocations /// manages a subframe grid resources, namely CCE and DL/UL RB allocations
@ -205,7 +224,7 @@ public:
alloc_outcome_t alloc_outcome_t
alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, bool is_msg3 = false, int msg3_mcs = -1); alloc_ul(sched_ue* user, prb_interval alloc, ul_alloc_t::type_t alloc_type, bool is_msg3 = false, int msg3_mcs = -1);
bool reserve_ul_prbs(const prbmask_t& ulmask, bool strict) { return tti_alloc.reserve_ul_prbs(ulmask, strict); } bool reserve_ul_prbs(const prbmask_t& ulmask, bool strict) { return tti_alloc.reserve_ul_prbs(ulmask, strict); }
bool alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_sf_result); bool alloc_phich(sched_ue* user);
// compute DCIs and generate dl_sched_result/ul_sched_result for a given TTI // compute DCIs and generate dl_sched_result/ul_sched_result for a given TTI
void generate_sched_results(sched_ue_list& ue_db); void generate_sched_results(sched_ue_list& ue_db);

View File

@ -68,6 +68,8 @@ int sched::cell_cfg(const std::vector<sched_interface::cell_cfg_t>& cell_cfg)
} }
} }
sched_results.set_nof_carriers(cell_cfg.size());
// Create remaining cells, if not created yet // Create remaining cells, if not created yet
uint32_t prev_size = carrier_schedulers.size(); uint32_t prev_size = carrier_schedulers.size();
carrier_schedulers.resize(sched_cell_params.size()); carrier_schedulers.resize(sched_cell_params.size());
@ -80,7 +82,7 @@ int sched::cell_cfg(const std::vector<sched_interface::cell_cfg_t>& cell_cfg)
carrier_schedulers[i]->carrier_cfg(sched_cell_params[i]); carrier_schedulers[i]->carrier_cfg(sched_cell_params[i]);
} }
configured.store(true, std::memory_order_release); configured = true;
return 0; return 0;
} }
@ -287,11 +289,10 @@ std::array<bool, SRSLTE_MAX_CARRIERS> sched::get_scell_activation_mask(uint16_t
// Downlink Scheduler API // Downlink Scheduler API
int sched::dl_sched(uint32_t tti_tx_dl, uint32_t enb_cc_idx, sched_interface::dl_sched_res_t& sched_result) int sched::dl_sched(uint32_t tti_tx_dl, uint32_t enb_cc_idx, sched_interface::dl_sched_res_t& sched_result)
{ {
if (not configured.load(std::memory_order_acquire)) { std::lock_guard<std::mutex> lock(sched_mutex);
if (not configured) {
return 0; return 0;
} }
std::lock_guard<std::mutex> lock(sched_mutex);
if (enb_cc_idx >= carrier_schedulers.size()) { if (enb_cc_idx >= carrier_schedulers.size()) {
return 0; return 0;
} }
@ -308,11 +309,10 @@ int sched::dl_sched(uint32_t tti_tx_dl, uint32_t enb_cc_idx, sched_interface::dl
// Uplink Scheduler API // Uplink Scheduler API
int sched::ul_sched(uint32_t tti, uint32_t enb_cc_idx, srsenb::sched_interface::ul_sched_res_t& sched_result) int sched::ul_sched(uint32_t tti, uint32_t enb_cc_idx, srsenb::sched_interface::ul_sched_res_t& sched_result)
{ {
if (not configured.load(std::memory_order_acquire)) { std::lock_guard<std::mutex> lock(sched_mutex);
if (not configured) {
return 0; return 0;
} }
std::lock_guard<std::mutex> lock(sched_mutex);
if (enb_cc_idx >= carrier_schedulers.size()) { if (enb_cc_idx >= carrier_schedulers.size()) {
return 0; return 0;
} }
@ -346,9 +346,7 @@ void sched::new_tti(tti_point tti_rx)
/// Check if TTI result is generated /// Check if TTI result is generated
bool sched::is_generated(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const bool sched::is_generated(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const
{ {
const sf_sched_result* sf_result = sched_results.get_sf(tti_rx); return sched_results.has_sf(tti_rx) and sched_results.get_sf(tti_rx)->is_generated(enb_cc_idx);
return sf_result != nullptr and sf_result->get_cc(enb_cc_idx) != nullptr and
sf_result->get_cc(enb_cc_idx)->is_generated(tti_rx);
} }
// Common way to access ue_db elements in a read locking way // Common way to access ue_db elements in a read locking way

View File

@ -322,10 +322,10 @@ void ra_sched::reset()
* Carrier scheduling * Carrier scheduling
*******************************************************/ *******************************************************/
sched::carrier_sched::carrier_sched(rrc_interface_mac* rrc_, sched::carrier_sched::carrier_sched(rrc_interface_mac* rrc_,
sched_ue_list* ue_db_, sched_ue_list* ue_db_,
uint32_t enb_cc_idx_, uint32_t enb_cc_idx_,
sched_result_list* sched_results_) : sched_result_ringbuffer* sched_results_) :
rrc(rrc_), rrc(rrc_),
ue_db(ue_db_), ue_db(ue_db_),
logger(srslog::fetch_basic_logger("MAC")), logger(srslog::fetch_basic_logger("MAC")),
@ -376,7 +376,7 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r
{ {
sf_sched* tti_sched = get_sf_sched(tti_rx); sf_sched* tti_sched = get_sf_sched(tti_rx);
sf_sched_result* sf_result = prev_sched_results->get_sf(tti_rx); sf_sched_result* sf_result = prev_sched_results->get_sf(tti_rx);
cc_sched_result* cc_result = sf_result->new_cc(enb_cc_idx); cc_sched_result* cc_result = sf_result->get_cc(enb_cc_idx);
bool dl_active = sf_dl_mask[tti_sched->get_tti_tx_dl().to_uint() % sf_dl_mask.size()] == 0; bool dl_active = sf_dl_mask[tti_sched->get_tti_tx_dl().to_uint() % sf_dl_mask.size()] == 0;
@ -390,7 +390,7 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r
if (cc_result->ul_sched_result.nof_phich_elems >= MAX_PHICH_LIST) { if (cc_result->ul_sched_result.nof_phich_elems >= MAX_PHICH_LIST) {
break; break;
} }
tti_sched->alloc_phich(ue_pair.second.get(), &cc_result->ul_sched_result); tti_sched->alloc_phich(ue_pair.second.get());
} }
/* Schedule DL control data */ /* Schedule DL control data */
@ -460,13 +460,13 @@ int sched::carrier_sched::alloc_ul_users(sf_sched* tti_sched)
sf_sched* sched::carrier_sched::get_sf_sched(tti_point tti_rx) sf_sched* sched::carrier_sched::get_sf_sched(tti_point tti_rx)
{ {
sf_sched* ret = &sf_scheds[tti_rx.to_uint() % sf_scheds.size()]; sf_sched* ret = &sf_scheds[tti_rx.to_uint()];
if (ret->get_tti_rx() != tti_rx) { if (ret->get_tti_rx() != tti_rx) {
sf_sched_result* sf_res = prev_sched_results->get_sf(tti_rx); if (not prev_sched_results->has_sf(tti_rx)) {
if (sf_res == nullptr) {
// Reset if tti_rx has not been yet set in the sched results // Reset if tti_rx has not been yet set in the sched results
sf_res = prev_sched_results->new_tti(tti_rx); prev_sched_results->new_tti(tti_rx);
} }
sf_sched_result* sf_res = prev_sched_results->get_sf(tti_rx);
// start new TTI for the given CC. // start new TTI for the given CC.
ret->new_tti(tti_rx, sf_res); ret->new_tti(tti_rx, sf_res);
} }

View File

@ -51,12 +51,13 @@ const char* alloc_outcome_t::to_string() const
return "unknown error"; return "unknown error";
} }
cc_sched_result* sf_sched_result::new_cc(uint32_t enb_cc_idx) void sf_sched_result::new_tti(tti_point tti_rx_)
{ {
if (enb_cc_idx >= enb_cc_list.size()) { assert(tti_rx != tti_rx_);
enb_cc_list.resize(enb_cc_idx + 1); tti_rx = tti_rx_;
for (auto& cc : enb_cc_list) {
cc = {};
} }
return &enb_cc_list[enb_cc_idx];
} }
bool sf_sched_result::is_ul_alloc(uint16_t rnti) const bool sf_sched_result::is_ul_alloc(uint16_t rnti) const
@ -82,36 +83,18 @@ bool sf_sched_result::is_dl_alloc(uint16_t rnti) const
return false; return false;
} }
sf_sched_result* sched_result_list::new_tti(srslte::tti_point tti_rx) void sched_result_ringbuffer::set_nof_carriers(uint32_t nof_carriers_)
{ {
sf_sched_result* res = &results[tti_rx.to_uint() % results.size()]; nof_carriers = nof_carriers_;
res->tti_rx = tti_rx; for (auto& sf_res : results) {
res->enb_cc_list.clear(); sf_res.enb_cc_list.resize(nof_carriers_);
return res; }
} }
sf_sched_result* sched_result_list::get_sf(srslte::tti_point tti_rx) void sched_result_ringbuffer::new_tti(srslte::tti_point tti_rx)
{ {
sf_sched_result* res = &results[tti_rx.to_uint() % results.size()]; sf_sched_result* res = &results[tti_rx.to_uint()];
return (res->tti_rx != tti_rx) ? nullptr : res; res->new_tti(tti_rx);
}
const sf_sched_result* sched_result_list::get_sf(srslte::tti_point tti_rx) const
{
const sf_sched_result* res = &results[tti_rx.to_uint() % results.size()];
return (res->tti_rx != tti_rx) ? nullptr : res;
}
const cc_sched_result* sched_result_list::get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const
{
const sf_sched_result* res = get_sf(tti_rx);
return res != nullptr ? res->get_cc(enb_cc_idx) : nullptr;
}
cc_sched_result* sched_result_list::get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx)
{
sf_sched_result* res = get_sf(tti_rx);
return res != nullptr ? res->get_cc(enb_cc_idx) : nullptr;
} }
/******************************************************* /*******************************************************
@ -634,14 +617,16 @@ alloc_outcome_t sf_sched::alloc_ul_user(sched_ue* user, prb_interval alloc)
return alloc_ul(user, alloc, alloc_type, h->is_msg3()); return alloc_ul(user, alloc, alloc_type, h->is_msg3());
} }
bool sf_sched::alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_sf_result) bool sf_sched::alloc_phich(sched_ue* user)
{ {
using phich_t = sched_interface::ul_sched_phich_t;
auto* ul_sf_result = &cc_results->get_cc(cc_cfg->enb_cc_idx)->ul_sched_result;
if (ul_sf_result->nof_phich_elems >= sched_interface::MAX_PHICH_LIST) { if (ul_sf_result->nof_phich_elems >= sched_interface::MAX_PHICH_LIST) {
logger.warning("SCHED: Maximum number of PHICH allocations has been reached"); logger.warning("SCHED: Maximum number of PHICH allocations has been reached");
return false; return false;
} }
using phich_t = sched_interface::ul_sched_phich_t; phich_t& phich_item = ul_sf_result->phich[ul_sf_result->nof_phich_elems];
auto& phich_list = ul_sf_result->phich[ul_sf_result->nof_phich_elems];
auto p = user->get_active_cell_index(cc_cfg->enb_cc_idx); auto p = user->get_active_cell_index(cc_cfg->enb_cc_idx);
if (not p.first) { if (not p.first) {
@ -653,8 +638,8 @@ bool sf_sched::alloc_phich(sched_ue* user, sched_interface::ul_sched_res_t* ul_s
/* Indicate PHICH acknowledgment if needed */ /* Indicate PHICH acknowledgment if needed */
if (h->has_pending_phich()) { if (h->has_pending_phich()) {
phich_list.phich = h->pop_pending_phich() ? phich_t::ACK : phich_t::NACK; phich_item.phich = h->pop_pending_phich() ? phich_t::ACK : phich_t::NACK;
phich_list.rnti = user->get_rnti(); phich_item.rnti = user->get_rnti();
ul_sf_result->nof_phich_elems++; ul_sf_result->nof_phich_elems++;
return true; return true;
} }
@ -968,9 +953,9 @@ void sf_sched::generate_sched_results(sched_ue_list& ue_db)
set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db); set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db);
/* Store remaining sf_sched results for this TTI */ /* Store remaining sf_sched results for this TTI */
cc_result->dl_mask = tti_alloc.get_dl_mask(); cc_result->dl_mask = tti_alloc.get_dl_mask();
cc_result->ul_mask = tti_alloc.get_ul_mask(); cc_result->ul_mask = tti_alloc.get_ul_mask();
cc_result->tti_rx = get_tti_rx(); cc_result->generated = true;
} }
uint32_t sf_sched::get_nof_ctrl_symbols() const uint32_t sf_sched::get_nof_ctrl_symbols() const

View File

@ -139,7 +139,6 @@ int sched_tester::process_results()
{ {
const srsenb::cc_sched_result* cc_result = sched_results.get_cc(tti_rx, CARRIER_IDX); const srsenb::cc_sched_result* cc_result = sched_results.get_cc(tti_rx, CARRIER_IDX);
srsenb::sf_output_res_t sf_out{sched_cell_params, tti_rx, tti_info.ul_sched_result, tti_info.dl_sched_result}; srsenb::sf_output_res_t sf_out{sched_cell_params, tti_rx, tti_info.ul_sched_result, tti_info.dl_sched_result};
TESTASSERT(tti_rx == cc_result->tti_rx);
// Common tests // Common tests
TESTASSERT(test_pdcch_collisions(sf_out, CARRIER_IDX, &cc_result->pdcch_mask) == SRSLTE_SUCCESS); TESTASSERT(test_pdcch_collisions(sf_out, CARRIER_IDX, &cc_result->pdcch_mask) == SRSLTE_SUCCESS);