Skip to content

Commit 5c66acb

Browse files
herlesupreethcodebot
authored andcommitted
sched: allow scheduling more than one UL PDCCH per UE per slot in UL heavy TDD configuration
1 parent 991aaa6 commit 5c66acb

File tree

1 file changed

+99
-25
lines changed

1 file changed

+99
-25
lines changed

lib/scheduler/policy/scheduler_time_rr.cpp

Lines changed: 99 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,80 @@ static unsigned compute_max_nof_rbs_per_ue_per_slot(const ue_repository&
112112
return (bwp_crb_limits.length() / nof_ues_to_be_scheduled_per_slot);
113113
}
114114

115+
/// \brief Algorithm to select next UE to allocate in a time-domain RR fashion
116+
/// \param[in] ue_db map of "slot_ue"
117+
/// \param[in] next_ue_index UE index with the highest priority to be allocated.
118+
/// \param[in] alloc_ue callable with signature "alloc_outcome(ue&, pusch_time_domain_resource_index)" that returns the
119+
/// UE allocation outcome.
120+
/// \return Index of next UE to allocate.
121+
template <typename AllocUEFunc>
122+
du_ue_index_t round_robin_ul_apply(const ue_repository& ue_db, du_ue_index_t next_ue_index, const AllocUEFunc& alloc_ue)
123+
{
124+
if (ue_db.empty()) {
125+
return next_ue_index;
126+
}
127+
auto it = ue_db.lower_bound(next_ue_index);
128+
bool first_alloc = true;
129+
130+
// NOTE: All UEs use the same PUSCH Time Domain Resource configuration.
131+
const ue& ref_u = **ue_db.begin();
132+
133+
unsigned max_pusch_time_domain_resource_index = 1;
134+
if (ref_u.nof_cells() > 0) {
135+
const ue_cell_configuration& ue_cfg = ref_u.get_pcell().cfg();
136+
const auto* ss_info =
137+
ue_cfg.find_search_space(ue_cfg.cfg_dedicated().init_dl_bwp.pdcch_cfg->search_spaces.back().get_id());
138+
if (ss_info == nullptr) {
139+
return next_ue_index;
140+
}
141+
142+
// [Implementation-defined] For UL heavy TDD configuration we allow multiple UL PDCCH allocations in the same slot
143+
// for same UE but with different k2 values. In other cases (DL heavy) k2 value which is less than or equal to
144+
// minimum value of k1(s) is used. Assumes that first entry in the PUSCH Time Domain resource list contains the k2
145+
// value which is less than or equal to minimum value of k1(s).
146+
if (ue_cfg.cell_cfg_common.is_tdd() and
147+
(nof_full_ul_slots_per_tdd_period(ue_cfg.cell_cfg_common.tdd_cfg_common.value()) >
148+
nof_full_dl_slots_per_tdd_period(ue_cfg.cell_cfg_common.tdd_cfg_common.value()))) {
149+
max_pusch_time_domain_resource_index = ss_info->pusch_time_domain_list.size();
150+
}
151+
}
152+
153+
for (unsigned pusch_td_res_idx = 0; pusch_td_res_idx < max_pusch_time_domain_resource_index; ++pusch_td_res_idx) {
154+
for (unsigned count = 0; count < ue_db.size(); ++count, ++it) {
155+
if (it == ue_db.end()) {
156+
// wrap-around
157+
it = ue_db.begin();
158+
}
159+
const ue& u = **it;
160+
const alloc_outcome alloc_result = alloc_ue(u, pusch_td_res_idx);
161+
if (alloc_result == alloc_outcome::skip_slot) {
162+
// Grid allocator directed policy to stop allocations for this slot.
163+
return next_ue_index;
164+
}
165+
166+
if (alloc_result == alloc_outcome::success) {
167+
if (first_alloc) {
168+
// Mark the next UE to be the first UE to get allocated in the following slot.
169+
// It is important that we equally distribute the opportunity to be the first UE being allocated in a slot for
170+
// all UEs. Otherwise, we could end up in a situation, where a UE is always the last one to be allocated and
171+
// can only use the RBs that were left from the previous UE allocations.
172+
next_ue_index = to_du_ue_index((unsigned)u.ue_index + 1U);
173+
first_alloc = false;
174+
}
175+
}
176+
}
177+
}
178+
179+
return next_ue_index;
180+
}
181+
115182
/// \brief Algorithm to select next UE to allocate in a time-domain RR fashion
116183
/// \param[in] ue_db map of "slot_ue"
117184
/// \param[in] next_ue_index UE index with the highest priority to be allocated.
118185
/// \param[in] alloc_ue callable with signature "bool(ue&)" that returns true if UE allocation was successful.
119186
/// \return Index of next UE to allocate.
120187
template <typename AllocUEFunc>
121-
du_ue_index_t round_robin_apply(const ue_repository& ue_db, du_ue_index_t next_ue_index, const AllocUEFunc& alloc_ue)
188+
du_ue_index_t round_robin_dl_apply(const ue_repository& ue_db, du_ue_index_t next_ue_index, const AllocUEFunc& alloc_ue)
122189
{
123190
if (ue_db.empty()) {
124191
return next_ue_index;
@@ -252,7 +319,15 @@ static alloc_outcome alloc_ul_ue(const ue& u,
252319
bool is_retx,
253320
bool schedule_sr_only,
254321
srslog::basic_logger& logger,
322+
unsigned pusch_td_res_idx,
255323
optional<unsigned> ul_new_tx_max_nof_rbs_per_ue_per_slot = {})
324+
// static alloc_outcome alloc_ul_ue(const ue& u,
325+
// const ue_resource_grid_view& res_grid,
326+
// ue_pusch_allocator& pusch_alloc,
327+
// bool is_retx,
328+
// bool schedule_sr_only,
329+
// srslog::basic_logger& logger,
330+
// optional<unsigned> ul_new_tx_max_nof_rbs_per_ue_per_slot = {})
256331
{
257332
unsigned pending_newtx_bytes = 0;
258333
if (not is_retx) {
@@ -270,11 +345,6 @@ static alloc_outcome alloc_ul_ue(const ue& u,
270345
const ue_cell& ue_cc = u.get_cell(to_ue_cell_index(i));
271346
const slot_point pdcch_slot = res_grid.get_pdcch_slot(ue_cc.cell_index);
272347

273-
// UE is already allocated resources.
274-
if (res_grid.has_ue_ul_pdcch(ue_cc.cell_index, u.crnti)) {
275-
return alloc_outcome::skip_ue;
276-
}
277-
278348
const cell_configuration& cell_cfg_common = res_grid.get_cell_cfg_common(ue_cc.cell_index);
279349
const ul_harq_process* h = is_retx ? ue_cc.harqs.find_pending_ul_retx() : ue_cc.harqs.find_empty_ul_harq();
280350
if (h == nullptr) {
@@ -308,12 +378,14 @@ static alloc_outcome alloc_ul_ue(const ue& u,
308378
continue;
309379
}
310380

311-
// - [Implementation-defined] k2 value which is less than or equal to minimum value of k1(s) is used.
312-
// Assumes that first entry in the PUSCH Time Domain resource list contains the k2 value which is less than or
313-
// equal to minimum value of k1(s).
314-
const unsigned time_res = 0;
315-
const pusch_time_domain_resource_allocation& pusch_td = ss->pusch_time_domain_list[time_res];
316-
const slot_point pusch_slot = pdcch_slot + pusch_td.k2 + cell_cfg_common.ntn_cs_koffset;
381+
const pusch_time_domain_resource_allocation& pusch_td = ss->pusch_time_domain_list[pusch_td_res_idx];
382+
383+
// UE is already allocated PUSCH.
384+
if (res_grid.has_ue_ul_grant(ue_cc.cell_index, u.crnti, pusch_td.k2)) {
385+
return alloc_outcome::skip_ue;
386+
}
387+
388+
const slot_point pusch_slot = pdcch_slot + pusch_td.k2 + cell_cfg_common.ntn_cs_koffset;
317389
const unsigned start_ul_symbols =
318390
NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell_cfg_common.get_nof_ul_symbol_per_slot(pusch_slot);
319391
// If it is a retx, we need to ensure we use a time_domain_resource with the same number of symbols as used for
@@ -401,7 +473,7 @@ static alloc_outcome alloc_ul_ue(const ue& u,
401473
h->id,
402474
ue_grant_crbs,
403475
pusch_td.symbols,
404-
time_res,
476+
pusch_td_res_idx,
405477
ss->cfg->get_id(),
406478
aggr_lvl,
407479
mcs_prbs.mcs});
@@ -433,7 +505,7 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc,
433505
auto retx_ue_function = [this, &res_grid, &pdsch_alloc](const ue& u) {
434506
return alloc_dl_ue(u, res_grid, pdsch_alloc, true, logger);
435507
};
436-
next_dl_ue_index = round_robin_apply(ues, next_dl_ue_index, retx_ue_function);
508+
next_dl_ue_index = round_robin_dl_apply(ues, next_dl_ue_index, retx_ue_function);
437509

438510
// Then, schedule new transmissions.
439511
const unsigned dl_new_tx_max_nof_rbs_per_ue_per_slot =
@@ -442,7 +514,7 @@ void scheduler_time_rr::dl_sched(ue_pdsch_allocator& pdsch_alloc,
442514
auto tx_ue_function = [this, &res_grid, &pdsch_alloc, dl_new_tx_max_nof_rbs_per_ue_per_slot](const ue& u) {
443515
return alloc_dl_ue(u, res_grid, pdsch_alloc, false, logger, dl_new_tx_max_nof_rbs_per_ue_per_slot);
444516
};
445-
next_dl_ue_index = round_robin_apply(ues, next_dl_ue_index, tx_ue_function);
517+
next_dl_ue_index = round_robin_dl_apply(ues, next_dl_ue_index, tx_ue_function);
446518
}
447519
}
448520

@@ -451,24 +523,26 @@ void scheduler_time_rr::ul_sched(ue_pusch_allocator& pusch_alloc,
451523
const ue_repository& ues)
452524
{
453525
// First schedule UL data re-transmissions.
454-
auto data_retx_ue_function = [this, &res_grid, &pusch_alloc](const ue& u) {
455-
return alloc_ul_ue(u, res_grid, pusch_alloc, true, false, logger);
526+
auto data_retx_ue_function = [this, &res_grid, &pusch_alloc](const ue& u, unsigned pusch_td_res_idx) {
527+
return alloc_ul_ue(u, res_grid, pusch_alloc, true, false, logger, pusch_td_res_idx);
456528
};
457-
next_ul_ue_index = round_robin_apply(ues, next_ul_ue_index, data_retx_ue_function);
529+
next_ul_ue_index = round_robin_ul_apply(ues, next_ul_ue_index, data_retx_ue_function);
458530

459531
// Then, schedule all pending SR.
460-
auto sr_ue_function = [this, &res_grid, &pusch_alloc](const ue& u) {
461-
return alloc_ul_ue(u, res_grid, pusch_alloc, false, true, logger);
532+
auto sr_ue_function = [this, &res_grid, &pusch_alloc](const ue& u, unsigned pusch_td_res_idx) {
533+
return alloc_ul_ue(u, res_grid, pusch_alloc, false, true, logger, pusch_td_res_idx);
462534
};
463-
next_ul_ue_index = round_robin_apply(ues, next_ul_ue_index, sr_ue_function);
535+
next_ul_ue_index = round_robin_ul_apply(ues, next_ul_ue_index, sr_ue_function);
464536

465537
// Finally, schedule UL data new transmissions.
466538
const unsigned ul_new_tx_max_nof_rbs_per_ue_per_slot =
467539
compute_max_nof_rbs_per_ue_per_slot(ues, false, res_grid, expert_cfg);
468540
if (ul_new_tx_max_nof_rbs_per_ue_per_slot > 0) {
469-
auto data_tx_ue_function = [this, &res_grid, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const ue& u) {
470-
return alloc_ul_ue(u, res_grid, pusch_alloc, false, false, logger, ul_new_tx_max_nof_rbs_per_ue_per_slot);
471-
};
472-
next_ul_ue_index = round_robin_apply(ues, next_ul_ue_index, data_tx_ue_function);
541+
auto data_tx_ue_function =
542+
[this, &res_grid, &pusch_alloc, ul_new_tx_max_nof_rbs_per_ue_per_slot](const ue& u, unsigned pusch_td_res_idx) {
543+
return alloc_ul_ue(
544+
u, res_grid, pusch_alloc, false, false, logger, pusch_td_res_idx, ul_new_tx_max_nof_rbs_per_ue_per_slot);
545+
};
546+
next_ul_ue_index = round_robin_ul_apply(ues, next_ul_ue_index, data_tx_ue_function);
473547
}
474548
}

0 commit comments

Comments
 (0)