Skip to content

Commit 8d0a2f9

Browse files
committed
sched: simplify pucch_collision_manager interface
1 parent 4350ad4 commit 8d0a2f9

File tree

5 files changed

+119
-108
lines changed

5 files changed

+119
-108
lines changed

lib/scheduler/pucch_scheduling/pucch_allocator_impl.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,10 @@ void pucch_allocator_impl::alloc_sr_opportunity(cell_slot_resource_allocator& pu
259259
const pucch_resource* pucch_sr_res = resource_manager.reserve_sr_resource(
260260
pucch_slot_alloc.slot, crnti, ue_cell_cfg.init_bwp().ul_ded->pucch_cfg.value());
261261
if (pucch_sr_res == nullptr) {
262-
logger.warning("rnti={}: SR occasion allocation for slot={} skipped. Cause: PUCCH F1 ded. resource not available",
263-
crnti,
264-
pucch_slot_alloc.slot);
262+
logger.warning(
263+
"rnti={}: SR occasion allocation for slot={} skipped. Cause: PUCCH resource configured for SR not available",
264+
crnti,
265+
pucch_slot_alloc.slot);
265266
return;
266267
}
267268

lib/scheduler/pucch_scheduling/pucch_collision_manager.cpp

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "pucch_collision_manager.h"
1212
#include "../support/pucch/pucch_default_resource.h"
1313
#include "srsran/adt/bounded_bitset.h"
14+
#include "srsran/adt/expected.h"
1415
#include "srsran/adt/static_vector.h"
1516
#include "srsran/ran/pucch/pucch_configuration.h"
1617
#include "srsran/ran/pucch/pucch_constants.h"
@@ -198,65 +199,26 @@ bool pucch_collision_manager::check_common_to_ded_collision(r_pucch_t r_pucch, u
198199
return collision_matrix[r_pucch.value()].test(nof_common_res + cell_res_id);
199200
}
200201

201-
bool pucch_collision_manager::can_alloc_common(slot_point sl, r_pucch_t r_pucch) const
202+
pucch_collision_manager::alloc_result_t pucch_collision_manager::alloc_common(slot_point sl, r_pucch_t r_pucch)
202203
{
203-
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
204-
"PUCCH resource ring-buffer accessed too far into the future");
205-
206-
const auto& ctx = slots_ctx[sl.to_uint()];
207-
const auto& row = collision_matrix[r_pucch.value()];
208-
209-
return (row & ctx.current_state).none();
210-
}
211-
212-
bool pucch_collision_manager::can_alloc_ded(slot_point sl, unsigned cell_res_id) const
213-
{
214-
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
215-
"PUCCH resource ring-buffer accessed too far into the future");
216-
srsran_assert(cell_res_id < cell_cfg.ded_pucch_resources.size(), "cell_res_id out of range");
217-
218-
const auto& ctx = slots_ctx[sl.to_uint()];
219-
const auto& row = collision_matrix[nof_common_res + cell_res_id];
220-
221-
return (row & ctx.current_state).none();
204+
return alloc_resource(sl, r_pucch.value());
222205
}
223206

224-
void pucch_collision_manager::alloc_common(slot_point sl, r_pucch_t r_pucch)
207+
pucch_collision_manager::alloc_result_t pucch_collision_manager::alloc_ded(slot_point sl, unsigned cell_res_id)
225208
{
226-
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
227-
"PUCCH resource ring-buffer accessed too far into the future");
228-
229-
auto& ctx = slots_ctx[sl.to_uint()];
230-
ctx.current_state.set(r_pucch.value());
231-
}
232-
233-
void pucch_collision_manager::alloc_ded(slot_point sl, unsigned cell_res_id)
234-
{
235-
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
236-
"PUCCH resource ring-buffer accessed too far into the future");
237209
srsran_assert(cell_res_id < cell_cfg.ded_pucch_resources.size(), "cell_res_id out of range");
238-
239-
auto& ctx = slots_ctx[sl.to_uint()];
240-
ctx.current_state.set(nof_common_res + cell_res_id);
210+
return alloc_resource(sl, nof_common_res + cell_res_id);
241211
}
242212

