Skip to content

Commit 72a367e

Browse files
committed
fapi_adaptor: removed the mutex from the FAPI PHY adaptor and use an atomic to store the slot
added warnings to the dummy downlink processor
1 parent 5d72d8b commit 72a367e

File tree

7 files changed

+117
-42
lines changed

7 files changed

+117
-42
lines changed

lib/fapi/message_loggers.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ static void log_csi_rs_pdu(const dl_csi_rs_pdu& pdu, fmt::memory_buffer& buffer)
125125
void srsran::fapi::log_dl_tti_request(const dl_tti_request_message& msg, srslog::basic_logger& logger)
126126
{
127127
fmt::memory_buffer buffer;
128-
fmt::format_to(buffer, "DL_TTI.request slot={}.{}", msg.sfn, msg.slot);
128+
fmt::format_to(
129+
buffer, "DL_TTI.request slot={}.{}, is_last_message_in_slot={}", msg.sfn, msg.slot, msg.is_last_message_in_slot);
129130

130131
for (const auto& pdu : msg.pdus) {
131132
switch (pdu.pdu_type) {
@@ -430,7 +431,8 @@ void srsran::fapi::log_slot_indication(const slot_indication_message& msg, srslo
430431
void srsran::fapi::log_ul_dci_request(const ul_dci_request_message& msg, srslog::basic_logger& logger)
431432
{
432433
fmt::memory_buffer buffer;
433-
fmt::format_to(buffer, "UL_DCI.request slot={}.{}", msg.sfn, msg.slot);
434+
fmt::format_to(
435+
buffer, "UL_DCI.request slot={}.{}, is_last_message_in_slot={}", msg.sfn, msg.slot, msg.is_last_message_in_slot);
434436

435437
for (const auto& pdu : msg.pdus) {
436438
switch (pdu.pdu_type) {

lib/fapi_adaptor/phy/fapi_to_phy_translator.cpp

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,24 @@ namespace {
3333
class downlink_processor_dummy : public downlink_processor
3434
{
3535
public:
36-
void process_pdcch(const pdcch_processor::pdu_t& pdu) override {}
36+
void process_pdcch(const pdcch_processor::pdu_t& pdu) override
37+
{
38+
srslog::fetch_basic_logger("FAPI").warning("Could not enqueue PDCCH PDU in the downlink processor");
39+
}
3740
void process_pdsch(unique_tx_buffer softbuffer,
3841
const static_vector<span<const uint8_t>, pdsch_processor::MAX_NOF_TRANSPORT_BLOCKS>& data,
3942
const pdsch_processor::pdu_t& pdu) override
4043
{
44+
srslog::fetch_basic_logger("FAPI").warning("Could not enqueue PDSCH PDU in the downlink processor");
45+
}
46+
void process_ssb(const ssb_processor::pdu_t& pdu) override
47+
{
48+
srslog::fetch_basic_logger("FAPI").warning("Could not enqueue SSB PDU in the downlink processor");
49+
}
50+
void process_nzp_csi_rs(const nzp_csi_rs_generator::config_t& config) override
51+
{
52+
srslog::fetch_basic_logger("FAPI").warning("Could not enqueue NZP-CSI-RS PDU in the downlink processor");
4153
}
42-
void process_ssb(const ssb_processor::pdu_t& pdu) override {}
43-
void process_nzp_csi_rs(const nzp_csi_rs_generator::config_t& config) override {}
4454
bool configure_resource_grid(const resource_grid_context& context, resource_grid& grid) override { return true; }
4555
void finish_processing_pdus() override {}
4656
};
@@ -270,9 +280,13 @@ void fapi_to_phy_translator::dl_tti_request(const fapi::dl_tti_request_message&
270280
{
271281
// :TODO: check the current slot matches the DL_TTI.request slot. Do this in a different class.
272282
// :TODO: check the messages order. Do this in a different class.
273-
std::lock_guard<std::mutex> lock(mutex);
274-
275283
slot_point slot(scs, msg.sfn, msg.slot);
284+
slot_point current_slot = get_current_slot();
285+
286+
if (!pdsch_repository.empty()) {
287+
logger.warning(
288+
"Could not process '{}' PDSCH PDUs from the slot '{}'", pdsch_repository.pdus.size(), pdsch_repository.slot);
289+
}
276290

277291
// Reset the repository.
278292
pdsch_repository.reset(slot);
@@ -428,9 +442,11 @@ static expected<uplink_pdus> translate_ul_tti_pdus_to_phy_pdus(const fapi::ul_tt
428442
void fapi_to_phy_translator::ul_tti_request(const fapi::ul_tti_request_message& msg)
429443
{
430444
// :TODO: check the messages order. Do this in a different class.
431-
std::lock_guard<std::mutex> lock(mutex);
432-
433445
slot_point slot(scs, msg.sfn, msg.slot);
446+
slot_point current_slot = get_current_slot();
447+
448+
// Clear the repository for the message slot.
449+
ul_pdu_repository.clear_slot(slot);
434450

435451
// Release the controller of the previous slot in case that it has not been released before. In case that it already
436452
// is released, this call will do nothing.
@@ -488,7 +504,7 @@ void fapi_to_phy_translator::ul_tti_request(const fapi::ul_tti_request_message&
488504

489505
void fapi_to_phy_translator::ul_dci_request(const fapi::ul_dci_request_message& msg)
490506
{
491-
std::lock_guard<std::mutex> lock(mutex);
507+
slot_point current_slot = get_current_slot();
492508

493509
// Ignore messages that do not correspond to the current slot.
494510
if (!is_message_in_time(msg)) {
@@ -535,7 +551,7 @@ void fapi_to_phy_translator::ul_dci_request(const fapi::ul_dci_request_message&
535551

536552
void fapi_to_phy_translator::tx_data_request(const fapi::tx_data_request_message& msg)
537553
{
538-
std::lock_guard<std::mutex> lock(mutex);
554+
slot_point current_slot = get_current_slot();
539555

540556
// Ignore messages that do not correspond to the current slot.
541557
if (!is_message_in_time(msg)) {
@@ -544,6 +560,9 @@ void fapi_to_phy_translator::tx_data_request(const fapi::tx_data_request_message
544560
error_notifier.get().on_error_indication(fapi::build_invalid_sfn_error_indication(
545561
msg.sfn, msg.slot, fapi::message_type_id::tx_data_request, current_slot.sfn(), current_slot.slot_index()));
546562
l2_tracer << instant_trace_event{"tx_data_req_late", instant_trace_event::cpu_scope::global};
563+
564+
pdsch_repository.clear();
565+
547566
return;
548567
}
549568

@@ -553,6 +572,9 @@ void fapi_to_phy_translator::tx_data_request(const fapi::tx_data_request_message
553572
pdsch_repository.pdus.size());
554573
// Raise invalid format error.
555574
error_notifier.get().on_error_indication(fapi::build_msg_tx_error_indication(msg.sfn, msg.slot));
575+
576+
pdsch_repository.clear();
577+
556578
return;
557579
}
558580

@@ -611,15 +633,18 @@ void fapi_to_phy_translator::tx_data_request(const fapi::tx_data_request_message
611633
}
612634

613635
slot_controller_mngr.release_controller(slot);
636+
637+
// All the PDSCH PDUs have been processed. Clear the repository.
638+
pdsch_repository.clear();
614639
}
615640

616641
void fapi_to_phy_translator::handle_new_slot(slot_point slot)
617642
{
618-
std::lock_guard<std::mutex> lock(mutex);
643+
// Update the atomic variable that holds the slot point.
644+
current_slot_count_val.store(slot.system_slot(), std::memory_order_release);
619645

620-
current_slot = slot;
646+
// Release old controllers.
621647
slot_controller_mngr.handle_new_slot(slot);
622-
ul_pdu_repository.clear_slot(slot);
623648

624649
// Enqueue soft buffer run slot.
625650
if (!asynchronous_executor.execute([this, slot]() { buffer_pool.run_slot(slot); })) {
@@ -634,6 +659,7 @@ template <typename T>
634659
bool fapi_to_phy_translator::is_message_in_time(const T& msg) const
635660
{
636661
slot_point msg_slot(scs, msg.sfn, msg.slot);
662+
slot_point current_slot = get_current_slot();
637663
slot_point last_allowed_message = current_slot - int(nof_slots_request_headroom);
638664

639665
return last_allowed_message <= msg_slot && msg_slot <= current_slot;
@@ -647,7 +673,7 @@ fapi_to_phy_translator::slot_based_upper_phy_controller_manager::get_controller(
647673

648674
void fapi_to_phy_translator::slot_based_upper_phy_controller_manager::handle_new_slot(slot_point slot)
649675
{
650-
// Remove the oldest controller.
676+
// Release the oldest controller.
651677
slot_point oldest_slot = slot - int(controllers.size() - 1);
652678
controller(oldest_slot) = slot_based_upper_phy_controller();
653679
}
@@ -673,7 +699,13 @@ fapi_to_phy_translator::slot_based_upper_phy_controller_manager::slot_based_uppe
673699
dl_processor_pool(dl_processor_pool_),
674700
rg_pool(rg_pool_),
675701
sector_id(sector_id_),
676-
// The manager should be able to manage the current slot plus the requests headroom size.
677-
controllers(nof_slots_request_headroom + 1U)
702+
// The manager should be able to manage the current slot plus the requests headroom size. Also, as it should clean the
703+
// oldest slot when a new SLOT.indication is received, it should have two extra positions for these oldest slots.
704+
// Adding two extra positions makes that if a new SLOT.indication arrives in the middle of a valid processing PDU, the
705+
// controller for that slot will not be released in the middle of processing the messages.
706+
// NOTE: if we can ensure that no messages will be lost, we can remove this extra positions in the manager, as it
707+
// would not be required to release controllers when the slot changes, Also, this would be valid when the time when a
708+
// controller is released does not matter for incomplete/lost messages.
709+
controllers(nof_slots_request_headroom + 3U)
678710
{
679711
}

lib/fapi_adaptor/phy/fapi_to_phy_translator.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@ class fapi_to_phy_translator : public fapi::slot_message_gateway
231231
template <typename T>
232232
bool is_message_in_time(const T& msg) const;
233233

234+
/// Returns this adaptor current slot.
235+
slot_point get_current_slot() const
236+
{
237+
return slot_point(scs, current_slot_count_val.load(std::memory_order_acquire));
238+
}
239+
234240
private:
235241
/// Sector identifier.
236242
const unsigned sector_id;
@@ -252,8 +258,8 @@ class fapi_to_phy_translator : public fapi::slot_message_gateway
252258
uplink_slot_pdu_repository& ul_pdu_repository;
253259
/// Asynchronous task executor.
254260
task_executor& asynchronous_executor;
255-
/// Current slot.
256-
slot_point current_slot;
261+
/// Current slot count value.
262+
std::atomic<uint32_t> current_slot_count_val;
257263
/// Slot controller manager.
258264
slot_based_upper_phy_controller_manager slot_controller_mngr;
259265
/// Precoding matrix repository.
@@ -262,9 +268,6 @@ class fapi_to_phy_translator : public fapi::slot_message_gateway
262268
std::unique_ptr<uci_part2_correspondence_repository> part2_repo;
263269
/// Error indication notifier.
264270
std::reference_wrapper<fapi::slot_error_message_notifier> error_notifier;
265-
/// Protects concurrent access to shared variables.
266-
// :TODO: make this lock free.
267-
std::mutex mutex;
268271
/// Subcarrier spacing as per TS38.211 Section 4.2.
269272
const subcarrier_spacing scs;
270273
/// Common subcarrier spacing as per TS38.331 Section 6.2.2.

lib/ofh/receiver/ofh_uplane_prach_symbol_data_flow_writer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ void uplane_prach_symbol_data_flow_writer::write_to_prach_buffer(unsigned
2121

2222
prach_context prach_context = prach_context_repo.get(slot);
2323
if (prach_context.empty()) {
24-
logger.info("Dropped received Open Fronthaul message as no uplink PRACH context was found for slot '{}'", slot);
24+
logger.info(
25+
"Dropped received Open Fronthaul message as no uplink PRACH context was found for slot '{}' and eAxC '{}'",
26+
slot,
27+
eaxc);
2528
return;
2629
}
2730

lib/ofh/receiver/ofh_uplane_rx_symbol_data_flow_writer.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ void uplane_rx_symbol_data_flow_writer::write_to_resource_grid(unsigned
2121
unsigned symbol = results.params.symbol_id;
2222
uplink_context ul_context = ul_context_repo.get(slot, symbol);
2323
if (ul_context.empty()) {
24-
logger.warning(
25-
"Dropped received Open Fronthaul message as no uplink slot context was found for slot '{}' and symbol '{}'",
26-
results.params.slot,
27-
results.params.symbol_id);
24+
logger.warning("Dropped received Open Fronthaul message as no uplink slot context was found for slot '{}', symbol "
25+
"'{}' and eAxC '{}'",
26+
results.params.slot,
27+
results.params.symbol_id,
28+
eaxc);
2829

2930
return;
3031
}

tests/unittests/fapi/validators/helpers.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ dl_tti_request_message unittest::build_valid_dl_tti_request()
319319
msg.pdus.back().pdu_type = dl_pdu_type::CSI_RS;
320320
msg.pdus.back().csi_rs_pdu = build_valid_dl_csi_pdu();
321321

322+
msg.is_last_message_in_slot = false;
323+
322324
return msg;
323325
}
324326

@@ -337,6 +339,8 @@ ul_dci_request_message unittest::build_valid_ul_dci_request()
337339
msg.pdus.back().pdu_type = ul_dci_pdu_type::PDCCH;
338340
msg.pdus.back().pdu = build_valid_dl_pdcch_pdu();
339341

342+
msg.is_last_message_in_slot = true;
343+
340344
return msg;
341345
}
342346

tests/unittests/fapi_adaptor/phy/fapi_to_phy_translator_test.cpp

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,18 @@ class fapi_to_phy_translator_fixture : public ::testing::Test
109109
resource_grid_pool_dummy rg_pool;
110110
uplink_request_processor_dummy ul_request_processor;
111111
uplink_slot_pdu_repository pdu_repo;
112-
const unsigned sector_id = 0;
113-
const unsigned allowed_delay_slots = 2;
114-
const subcarrier_spacing scs = subcarrier_spacing::kHz15;
115-
const slot_point slot = {scs, 1, 0};
112+
const unsigned sector_id = 0;
113+
const unsigned headroom_in_slots = 2;
114+
const subcarrier_spacing scs = subcarrier_spacing::kHz15;
115+
const slot_point slot = {scs, 1, 0};
116116
fapi::prach_config prach_cfg;
117117
fapi::carrier_config carrier_cfg = {0, 0, {}, {11, 51, 106, 0, 0}, 0, 0, 0, {}, {}, 0, 0, 0, 0};
118118
downlink_pdu_validator_dummy dl_pdu_validator;
119119
uplink_pdu_validator_dummy ul_pdu_validator;
120120
slot_error_message_notifier_spy error_notifier_spy;
121121
manual_task_worker worker;
122122
tx_softbuffer_pool_spy softbuffer_pool_spy;
123-
fapi_to_phy_translator_config config =
124-
{sector_id, allowed_delay_slots, scs, scs_common, &prach_cfg, &carrier_cfg, {0}};
123+
fapi_to_phy_translator_config config = {sector_id, headroom_in_slots, scs, scs_common, &prach_cfg, &carrier_cfg, {0}};
125124
fapi_to_phy_translator_dependencies dependencies = {
126125
&srslog::fetch_basic_logger("FAPI"),
127126
&dl_processor_pool,
@@ -151,10 +150,6 @@ TEST_F(fapi_to_phy_translator_fixture, downlink_processor_is_not_configured_on_n
151150
ASSERT_FALSE(dl_processor_pool.processor(slot).has_configure_resource_grid_method_been_called());
152151
ASSERT_FALSE(grid.has_set_all_zero_method_been_called());
153152

154-
// Assert that the downlink processor is configured.
155-
ASSERT_FALSE(dl_processor_pool.processor(slot).has_configure_resource_grid_method_been_called());
156-
ASSERT_FALSE(grid.has_set_all_zero_method_been_called());
157-
158153
// Assert that the softbuffer pool ran the slot.
159154
auto& run_slot_entries = softbuffer_pool_spy.get_run_slot_entries();
160155
ASSERT_EQ(run_slot_entries.size(), 1);
@@ -246,7 +241,7 @@ TEST_F(fapi_to_phy_translator_fixture, dl_ssb_pdu_within_allowed_delay_is_proces
246241
translator.handle_new_slot(msg_slot);
247242

248243
// Increase the slots.
249-
for (unsigned i = 1; i != allowed_delay_slots; ++i) {
244+
for (unsigned i = 1; i != headroom_in_slots; ++i) {
250245
translator.handle_new_slot(msg_slot + i);
251246
}
252247

@@ -272,7 +267,7 @@ TEST_F(fapi_to_phy_translator_fixture, receiving_a_dl_tti_request_sends_previous
272267
msg.is_last_message_in_slot = false;
273268

274269
// Increase the slots.
275-
for (unsigned i = 1; i != allowed_delay_slots; ++i) {
270+
for (unsigned i = 1; i != headroom_in_slots; ++i) {
276271
translator.handle_new_slot(slot + i);
277272
}
278273

@@ -305,7 +300,7 @@ TEST_F(fapi_to_phy_translator_fixture, receiving_a_dl_tti_request_from_a_slot_de
305300
msg.is_last_message_in_slot = false;
306301

307302
// Increase the slots.
308-
for (unsigned i = 0, e = allowed_delay_slots + 1; i != e; ++i) {
303+
for (unsigned i = 0, e = headroom_in_slots + 1; i != e; ++i) {
309304
current_slot += 1;
310305
translator.handle_new_slot(current_slot);
311306
}
@@ -324,6 +319,39 @@ TEST_F(fapi_to_phy_translator_fixture, receiving_a_dl_tti_request_from_a_slot_de
324319
ASSERT_EQ(error_msg.expected_slot, current_slot.slot_index());
325320
}
326321

322+
TEST_F(fapi_to_phy_translator_fixture, message_received_is_sended_when_a_message_for_the_next_slot_is_received)
323+
{
324+
ASSERT_FALSE(dl_processor_pool.processor(slot).has_configure_resource_grid_method_been_called());
325+
ASSERT_FALSE(grid.has_set_all_zero_method_been_called());
326+
327+
fapi::dl_tti_request_message msg;
328+
msg.sfn = slot.sfn();
329+
msg.slot = slot.slot_index();
330+
msg.is_last_message_in_slot = false;
331+
332+
// Send a DL_TTI.request.
333+
translator.dl_tti_request(msg);
334+
335+
// Assert that the downlink processor is configured.
336+
ASSERT_TRUE(dl_processor_pool.processor(slot).has_configure_resource_grid_method_been_called());
337+
// Assert that the resource grid has NOT been set to zero.
338+
ASSERT_FALSE(grid.has_set_all_zero_method_been_called());
339+
340+
// Increase the slots.
341+
ASSERT_FALSE(dl_processor_pool.processor(slot).has_finish_processing_pdus_method_been_called());
342+
343+
translator.handle_new_slot(slot + headroom_in_slots);
344+
345+
ASSERT_FALSE(dl_processor_pool.processor(slot).has_finish_processing_pdus_method_been_called());
346+
347+
++msg.slot;
348+
translator.dl_tti_request(msg);
349+
350+
// Assert that the finish processing PDUs method of the previous slot downlink_processor has been called.
351+
ASSERT_TRUE(dl_processor_pool.processor(slot).has_finish_processing_pdus_method_been_called());
352+
ASSERT_FALSE(error_notifier_spy.has_on_error_indication_been_called());
353+
}
354+
327355
TEST_F(fapi_to_phy_translator_fixture, message_received_is_sended_when_the_current_slot_is_bigger_than_the_allowed)
328356
{
329357
ASSERT_FALSE(dl_processor_pool.processor(slot).has_configure_resource_grid_method_been_called());
@@ -342,13 +370,15 @@ TEST_F(fapi_to_phy_translator_fixture, message_received_is_sended_when_the_curre
342370
// Assert that the resource grid has NOT been set to zero.
343371
ASSERT_FALSE(grid.has_set_all_zero_method_been_called());
344372

373+
// The manager headroom size is the number of headroom in slots plus 3.
374+
unsigned manager_headroom_size = headroom_in_slots + 3U;
345375
// Increase the slots.
346-
for (unsigned i = 0; i != allowed_delay_slots; ++i) {
376+
for (unsigned i = 1; i != (manager_headroom_size - 1U); ++i) {
347377
translator.handle_new_slot(slot + i);
348378
ASSERT_FALSE(dl_processor_pool.processor(slot).has_finish_processing_pdus_method_been_called());
349379
}
350380

351-
translator.handle_new_slot(slot + allowed_delay_slots);
381+
translator.handle_new_slot(slot + (manager_headroom_size - 1U));
352382

353383
// Assert that the finish processing PDUs method of the previous slot downlink_processor has been called.
354384
ASSERT_TRUE(dl_processor_pool.processor(slot).has_finish_processing_pdus_method_been_called());

0 commit comments

Comments
 (0)