refactored sf result resetting to avoid realloc of memory

master
Francisco 4 years ago committed by Francisco Paisana
parent 875773556e
commit c0a90c5aa8

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

@ -28,7 +28,7 @@ public:
explicit carrier_sched(rrc_interface_mac* rrc_,
std::map<uint16_t, std::unique_ptr<sched_ue> >* ue_db_,
uint32_t enb_cc_idx_,
sched_result_list* sched_results_);
sched_result_ringbuffer* sched_results_);
~carrier_sched();
void reset();
void carrier_cfg(const sched_cell_params_t& sched_params_);
@ -57,10 +57,10 @@ private:
const uint32_t enb_cc_idx;
// Subframe scheduling logic
std::array<sf_sched, TTIMOD_SZ> sf_scheds;
srslte::circular_array<sf_sched, TTIMOD_SZ> sf_scheds;
// 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

@ -17,6 +17,7 @@
#include "sched_phy_ch/sf_cch_allocator.h"
#include "sched_ue.h"
#include "srslte/adt/bounded_bitset.h"
#include "srslte/adt/circular_array.h"
#include "srslte/srslog/srslog.h"
#include <deque>
#include <vector>
@ -50,43 +51,61 @@ struct alloc_outcome_t {
//! Result of a Subframe sched computation
struct cc_sched_result {
tti_point tti_rx;
sched_interface::dl_sched_res_t dl_sched_result = {};
sched_interface::ul_sched_res_t ul_sched_result = {};
bool generated = false;
rbgmask_t dl_mask = {}; ///< Accumulation of all DL RBG allocations
prbmask_t ul_mask = {}; ///< Accumulation of all UL PRB allocations
pdcch_mask_t pdcch_mask = {}; ///< Accumulation of all CCE allocations
bool is_generated(tti_point tti_rx_) const { return tti_rx == tti_rx_; }
sched_interface::dl_sched_res_t dl_sched_result = {};
sched_interface::ul_sched_res_t ul_sched_result = {};
};
struct sf_sched_result {
srslte::tti_point tti_rx;
tti_point tti_rx;
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
{
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)
{
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_dl_alloc(uint16_t rnti) const;
};
struct sched_result_list {
struct sched_result_ringbuffer {
public:
sf_sched_result* new_tti(srslte::tti_point tti_rx);
sf_sched_result* get_sf(srslte::tti_point tti_rx);
const sf_sched_result* get_sf(srslte::tti_point tti_rx) const;
const cc_sched_result* get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx) const;
cc_sched_result* get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx);
void set_nof_carriers(uint32_t nof_carriers);
void new_tti(srslte::tti_point tti_rx);
bool has_sf(srslte::tti_point tti_rx) const { return results[tti_rx.to_uint()].tti_rx == tti_rx; }
sf_sched_result* get_sf(srslte::tti_point tti_rx)
{
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:
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
@ -205,7 +224,7 @@ public:
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);
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
void generate_sched_results(sched_ue_list& ue_db);

@ -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
uint32_t prev_size = carrier_schedulers.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]);
}
configured.store(true, std::memory_order_release);
configured = true;
return 0;
}
@ -287,11 +289,10 @@ std::array<bool, SRSLTE_MAX_CARRIERS> sched::get_scell_activation_mask(uint16_t
// 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)
{
if (not configured.load(std::memory_order_acquire)) {
std::lock_guard<std::mutex> lock(sched_mutex);
if (not configured) {
return 0;
}
std::lock_guard<std::mutex> lock(sched_mutex);
if (enb_cc_idx >= carrier_schedulers.size()) {
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
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;
}
std::lock_guard<std::mutex> lock(sched_mutex);
if (enb_cc_idx >= carrier_schedulers.size()) {
return 0;
}
@ -346,9 +346,7 @@ void sched::new_tti(tti_point tti_rx)
/// Check if TTI result is generated
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 sf_result != nullptr and sf_result->get_cc(enb_cc_idx) != nullptr and
sf_result->get_cc(enb_cc_idx)->is_generated(tti_rx);
return sched_results.has_sf(tti_rx) and sched_results.get_sf(tti_rx)->is_generated(enb_cc_idx);
}
// Common way to access ue_db elements in a read locking way

@ -325,7 +325,7 @@ void ra_sched::reset()
sched::carrier_sched::carrier_sched(rrc_interface_mac* rrc_,
sched_ue_list* ue_db_,
uint32_t enb_cc_idx_,
sched_result_list* sched_results_) :
sched_result_ringbuffer* sched_results_) :
rrc(rrc_),
ue_db(ue_db_),
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_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;
@ -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) {
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 */
@ -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* 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) {
sf_sched_result* sf_res = prev_sched_results->get_sf(tti_rx);
if (sf_res == nullptr) {
if (not prev_sched_results->has_sf(tti_rx)) {
// 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.
ret->new_tti(tti_rx, sf_res);
}

@ -51,12 +51,13 @@ const char* alloc_outcome_t::to_string() const
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()) {
enb_cc_list.resize(enb_cc_idx + 1);
assert(tti_rx != tti_rx_);
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
@ -82,36 +83,18 @@ bool sf_sched_result::is_dl_alloc(uint16_t rnti) const
return false;
}
sf_sched_result* sched_result_list::new_tti(srslte::tti_point tti_rx)
{
sf_sched_result* res = &results[tti_rx.to_uint() % results.size()];
res->tti_rx = tti_rx;
res->enb_cc_list.clear();
return res;
}
sf_sched_result* sched_result_list::get_sf(srslte::tti_point tti_rx)
{
sf_sched_result* res = &results[tti_rx.to_uint() % results.size()];
return (res->tti_rx != tti_rx) ? nullptr : res;
}
const sf_sched_result* sched_result_list::get_sf(srslte::tti_point tti_rx) const
void sched_result_ringbuffer::set_nof_carriers(uint32_t nof_carriers_)
{
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;
nof_carriers = nof_carriers_;
for (auto& sf_res : results) {
sf_res.enb_cc_list.resize(nof_carriers_);
}
}
cc_sched_result* sched_result_list::get_cc(srslte::tti_point tti_rx, uint32_t enb_cc_idx)
void sched_result_ringbuffer::new_tti(srslte::tti_point tti_rx)
{
sf_sched_result* res = get_sf(tti_rx);
return res != nullptr ? res->get_cc(enb_cc_idx) : nullptr;
sf_sched_result* res = &results[tti_rx.to_uint()];
res->new_tti(tti_rx);
}
/*******************************************************
@ -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());
}
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) {
logger.warning("SCHED: Maximum number of PHICH allocations has been reached");
return false;
}
using phich_t = sched_interface::ul_sched_phich_t;
auto& phich_list = ul_sf_result->phich[ul_sf_result->nof_phich_elems];
phich_t& phich_item = ul_sf_result->phich[ul_sf_result->nof_phich_elems];
auto p = user->get_active_cell_index(cc_cfg->enb_cc_idx);
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 */
if (h->has_pending_phich()) {
phich_list.phich = h->pop_pending_phich() ? phich_t::ACK : phich_t::NACK;
phich_list.rnti = user->get_rnti();
phich_item.phich = h->pop_pending_phich() ? phich_t::ACK : phich_t::NACK;
phich_item.rnti = user->get_rnti();
ul_sf_result->nof_phich_elems++;
return true;
}
@ -970,7 +955,7 @@ void sf_sched::generate_sched_results(sched_ue_list& ue_db)
/* Store remaining sf_sched results for this TTI */
cc_result->dl_mask = tti_alloc.get_dl_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

@ -139,7 +139,6 @@ int sched_tester::process_results()
{
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};
TESTASSERT(tti_rx == cc_result->tti_rx);
// Common tests
TESTASSERT(test_pdcch_collisions(sf_out, CARRIER_IDX, &cc_result->pdcch_mask) == SRSLTE_SUCCESS);

Loading…
Cancel
Save