243213
void pucch_collision_manager::free_common(slot_point sl, r_pucch_t r_pucch)
244214
{
245-
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
246-
"PUCCH resource ring-buffer accessed too far into the future");
247-
248-
auto& ctx = slots_ctx[sl.to_uint()];
249-
ctx.current_state.reset(r_pucch.value());
215+
free_resource(sl, r_pucch.value());
250216
}
251217

252218
void pucch_collision_manager::free_ded(slot_point sl, unsigned cell_res_id)
253219
{
254-
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
255-
"PUCCH resource ring-buffer accessed too far into the future");
256220
srsran_assert(cell_res_id < cell_cfg.ded_pucch_resources.size(), "cell_res_id out of range");
257-
258-
auto& ctx = slots_ctx[sl.to_uint()];
259-
ctx.current_state.reset(nof_common_res + cell_res_id);
221+
free_resource(sl, nof_common_res + cell_res_id);
260222
}
261223

262224
/// Collects all PUCCH resources (common + dedicated) from the cell configuration.
@@ -345,3 +307,38 @@ pucch_collision_manager::compute_mux_regions(span<const detail::resource_info> r
345307
}
346308
return mux_regions;
347309
}
310+
311+
pucch_collision_manager::alloc_result_t pucch_collision_manager::alloc_resource(slot_point sl, unsigned res_idx)
312+
{
313+
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
314+
"PUCCH resource ring-buffer accessed too far into the future");
315+
316+
// TODO: Take in ul_res_grid as a parameter.
317+
// TODO: Compute the difference grid ul_res_grid - ctx.pucch_res_grid.
318+
// TODO: Check if the resource collides in the difference grid (with any non-PUCCH UL grant).
319+
320+
// Check for PUCCH-to-PUCCH collisions using the collision matrix.
321+
auto& ctx = slots_ctx[sl.to_uint()];
322+
const auto& row = collision_matrix[res_idx];
323+
if ((row & ctx.current_state).any()) {
324+
return make_unexpected(alloc_failure_reason::PUCCH_COLLISION);
325+
}
326+
327+
// Allocate the resource.
328+
ctx.current_state.set(res_idx);
329+
// TODO: mark grants in ul_res_grid.
330+
// TODO: mark grants in ctx.pucch_res_grid.
331+
return default_success_t();
332+
}
333+
334+
void pucch_collision_manager::free_resource(slot_point sl, unsigned res_idx)
335+
{
336+
srsran_sanity_check(sl < last_sl_ind + cell_resource_allocator::RING_ALLOCATOR_SIZE,
337+
"PUCCH resource ring-buffer accessed too far into the future");
338+
339+
auto& ctx = slots_ctx[sl.to_uint()];
340+
ctx.current_state.reset(res_idx);
341+
342+
// TODO: Check if any other resource in the same multiplexing region is still allocated.
343+
// If not, free the grants in ul_res_grid and ctx.pucch_res_grid.
344+
}

lib/scheduler/pucch_scheduling/pucch_collision_manager.h

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "srsran/adt/bounded_bitset.h"
1616
#include "srsran/adt/bounded_integer.h"
1717
#include "srsran/adt/circular_array.h"
18+
#include "srsran/adt/expected.h"
1819
#include "srsran/adt/span.h"
1920
#include "srsran/adt/static_vector.h"
2021
#include "srsran/ran/pucch/pucch_constants.h"
@@ -85,35 +86,34 @@ class pucch_collision_manager
8586
void slot_indication(slot_point sl_tx);
8687
void stop();
8788

88-
/// Checks if two dedicated PUCCH resources collide.
89+
/// Check if two dedicated PUCCH resources collide.
8990
bool check_ded_to_ded_collision(unsigned cell_res_id1, unsigned cell_res_id2) const;
9091

91-
/// Checks if a common PUCCH resource collides with a dedicated PUCCH resource.
92+
/// Check if a common PUCCH resource collides with a dedicated PUCCH resource.
9293
bool check_common_to_ded_collision(r_pucch_t r_pucch, unsigned cell_res_id) const;
9394

94-
/// Returns the number of multiplexing regions defined in the cell configuration.
95+
/// Return the number of multiplexing regions defined in the cell configuration.
9596
unsigned nof_mux_regions() const { return mux_matrix.size(); }
9697

