diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index ff5fbad48..3a8e68f33 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -97,11 +97,11 @@ protected: std::vector > 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 configured; + bool configured; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/sched_carrier.h b/srsenb/hdr/stack/mac/sched_carrier.h index 01711ec98..03cd5f498 100644 --- a/srsenb/hdr/stack/mac/sched_carrier.h +++ b/srsenb/hdr/stack/mac/sched_carrier.h @@ -28,7 +28,7 @@ public: explicit carrier_sched(rrc_interface_mac* rrc_, std::map >* 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_scheds; + srslte::circular_array sf_scheds; // scheduling results - sched_result_list* prev_sched_results; + sched_result_ringbuffer* prev_sched_results; std::vector sf_dl_mask; ///< Some TTIs may be forbidden for DL sched due to MBMS diff --git a/srsenb/hdr/stack/mac/sched_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index d77e2e1d4..f19544398 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -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 #include @@ -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 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 results; + uint32_t nof_carriers = 1; + srslte::circular_array 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); diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index 336320c6e..75e1e54dc 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -68,6 +68,8 @@ int sched::cell_cfg(const std::vector& 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& 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 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 lock(sched_mutex); + if (not configured) { return 0; } - - std::lock_guard 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 lock(sched_mutex); + if (not configured) { return 0; } - - std::lock_guard 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 diff --git a/srsenb/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index c5930ab4e..0813f1b30 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -322,10 +322,10 @@ void ra_sched::reset() * Carrier scheduling *******************************************************/ -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::carrier_sched::carrier_sched(rrc_interface_mac* rrc_, + sched_ue_list* ue_db_, + uint32_t enb_cc_idx_, + 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); } diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index 5a3c1aa06..3c9e915ef 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -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) +void sched_result_ringbuffer::set_nof_carriers(uint32_t nof_carriers_) { - sf_sched_result* res = &results[tti_rx.to_uint() % results.size()]; - res->tti_rx = tti_rx; - res->enb_cc_list.clear(); - return res; + nof_carriers = nof_carriers_; + for (auto& sf_res : results) { + sf_res.enb_cc_list.resize(nof_carriers_); + } } -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()]; - return (res->tti_rx != tti_rx) ? nullptr : res; -} - -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; + 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; } @@ -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); /* 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->dl_mask = tti_alloc.get_dl_mask(); + cc_result->ul_mask = tti_alloc.get_ul_mask(); + cc_result->generated = true; } uint32_t sf_sched::get_nof_ctrl_symbols() const diff --git a/srsenb/test/mac/sched_test_rand.cc b/srsenb/test/mac/sched_test_rand.cc index 20ee20174..114d19adb 100644 --- a/srsenb/test/mac/sched_test_rand.cc +++ b/srsenb/test/mac/sched_test_rand.cc @@ -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);