diff --git a/lib/include/srslte/adt/interval.h b/lib/include/srslte/adt/interval.h index 0d96fbfe2..90bdca218 100644 --- a/lib/include/srslte/adt/interval.h +++ b/lib/include/srslte/adt/interval.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_INTERVAL_H #define SRSLTE_INTERVAL_H +#include #include #include @@ -37,45 +38,71 @@ class interval #endif public: - T start; - T stop; + interval() : start_(T{}), stop_(T{}) {} + interval(T start_point, T stop_point) : start_(start_point), stop_(stop_point) { assert(start_ <= stop_); } - interval() : start(T{}), stop(T{}) {} - interval(T start_, T stop_) : start(start_), stop(stop_) {} + T start() const { return start_; } + T stop() const { return stop_; } - bool empty() const { return stop <= start; } + bool empty() const { return stop_ == start_; } - T length() const { return stop > start ? stop - start : 0; } + T length() const { return stop_ - start_; } - void set_length(T len) { stop = start + len; } + void inc_length(int n) + { + stop_ += n; + assert(stop_ >= start_); + } + + void set_length(T len) + { + assert(len >= 0); + stop_ = start_ + len; + } + + void set_start(T start_point) + { + assert(start_point <= stop_); + start_ = start_point; + } + + void set_stop(T stop_point) + { + assert(start_ <= stop_point); + stop_ = stop_point; + } void displace_by(int offset) { - start += offset; - stop += offset; + start_ += offset; + stop_ += offset; } void displace_to(T start_point) { - stop = start_point + length(); - start = start_point; + stop_ = start_point + length(); + start_ = start_point; } - bool overlaps(interval other) const { return start < other.stop and other.start < stop; } + bool overlaps(interval other) const { return start_ < other.stop_ and other.start_ < stop_; } - bool contains(T point) const { return start <= point and point < stop; } + bool contains(T point) const { return start_ <= point and point < stop_; } std::string to_string() const { - std::string s = "[" + std::to_string(start) + "," + std::to_string(stop) + ")"; + std::string s = "[" + std::to_string(start_) + "," + std::to_string(stop_) + ")"; return s; } + +private: + T start_; + T stop_; }; template bool operator==(const interval& lhs, const interval& rhs) { - return lhs.start == rhs.start and lhs.stop == rhs.stop; + return lhs.start() == rhs.start() and lhs.stop() == rhs.stop(); } template @@ -87,7 +114,7 @@ bool operator!=(const interval& lhs, const interval& rhs) template bool operator<(const interval& lhs, const interval& rhs) { - return lhs.start < rhs.start or (lhs.start == rhs.start and lhs.stop < rhs.stop); + return lhs.start() < rhs.start() or (lhs.start() == rhs.start() and lhs.stop() < rhs.stop()); } //! Union of intervals @@ -97,7 +124,7 @@ interval operator|(const interval& lhs, const interval& rhs) if (not lhs.overlaps(rhs)) { return interval{}; } - return {std::min(lhs.start, rhs.start), std::max(lhs.stop, rhs.stop)}; + return {std::min(lhs.start(), rhs.start()), std::max(lhs.stop(), rhs.stop())}; } template @@ -113,7 +140,7 @@ interval operator&(const interval& lhs, const interval& rhs) if (not lhs.overlaps(rhs)) { return interval{}; } - return interval{std::max(lhs.start, rhs.start), std::min(lhs.stop, rhs.stop)}; + return interval{std::max(lhs.start(), rhs.start()), std::min(lhs.stop(), rhs.stop())}; } template diff --git a/lib/test/adt/interval_test.cc b/lib/test/adt/interval_test.cc index 5df50d4e7..47ba279e2 100644 --- a/lib/test/adt/interval_test.cc +++ b/lib/test/adt/interval_test.cc @@ -26,9 +26,9 @@ int test_interval_init() { srslte::interval I{}, I2{12, 15}, I3{12, 12}; - TESTASSERT(I.empty() and I.start == 0 and I.stop == 0); - TESTASSERT(not I2.empty() and I2.start == 12 and I2.stop == 15); - TESTASSERT(I3.empty() and I3.start == 12 and I3.stop == 12); + TESTASSERT(I.empty() and I.start() == 0 and I.stop() == 0); + TESTASSERT(not I2.empty() and I2.start() == 12 and I2.stop() == 15); + TESTASSERT(I3.empty() and I3.start() == 12 and I3.stop() == 12); return SRSLTE_SUCCESS; } diff --git a/srsenb/src/stack/mac/scheduler.cc b/srsenb/src/stack/mac/scheduler.cc index 72446dcb5..dd6758d17 100644 --- a/srsenb/src/stack/mac/scheduler.cc +++ b/srsenb/src/stack/mac/scheduler.cc @@ -452,23 +452,22 @@ void sched_cell_params_t::regs_deleter::operator()(srslte_regs_t* p) rbg_interval rbg_interval::prbs_to_rbgs(const prb_interval& prbs, uint32_t P) { - return rbg_interval{srslte::ceil_div(prbs.start, P), srslte::ceil_div(prbs.start, P)}; + return rbg_interval{srslte::ceil_div(prbs.start(), P), srslte::ceil_div(prbs.stop(), P)}; } prb_interval prb_interval::rbgs_to_prbs(const rbg_interval& rbgs, uint32_t P) { - return prb_interval{rbgs.start * P, rbgs.stop * P}; + return prb_interval{rbgs.start() * P, rbgs.stop() * P}; } prb_interval prb_interval::riv_to_prbs(uint32_t riv, uint32_t nof_prbs, int nof_vrbs) { - prb_interval p; if (nof_vrbs < 0) { nof_vrbs = nof_prbs; } - srslte_ra_type2_from_riv(riv, &p.stop, &p.start, nof_prbs, (uint32_t)nof_vrbs); - p.stop += p.start; - return p; + uint32_t rb_start, l_crb; + srslte_ra_type2_from_riv(riv, &l_crb, &rb_start, nof_prbs, (uint32_t)nof_vrbs); + return {rb_start, rb_start + l_crb}; } namespace sched_utils { diff --git a/srsenb/src/stack/mac/scheduler_grid.cc b/srsenb/src/stack/mac/scheduler_grid.cc index a8550b06e..ff3d8f8fc 100644 --- a/srsenb/src/stack/mac/scheduler_grid.cc +++ b/srsenb/src/stack/mac/scheduler_grid.cc @@ -444,9 +444,8 @@ alloc_outcome_t sf_grid_t::alloc_dl(uint32_t aggr_idx, alloc_type_t alloc_type, //! Allocates CCEs and RBs for control allocs. It allocates RBs in a contiguous manner. sf_grid_t::dl_ctrl_alloc_t sf_grid_t::alloc_dl_ctrl(uint32_t aggr_idx, alloc_type_t alloc_type) { - rbg_interval range; - range.start = nof_rbgs - avail_rbg; - range.set_length((alloc_type == alloc_type_t::DL_RAR) ? rar_n_rbg : si_n_rbg); + rbg_interval range{nof_rbgs - avail_rbg, + nof_rbgs - avail_rbg + ((alloc_type == alloc_type_t::DL_RAR) ? rar_n_rbg : si_n_rbg)}; if (alloc_type != alloc_type_t::DL_RAR and alloc_type != alloc_type_t::DL_BC and alloc_type != alloc_type_t::DL_PCCH) { @@ -454,13 +453,13 @@ sf_grid_t::dl_ctrl_alloc_t sf_grid_t::alloc_dl_ctrl(uint32_t aggr_idx, alloc_typ return {alloc_outcome_t::ERROR, range}; } // Setup range starting from left - if (range.stop > nof_rbgs) { + if (range.stop() > nof_rbgs) { return {alloc_outcome_t::RB_COLLISION, range}; } // allocate DCI and RBGs rbgmask_t new_mask(dl_mask.size()); - new_mask.fill(range.start, range.stop); + new_mask.fill(range.start(), range.stop()); return {alloc_dl(aggr_idx, alloc_type, new_mask), range}; } @@ -477,12 +476,12 @@ alloc_outcome_t sf_grid_t::alloc_dl_data(sched_ue* user, const rbgmask_t& user_m alloc_outcome_t sf_grid_t::alloc_ul_data(sched_ue* user, prb_interval alloc, bool needs_pdcch) { - if (alloc.stop > ul_mask.size()) { + if (alloc.stop() > ul_mask.size()) { return alloc_outcome_t::ERROR; } prbmask_t newmask(ul_mask.size()); - newmask.fill(alloc.start, alloc.stop); + newmask.fill(alloc.start(), alloc.stop()); if ((ul_mask & newmask).any()) { return alloc_outcome_t::RB_COLLISION; } @@ -539,12 +538,11 @@ bool sf_grid_t::find_ul_alloc(uint32_t L, prb_interval* alloc) const alloc->displace_to(n); } if (not ul_mask.test(n)) { - alloc->stop++; + alloc->inc_length(1); } else if (alloc->length() > 0) { // avoid edges if (n < 3) { - alloc->start = 0; - alloc->stop = 0; + *alloc = {}; } else { break; } @@ -556,7 +554,7 @@ bool sf_grid_t::find_ul_alloc(uint32_t L, prb_interval* alloc) const // Make sure L is allowed by SC-FDMA modulation while (!srslte_dft_precoding_valid_prb(alloc->length())) { - alloc->stop--; + alloc->inc_length(-1); } return alloc->length() == L; } @@ -758,7 +756,7 @@ alloc_outcome_t sf_sched::alloc_dl_user(sched_ue* user, const rbgmask_t& user_ma if (h.is_empty()) { // It is newTx rbg_interval r = user->get_required_dl_rbgs(ue_cc_idx); - if (r.start > user_mask.count()) { + if (r.start() > user_mask.count()) { log_h->warning("The number of RBGs allocated to rnti=0x%x will force segmentation\n", user->get_rnti()); return alloc_outcome_t::NOF_RB_INVALID; } @@ -890,8 +888,8 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul if (tbs <= (int)bc_alloc.req_bytes) { log_h->warning("SCHED: Error SIB%d, rbgs=(%d,%d), dci=(%d,%d), len=%d\n", bc_alloc.sib_idx + 1, - bc_alloc.rbg_range.start, - bc_alloc.rbg_range.stop, + bc_alloc.rbg_range.start(), + bc_alloc.rbg_range.stop(), bc->dci.location.L, bc->dci.location.ncce, bc_alloc.req_bytes); @@ -905,8 +903,8 @@ void sf_sched::set_bc_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul log_h->debug("SCHED: SIB%d, rbgs=(%d,%d), dci=(%d,%d), rv=%d, len=%d, period=%d, mcs=%d\n", bc_alloc.sib_idx + 1, - bc_alloc.rbg_range.start, - bc_alloc.rbg_range.stop, + bc_alloc.rbg_range.start(), + bc_alloc.rbg_range.stop(), bc->dci.location.L, bc->dci.location.ncce, bc_alloc.rv, @@ -1164,10 +1162,7 @@ void sf_sched::set_ul_sched_result(const pdcch_grid_t::alloc_result_t& dci_resul alloc_outcome_t sf_sched::alloc_msg3(sched_ue* user, const sched_interface::dl_sched_rar_grant_t& rargrant) { // Derive PRBs from allocated RAR grants - prb_interval msg3_alloc = {}; - uint32_t L; - srslte_ra_type2_from_riv(rargrant.grant.rba, &L, &msg3_alloc.start, cc_cfg->nof_prb(), cc_cfg->nof_prb()); - msg3_alloc.set_length(L); + prb_interval msg3_alloc = prb_interval::riv_to_prbs(rargrant.grant.rba, cc_cfg->nof_prb()); alloc_outcome_t ret = alloc_ul(user, msg3_alloc, sf_sched::ul_alloc_t::MSG3, rargrant.grant.trunc_mcs); if (not ret) { @@ -1246,7 +1241,7 @@ int sf_sched::generate_format1a(prb_interval prb_range, dci->alloc_type = SRSLTE_RA_ALLOC_TYPE2; dci->type2_alloc.mode = srslte_ra_type2_t::SRSLTE_RA_TYPE2_LOC; - dci->type2_alloc.riv = srslte_ra_type2_to_riv(prb_range.length(), prb_range.start, cc_cfg->cfg.cell.nof_prb); + dci->type2_alloc.riv = srslte_ra_type2_to_riv(prb_range.length(), prb_range.start(), cc_cfg->cfg.cell.nof_prb); dci->pid = 0; dci->tb[0].mcs_idx = mcs; dci->tb[0].rv = rv; diff --git a/srsenb/src/stack/mac/scheduler_metric.cc b/srsenb/src/stack/mac/scheduler_metric.cc index b9e70c6f0..7cbb020c0 100644 --- a/srsenb/src/stack/mac/scheduler_metric.cc +++ b/srsenb/src/stack/mac/scheduler_metric.cc @@ -132,9 +132,9 @@ dl_harq_proc* dl_metric_rr::allocate_user(sched_ue* user) if (h != nullptr) { // Allocate resources based on pending data rbg_interval req_rbgs = user->get_required_dl_rbgs(cell_idx); - if (req_rbgs.start > 0) { + if (req_rbgs.stop() > 0) { rbgmask_t newtx_mask(tti_alloc->get_dl_mask().size()); - if (find_allocation(req_rbgs.start, req_rbgs.stop, &newtx_mask)) { + if (find_allocation(req_rbgs.start(), req_rbgs.stop(), &newtx_mask)) { // some empty spaces were found code = tti_alloc->alloc_dl_user(user, newtx_mask, h->get_id()); if (code == alloc_outcome_t::SUCCESS) { @@ -212,7 +212,7 @@ bool ul_metric_rr::find_allocation(uint32_t L, prb_interval* alloc) alloc->displace_to(n); } if (not used_rb->test(n)) { - alloc->stop++; + alloc->inc_length(1); } else if (alloc->length() > 0) { // avoid edges if (n < 3) { @@ -228,7 +228,7 @@ bool ul_metric_rr::find_allocation(uint32_t L, prb_interval* alloc) // Make sure L is allowed by SC-FDMA modulation while (!srslte_dft_precoding_valid_prb(alloc->length())) { - alloc->stop--; + alloc->inc_length(-1); } return alloc->length() == L; } diff --git a/srsenb/src/stack/mac/scheduler_ue.cc b/srsenb/src/stack/mac/scheduler_ue.cc index 905c73c98..ee68b01f7 100644 --- a/srsenb/src/stack/mac/scheduler_ue.cc +++ b/srsenb/src/stack/mac/scheduler_ue.cc @@ -539,7 +539,7 @@ std::pair sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_i // Use a higher MCS for the Msg4 to fit in the 6 PRB case if (carriers[ue_cc_idx].fixed_mcs_dl < 0 or not carriers[ue_cc_idx].dl_cqi_rx) { // Dynamic MCS - tbs_bytes = carriers[ue_cc_idx].alloc_tbs_dl(nof_alloc_prbs, nof_re, req_bytes.stop, &mcs); + tbs_bytes = carriers[ue_cc_idx].alloc_tbs_dl(nof_alloc_prbs, nof_re, req_bytes.stop(), &mcs); } else { // Fixed MCS mcs = carriers[ue_cc_idx].fixed_mcs_dl; @@ -549,7 +549,7 @@ std::pair sched_ue::compute_mcs_and_tbs(uint32_t ue_cc_i // If the number of prbs is not sufficient to fit minimum required bytes, increase the mcs // NOTE: this may happen during ConRes CE tx when DL-CQI is still not available - while (tbs_bytes > 0 and (uint32_t) tbs_bytes < req_bytes.start and mcs < 28) { + while (tbs_bytes > 0 and (uint32_t) tbs_bytes < req_bytes.start() and mcs < 28) { mcs++; tbs_bytes = sched_utils::get_tbs_bytes((uint32_t)mcs, nof_alloc_prbs, cfg.use_tbs_index_alt, false); } @@ -722,7 +722,7 @@ int sched_ue::generate_format0(sched_interface::ul_sched_data_t* data, dci->rnti = rnti; dci->format = SRSLTE_DCI_FORMAT0; dci->ue_cc_idx = cc_idx; - dci->type2_alloc.riv = srslte_ra_type2_to_riv(alloc.length(), alloc.start, cell.nof_prb); + dci->type2_alloc.riv = srslte_ra_type2_to_riv(alloc.length(), alloc.start(), cell.nof_prb); dci->tb.rv = sched_utils::get_rvidx(h->nof_retx(0)); if (!is_newtx && h->is_adaptive_retx()) { dci->tb.mcs_idx = 28 + dci->tb.rv; @@ -801,17 +801,17 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t ue_cc_idx) } const auto* cellparams = carriers[ue_cc_idx].get_cell_cfg(); int pending_prbs = - carriers[ue_cc_idx].get_required_prb_dl(req_bytes.start, cellparams->sched_cfg->max_nof_ctrl_symbols); + carriers[ue_cc_idx].get_required_prb_dl(req_bytes.start(), cellparams->sched_cfg->max_nof_ctrl_symbols); if (pending_prbs < 0) { // Cannot fit allocation in given PRBs log_h->error("SCHED: DL CQI=%d does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. " "Consider increasing initial CQI value.\n", carriers[ue_cc_idx].dl_cqi, - req_bytes.start); + req_bytes.start()); return {cellparams->nof_prb(), cellparams->nof_prb()}; } uint32_t min_pending_rbg = cellparams->prb_to_rbg(pending_prbs); - pending_prbs = carriers[ue_cc_idx].get_required_prb_dl(req_bytes.stop, cellparams->sched_cfg->max_nof_ctrl_symbols); + pending_prbs = carriers[ue_cc_idx].get_required_prb_dl(req_bytes.stop(), cellparams->sched_cfg->max_nof_ctrl_symbols); pending_prbs = (pending_prbs < 0) ? cellparams->nof_prb() : pending_prbs; uint32_t max_pending_rbg = cellparams->prb_to_rbg(pending_prbs); return {min_pending_rbg, max_pending_rbg}; diff --git a/srsenb/test/mac/scheduler_test_common.cc b/srsenb/test/mac/scheduler_test_common.cc index 1bf7c3242..49daa823a 100644 --- a/srsenb/test/mac/scheduler_test_common.cc +++ b/srsenb/test/mac/scheduler_test_common.cc @@ -65,15 +65,15 @@ int output_sched_tester::test_pusch_collisions(const tti_params_t& ul_allocs.reset(); auto try_ul_fill = [&](prb_interval alloc, const char* ch_str, bool strict = true) { - CONDERROR(alloc.stop > nof_prb, "Allocated RBs %s out-of-bounds\n", alloc.to_string().c_str()); + CONDERROR(alloc.stop() > nof_prb, "Allocated RBs %s out-of-bounds\n", alloc.to_string().c_str()); CONDERROR(alloc.empty(), "Allocations must have at least one PRB\n"); - if (strict and ul_allocs.any(alloc.start, alloc.stop)) { + if (strict and ul_allocs.any(alloc.start(), alloc.stop())) { TESTERROR("Collision Detected of %s alloc=%s and cumulative_mask=0x%s\n", ch_str, alloc.to_string().c_str(), ul_allocs.to_hex().c_str()); } - ul_allocs.fill(alloc.start, alloc.stop, true); + ul_allocs.fill(alloc.start(), alloc.stop(), true); return SRSLTE_SUCCESS; };