From 52355024e7ac5bc1ccaa416ec97a385f1f78356c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 31 Jul 2020 08:50:32 +0200 Subject: [PATCH] SRSUE PHY: move mutex lock to cc worker and unlock for stack calls --- srsue/hdr/phy/cc_worker.h | 5 ++- srsue/hdr/phy/sf_worker.h | 7 ++-- srsue/src/phy/cc_worker.cc | 34 +++++++++++++--- srsue/src/phy/sf_worker.cc | 81 +++++++++++++++++--------------------- 4 files changed, 71 insertions(+), 56 deletions(-) diff --git a/srsue/hdr/phy/cc_worker.h b/srsue/hdr/phy/cc_worker.h index d1c2515cf..e7a29a56e 100644 --- a/srsue/hdr/phy/cc_worker.h +++ b/srsue/hdr/phy/cc_worker.h @@ -44,7 +44,7 @@ public: void set_tti(uint32_t tti); void set_cfo(float cfo); - float get_ref_cfo(); + float get_ref_cfo() const; void set_tdd_config(srslte_tdd_config_t config); void set_config(srslte::phy_cfg_t& phy_cfg); @@ -120,6 +120,9 @@ private: // Metrics dl_metrics_t dl_metrics = {}; ul_metrics_t ul_metrics = {}; + + // Mutex, for protecting what matters most: ue_ul, ue_ul_cfg, ue_dl, ue_dl_cfg, cell, pmch_cfg + std::mutex mutex; }; } // namespace srsue diff --git a/srsue/hdr/phy/sf_worker.h b/srsue/hdr/phy/sf_worker.h index 26b72e21c..8b2296f2c 100644 --- a/srsue/hdr/phy/sf_worker.h +++ b/srsue/hdr/phy/sf_worker.h @@ -69,7 +69,7 @@ public: uint32_t get_cell_nof_ports() { // wait until cell is initialized - std::unique_lock lock(mutex); + std::unique_lock lock(cell_mutex); while (!cell_initiated) { cell_init_cond.wait(lock); } @@ -98,9 +98,8 @@ private: chest_feedback_itf* chest_loop = nullptr; - std::mutex mutex; - - srslte_cell_t cell = {}; + srslte_cell_t cell = {}; + std::mutex cell_mutex; srslte_tdd_config_t tdd_config = {}; std::condition_variable cell_init_cond; diff --git a/srsue/src/phy/cc_worker.cc b/srsue/src/phy/cc_worker.cc index cfd1408c7..44635048d 100644 --- a/srsue/src/phy/cc_worker.cc +++ b/srsue/src/phy/cc_worker.cc @@ -127,6 +127,8 @@ void cc_worker::reset() bool cc_worker::set_cell(srslte_cell_t cell_) { + std::unique_lock lock(mutex); + if (cell.id != cell_.id || !cell_initiated) { cell = cell_; @@ -178,29 +180,32 @@ void cc_worker::set_tti(uint32_t tti) void cc_worker::set_cfo(float cfo) { + std::unique_lock lock(mutex); ue_ul_cfg.cfo_value = cfo; } -float cc_worker::get_ref_cfo() +float cc_worker::get_ref_cfo() const { return ue_dl.chest_res.cfo; } void cc_worker::set_crnti(uint16_t rnti) { + std::unique_lock lock(mutex); srslte_ue_dl_set_rnti(&ue_dl, rnti); srslte_ue_ul_set_rnti(&ue_ul, rnti); } void cc_worker::set_tdd_config(srslte_tdd_config_t config) { + std::unique_lock lock(mutex); sf_cfg_dl.tdd_config = config; sf_cfg_ul.tdd_config = config; } void cc_worker::enable_pregen_signals(bool enabled) { - this->pregen_enabled = enabled; + pregen_enabled = enabled; } /************ @@ -211,7 +216,8 @@ void cc_worker::enable_pregen_signals(bool enabled) bool cc_worker::work_dl_regular() { - bool dl_ack[SRSLTE_MAX_CODEWORDS] = {}; + std::unique_lock lock(mutex); + bool dl_ack[SRSLTE_MAX_CODEWORDS] = {}; mac_interface_phy_lte::tb_action_dl_t dl_action = {}; @@ -287,9 +293,17 @@ bool cc_worker::work_dl_regular() srslte_pdsch_ack_resource_t ack_resource = {dci_dl.dai, dci_dl.location.ncce, grant_cc_idx, dci_dl.tpc_pucch}; // Send grant to MAC and get action for this TB, then call tb_decoded to unlock MAC + mutex.unlock(); phy->stack->new_grant_dl(cc_idx, mac_grant, &dl_action); + mutex.lock(); + + // Decode PDSCH decode_pdsch(ack_resource, &dl_action, dl_ack); + + // Informs Stack about the decoding status + mutex.unlock(); phy->stack->tb_decoded(cc_idx, mac_grant, dl_ack); + mutex.lock(); } /* Decode PHICH */ @@ -300,6 +314,7 @@ bool cc_worker::work_dl_regular() bool cc_worker::work_dl_mbsfn(srslte_mbsfn_cfg_t mbsfn_cfg) { + std::unique_lock lock(mutex); mac_interface_phy_lte::tb_action_dl_t dl_action = {}; // Configure MBSFN settings @@ -539,7 +554,8 @@ void cc_worker::decode_phich() void cc_worker::update_measurements() { - float snr_ema_coeff = phy->args->snr_ema_coeff; + std::unique_lock lock(mutex); + float snr_ema_coeff = phy->args->snr_ema_coeff; // In TDD, ignore special subframes without PDSCH if (srslte_sfidx_tdd_type(sf_cfg_dl.tdd_config, CURRENT_SFIDX) == SRSLTE_TDD_SF_S && @@ -625,8 +641,8 @@ void cc_worker::update_measurements() bool cc_worker::work_ul(srslte_uci_data_t* uci_data) { - - bool signal_ready; + std::unique_lock lock(mutex); + bool signal_ready; srslte_dci_ul_t dci_ul = {}; mac_interface_phy_lte::mac_grant_ul_t ul_mac_grant = {}; @@ -670,7 +686,9 @@ bool cc_worker::work_ul(srslte_uci_data_t* uci_data) // Fill MAC dci ul_phy_to_mac_grant(&ue_ul_cfg.ul_cfg.pusch.grant, &dci_ul, pid, ul_grant_available, &ul_mac_grant); + mutex.unlock(); phy->stack->new_grant_ul(cc_idx, ul_mac_grant, &ul_action); + mutex.lock(); // Calculate PUSCH Hopping procedure ue_ul_cfg.ul_cfg.hopping.current_tx_nb = ul_action.current_tx_nb; @@ -857,6 +875,7 @@ uint32_t cc_worker::get_wideband_cqi() void cc_worker::set_uci_periodic_cqi(srslte_uci_data_t* uci_data) { + std::unique_lock lock(mutex); srslte_ue_dl_gen_cqi_periodic(&ue_dl, &ue_dl_cfg, get_wideband_cqi(), CURRENT_TTI_TX, uci_data); } @@ -910,6 +929,8 @@ void cc_worker::set_uci_ack(srslte_uci_data_t* uci_data, */ void cc_worker::set_config(srslte::phy_cfg_t& phy_cfg) { + std::unique_lock lock(mutex); + // Save configuration ue_dl_cfg.cfg = phy_cfg.dl_cfg; ue_ul_cfg.ul_cfg = phy_cfg.ul_cfg; @@ -926,6 +947,7 @@ void cc_worker::set_config(srslte::phy_cfg_t& phy_cfg) void cc_worker::upd_config_dci(srslte_dci_cfg_t& dci_cfg) { + std::unique_lock lock(mutex); ue_dl_cfg.cfg.dci = dci_cfg; } diff --git a/srsue/src/phy/sf_worker.cc b/srsue/src/phy/sf_worker.cc index a73514d07..4a7573cce 100644 --- a/srsue/src/phy/sf_worker.cc +++ b/srsue/src/phy/sf_worker.cc @@ -81,7 +81,6 @@ sf_worker::~sf_worker() void sf_worker::reset() { - std::lock_guard lock(mutex); rssi_read_cnt = 0; for (auto& cc_worker : cc_workers) { cc_worker->reset(); @@ -90,7 +89,7 @@ void sf_worker::reset() bool sf_worker::set_cell(uint32_t cc_idx, srslte_cell_t cell_) { - std::lock_guard lock(mutex); + std::lock_guard lock(cell_mutex); if (cc_idx < cc_workers.size()) { if (!cc_workers[cc_idx]->set_cell(cell_)) { @@ -156,7 +155,6 @@ void sf_worker::set_cfo(const uint32_t& cc_idx, float cfo) void sf_worker::set_crnti(uint16_t rnti) { - std::lock_guard lock(mutex); for (auto& cc_worker : cc_workers) { cc_worker->set_crnti(rnti); } @@ -164,7 +162,6 @@ void sf_worker::set_crnti(uint16_t rnti) void sf_worker::set_tdd_config(srslte_tdd_config_t config) { - std::lock_guard lock(mutex); for (auto& cc_worker : cc_workers) { cc_worker->set_tdd_config(config); } @@ -173,7 +170,6 @@ void sf_worker::set_tdd_config(srslte_tdd_config_t config) void sf_worker::enable_pregen_signals(bool enabled) { - std::lock_guard lock(mutex); for (auto& cc_worker : cc_workers) { cc_worker->enable_pregen_signals(enabled); } @@ -181,7 +177,6 @@ void sf_worker::enable_pregen_signals(bool enabled) void sf_worker::set_config(uint32_t cc_idx, srslte::phy_cfg_t& phy_cfg) { - std::lock_guard lock(mutex); if (cc_idx < cc_workers.size()) { Info("Setting configuration for worker=%d, cc=%d\n", get_id(), cc_idx); cc_workers[cc_idx]->set_config(phy_cfg); @@ -207,59 +202,55 @@ void sf_worker::work_imp() bool tx_signal_ready = false; uint32_t nof_samples = SRSLTE_SF_LEN_PRB(cell.nof_prb); - { - std::lock_guard lock(mutex); + /***** Downlink Processing *******/ - /***** Downlink Processing *******/ + // Loop through all carriers. carrier_idx=0 is PCell + for (uint32_t carrier_idx = 0; carrier_idx < cc_workers.size(); carrier_idx++) { - // Loop through all carriers. carrier_idx=0 is PCell - for (uint32_t carrier_idx = 0; carrier_idx < cc_workers.size(); carrier_idx++) { + // Process all DL and special subframes + if (srslte_sfidx_tdd_type(tdd_config, tti % 10) != SRSLTE_TDD_SF_U || cell.frame_type == SRSLTE_FDD) { + srslte_mbsfn_cfg_t mbsfn_cfg; + ZERO_OBJECT(mbsfn_cfg); - // Process all DL and special subframes - if (srslte_sfidx_tdd_type(tdd_config, tti % 10) != SRSLTE_TDD_SF_U || cell.frame_type == SRSLTE_FDD) { - srslte_mbsfn_cfg_t mbsfn_cfg; - ZERO_OBJECT(mbsfn_cfg); - - if (carrier_idx == 0 && phy->is_mbsfn_sf(&mbsfn_cfg, tti)) { - cc_workers[0]->work_dl_mbsfn(mbsfn_cfg); // Don't do chest_ok in mbsfn since it trigger measurements - } else { - if ((carrier_idx == 0) || phy->scell_cfg[carrier_idx].enabled) { - rx_signal_ok = cc_workers[carrier_idx]->work_dl_regular(); - } + if (carrier_idx == 0 && phy->is_mbsfn_sf(&mbsfn_cfg, tti)) { + cc_workers[0]->work_dl_mbsfn(mbsfn_cfg); // Don't do chest_ok in mbsfn since it trigger measurements + } else { + if ((carrier_idx == 0) || phy->scell_cfg[carrier_idx].enabled) { + rx_signal_ok = cc_workers[carrier_idx]->work_dl_regular(); } } } + } - /***** Uplink Generation + Transmission *******/ + /***** Uplink Generation + Transmission *******/ - /* If TTI+4 is an uplink subframe (TODO: Support short PRACH and SRS in UpPts special subframes) */ - if ((srslte_sfidx_tdd_type(tdd_config, TTI_TX(tti) % 10) == SRSLTE_TDD_SF_U) || cell.frame_type == SRSLTE_FDD) { - // Generate Uplink signal if no PRACH pending - if (!prach_ptr) { + /* If TTI+4 is an uplink subframe (TODO: Support short PRACH and SRS in UpPts special subframes) */ + if ((srslte_sfidx_tdd_type(tdd_config, TTI_TX(tti) % 10) == SRSLTE_TDD_SF_U) || cell.frame_type == SRSLTE_FDD) { + // Generate Uplink signal if no PRACH pending + if (!prach_ptr) { - // Common UCI data object for all carriers - srslte_uci_data_t uci_data; - reset_uci(&uci_data); + // Common UCI data object for all carriers + srslte_uci_data_t uci_data; + reset_uci(&uci_data); - uint32_t uci_cc_idx = phy->get_ul_uci_cc(TTI_TX(tti)); + uint32_t uci_cc_idx = phy->get_ul_uci_cc(TTI_TX(tti)); - // Fill periodic CQI data; In case of periodic CSI report collision, lower carrier index have preference, so - // stop as soon as either CQI data is enabled or RI is carried - for (uint32_t carrier_idx = 0; carrier_idx < phy->args->nof_carriers and not uci_data.cfg.cqi.data_enable and - uci_data.cfg.cqi.ri_len == 0; - carrier_idx++) { - if (carrier_idx == 0 or phy->scell_cfg[carrier_idx].configured) { - cc_workers[carrier_idx]->set_uci_periodic_cqi(&uci_data); - } + // Fill periodic CQI data; In case of periodic CSI report collision, lower carrier index have preference, so + // stop as soon as either CQI data is enabled or RI is carried + for (uint32_t carrier_idx = 0; + carrier_idx < phy->args->nof_carriers and not uci_data.cfg.cqi.data_enable and uci_data.cfg.cqi.ri_len == 0; + carrier_idx++) { + if (carrier_idx == 0 or phy->scell_cfg[carrier_idx].configured) { + cc_workers[carrier_idx]->set_uci_periodic_cqi(&uci_data); } + } - // Loop through all carriers - for (uint32_t carrier_idx = 0; carrier_idx < phy->args->nof_carriers; carrier_idx++) { - tx_signal_ready |= cc_workers[carrier_idx]->work_ul(uci_cc_idx == carrier_idx ? &uci_data : nullptr); + // Loop through all carriers + for (uint32_t carrier_idx = 0; carrier_idx < phy->args->nof_carriers; carrier_idx++) { + tx_signal_ready |= cc_workers[carrier_idx]->work_ul(uci_cc_idx == carrier_idx ? &uci_data : nullptr); - // Set signal pointer based on offset - tx_signal_ptr.set(carrier_idx, 0, phy->args->nof_rx_ant, cc_workers[carrier_idx]->get_tx_buffer(0)); - } + // Set signal pointer based on offset + tx_signal_ptr.set(carrier_idx, 0, phy->args->nof_rx_ant, cc_workers[carrier_idx]->get_tx_buffer(0)); } } }