97-
/// \brief Checks if a common PUCCH resource can be allocated at a given slot.
98-
/// A resource can be allocated if it is not in use and it does not collide with any other resource already allocated
99-
/// at the same slot.
100-
bool can_alloc_common(slot_point sl, r_pucch_t r_pucch) const;
101-
102-
/// \brief Checks if a dedicated PUCCH resource can be allocated at a given slot.
103-
/// A resource can be allocated if it is not in use and it does not collide with any other resource already allocated
104-
/// at the same slot.
105-
bool can_alloc_ded(slot_point sl, unsigned cell_res_id) const;
98+
/// Reasons for a PUCCH allocation failure.
99+
enum class alloc_failure_reason {
100+
PUCCH_COLLISION,
101+
UL_GRANT_COLLISION,
102+
};
103+
using alloc_result_t = error_type<alloc_failure_reason>;
106104

107-
/// Allocates a common PUCCH resource at a given slot.
108-
void alloc_common(slot_point sl, r_pucch_t r_pucch);
105+
/// \brief Allocate a common PUCCH resource at a given slot.
106+
/// \return Success if the allocation was successful, otherwise an error indicating the reason of failure.
107+
alloc_result_t alloc_common(slot_point sl, r_pucch_t r_pucch);
109108

110-
/// Allocates a dedicated PUCCH resource at a given slot.
111-
void alloc_ded(slot_point sl, unsigned cell_res_id);
109+
/// \brief Allocate a dedicated PUCCH resource at a given slot.
110+
/// \return Success if the allocation was successful, otherwise an error indicating the reason of failure.
111+
alloc_result_t alloc_ded(slot_point sl, unsigned cell_res_id);
112112

113-
/// Frees a common PUCCH resource at a given slot.
113+
/// Free a common PUCCH resource at a given slot.
114114
void free_common(slot_point sl, r_pucch_t r_pucch);
115115

116-
/// Frees a dedicated PUCCH resource at a given slot.
116+
/// Free a dedicated PUCCH resource at a given slot.
117117
void free_ded(slot_point sl, unsigned cell_res_id);
118118

119119
private:
@@ -152,14 +152,20 @@ class pucch_collision_manager
152152
// Keeps track of the last slot_point used by the resource manager.
153153
slot_point last_sl_ind;
154154

155-
/// Computes the collision matrix for all PUCCH resources in the cell configuration.
155+
/// Compute the collision matrix for all PUCCH resources in the cell configuration.
156156
static cell_resources_t compute_resources(const cell_configuration& cell_cfg);
157157

158-
/// Computes the collision matrix for all PUCCH resources in the cell configuration.
158+
/// Compute the collision matrix for all PUCCH resources in the cell configuration.
159159
static collision_matrix_t compute_collisions(span<const detail::resource_info> resources);
160160

161-
/// Computes the multiplexing matrix for all PUCCH resources in the cell configuration.
161+
/// Compute the multiplexing matrix for all PUCCH resources in the cell configuration.
162162
static mux_regions_matrix_t compute_mux_regions(span<const detail::resource_info> resources);
163+
164+
/// Allocate the PUCCH resource at \ref res_idx at a given slot.
165+
alloc_result_t alloc_resource(slot_point sl, unsigned res_idx);
166+
167+
/// Free the PUCCH resource at \ref res_idx at a given slot.
168+
void free_resource(slot_point sl, unsigned res_idx);
163169
};
164170

165171
} // namespace srsran

lib/scheduler/pucch_scheduling/pucch_resource_manager.cpp

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,15 @@ void pucch_resource_manager::stop()
7676
bool pucch_resource_manager::is_harq_common_resource_available(slot_point sl, size_t r_pucch)
7777
{
7878
srsran_assert(r_pucch < 16, "r_PUCCH must be less than 16");
79-
return collision_manager.can_alloc_common(sl, r_pucch);
79+
// TODO: Remove this method and use collision_manager.alloc_common directly once it checks for UL grant collisions
80+
// correctly.
81+
auto res = collision_manager.alloc_common(sl, r_pucch);
82+
if (res.has_value()) {
83+
// Allocation was successful, free the resource and return true.
84+
collision_manager.free_common(sl, r_pucch);
85+
return true;
86+
}
87+
return false;
8088
}
8189

8290
void pucch_resource_manager::reserve_harq_common_resource(slot_point sl, size_t r_pucch)
@@ -156,11 +164,10 @@ pucch_resource_manager::reserve_sr_resource(slot_point slot_sr, rnti_t crnti, co
156164
// the resource had already been allocated, just return it.
157165
if (res_rnti != crnti) {
158166
// Check for collisions.
159-
if (not collision_manager.can_alloc_ded(slot_sr, cell_res_id)) {
167+
if (not collision_manager.alloc_ded(slot_sr, cell_res_id).has_value()) {
160168
return nullptr;
161169
}
162170
res_rnti = crnti;
163-
collision_manager.alloc_ded(slot_sr, cell_res_id);
164171
}
165172

166173
return res_cfg;
@@ -205,11 +212,10 @@ const pucch_resource* pucch_resource_manager::reserve_csi_resource(slot_point
205212
// the resource had already been allocated, just return it.
206213
if (res_rnti != crnti) {
207214
// Check for collisions.
208-
if (not collision_manager.can_alloc_ded(slot_csi, cell_res_id)) {
215+
if (not collision_manager.alloc_ded(slot_csi, cell_res_id).has_value()) {
209216
return nullptr;
210217
}
211218
res_rnti = crnti;
212-
collision_manager.alloc_ded(slot_csi, cell_res_id);
213219
}
214220

215221
return res_cfg;
@@ -384,59 +390,61 @@ pucch_harq_resource_alloc_record pucch_resource_manager::reserve_next_harq_res_a
384390

385391
// For PUCCH F0 and F2, we don't use the last 2 resources of the PUCCH resource set; these are reserved for CSI and SR
386392
// slots and should only be picked for through the specific PUCCH resource indicator.
387-
const unsigned nof_eligible_resource =
393+
const unsigned nof_eligible_resources =
388394
cell_cfg.is_pucch_f0_and_f2() ? ue_res_set_id_list.size() - 2U : ue_res_set_id_list.size();
389-
srsran_assert(nof_eligible_resource >= 1U,
395+
srsran_assert(nof_eligible_resources >= 1U,
390396
"rnti={}: Not enough eligible resources from PUCCH resource set={}",
391397
crnti,
392398
pucch_res_set_idx_to_uint(res_set_idx));
393399

394400
// Get context of wanted slot.
395401
auto& ctx = slots_ctx[slot_harq.to_uint()];
396402

397-
std::optional<uint8_t> available_r_pucch;
398-
for (uint8_t r_pucch = 0; r_pucch != nof_eligible_resource; ++r_pucch) {
399-
const unsigned cell_res_id = ue_res_set_id_list[r_pucch].cell_res_id;
403+
std::optional<std::pair<uint8_t, unsigned>> available_res;
400404

405+
// If a resource is already allocated to this RNTI, use it.
406+
for (uint8_t r_pucch = 0; r_pucch != nof_eligible_resources; ++r_pucch) {
407+
const unsigned cell_res_id = ue_res_set_id_list[r_pucch].cell_res_id;
401408
srsran_assert(cell_res_id < ctx.ues_using_pucch_res.size(),
402409
"PUCCH resource index from PUCCH resource set exceeds the size of the cell resource array");
403410
auto& res_rnti = ctx.ues_using_pucch_res[cell_res_id];
404411

405412
if (res_rnti == crnti) {
406-
// If a resource is already allocated to this RNTI, use it.
407-
available_r_pucch = r_pucch;
413+
available_res = {r_pucch, cell_res_id};
408414
break;
409415
}
416+
}
410417

411-
if (not available_r_pucch.has_value() and res_rnti == rnti_t::INVALID_RNTI and
412-
collision_manager.can_alloc_ded(slot_harq, cell_res_id)) {
413-
// Else, keep track of the first available resource.
414-
available_r_pucch = r_pucch;
418+
if (not available_res.has_value()) {
419+
// Else, keep track of the first available resource.
420+
for (uint8_t r_pucch = 0; r_pucch != nof_eligible_resources; ++r_pucch) {
421+
const unsigned cell_res_id = ue_res_set_id_list[r_pucch].cell_res_id;
422+
srsran_assert(cell_res_id < ctx.ues_using_pucch_res.size(),
423+
"PUCCH resource index from PUCCH resource set exceeds the size of the cell resource array");
424+
auto& res_rnti = ctx.ues_using_pucch_res[cell_res_id];
425+
426+
if (res_rnti == rnti_t::INVALID_RNTI and collision_manager.alloc_ded(slot_harq, cell_res_id).has_value()) {
427+
ctx.ues_using_pucch_res[cell_res_id] = crnti;
428+
available_res = {r_pucch, cell_res_id};
429+
break;
430+
}
415431
}
416432
}
417433

418-
const auto& pucch_res_list = pucch_cfg.pucch_res_list;
419-
420-
// If there is an available resource, allocate it.
421-
if (available_r_pucch.has_value()) {
422-
const unsigned r_pucch = available_r_pucch.value();
423-
// Get the PUCCH resource ID from the PUCCH resource indicator and the PUCCH resource set.
424-
const unsigned cell_res_id = ue_res_set_id_list[r_pucch].cell_res_id;
425-
434+
// If an available resource was found, return it.
435+
if (available_res.has_value()) {
426436
// Search for the PUCCH resource with the correct PUCCH resource ID from the PUCCH resource list.
427-
const auto* res_cfg =
428-
std::find_if(pucch_res_list.begin(), pucch_res_list.end(), [cell_res_id](const pucch_resource& res) {
437+
const auto& pucch_res_list = pucch_cfg.pucch_res_list;
438+
const auto* res_cfg = std::find_if(
439+
pucch_res_list.begin(), pucch_res_list.end(), [cell_res_id = available_res->second](const pucch_resource& res) {
429440
return res.res_id.cell_res_id == cell_res_id;
430441
});
431442
srsran_sanity_check(res_cfg != pucch_res_list.end(),
432443
"rnti={}: PUCCH resource with cell_res_id={} not found in PUCCH resource list",
433444
crnti,
434-
cell_res_id);
445+
available_res->second);
435446

436-
// Allocate it and return it.
437-
ctx.ues_using_pucch_res[cell_res_id] = crnti;
438-
collision_manager.alloc_ded(slot_harq, cell_res_id);
439-
return pucch_harq_resource_alloc_record{.resource = res_cfg, .pucch_res_indicator = available_r_pucch.value()};
447+
return pucch_harq_resource_alloc_record{.resource = res_cfg, .pucch_res_indicator = available_res->first};
440448
}
441449
return pucch_harq_resource_alloc_record{.resource = nullptr};
442450
}
@@ -505,14 +513,11 @@ const pucch_resource* pucch_resource_manager::reserve_harq_resource_by_res_indic
505513
return res_cfg;
506514
}
507515

508-
// Check for collisions.
509-
if (not collision_manager.can_alloc_ded(slot_harq, cell_res_id)) {
516+
// Allocate the resource to this RNTI.
517+
if (not collision_manager.alloc_ded(slot_harq, cell_res_id).has_value()) {
510518
return nullptr;
511519
}
512-
513-
// Allocate the resource to this RNTI.
514520
res_rnti = crnti;
515-
collision_manager.alloc_ded(slot_harq, cell_res_id);
516521
return res_cfg;
517522
}
518523

tests/unittests/scheduler/uci_and_pucch/pucch_collision_manager_test.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ TEST(pucch_collision_manager_test, common_resources_dont_collide_with_each_other
5858
slot_point sl(cell_cfg.ul_cfg_common.init_ul_bwp.generic_params.scs, 0);
5959
col_manager.slot_indication(sl);
6060
for (unsigned r_pucch = 0; r_pucch < pucch_constants::MAX_NOF_CELL_COMMON_PUCCH_RESOURCES; ++r_pucch) {
61-
ASSERT_TRUE(col_manager.can_alloc_common(sl, r_pucch));
62-
col_manager.alloc_common(sl, r_pucch);
63-
ASSERT_FALSE(col_manager.can_alloc_common(sl, r_pucch));
61+
auto res = col_manager.alloc_common(sl, r_pucch);
62+
ASSERT_TRUE(res.has_value());
63+
res = col_manager.alloc_common(sl, r_pucch);
64+
ASSERT_FALSE(res.has_value());
65+
ASSERT_EQ(res.error(), pucch_collision_manager::alloc_failure_reason::PUCCH_COLLISION);
6466
}
6567
}
6668

0 commit comments

Comments
 (0)