diff --git a/srsue/hdr/phy/scell/intra_measure_base.h b/srsue/hdr/phy/scell/intra_measure_base.h index b5b46fc9f..7879804f1 100644 --- a/srsue/hdr/phy/scell/intra_measure_base.h +++ b/srsue/hdr/phy/scell/intra_measure_base.h @@ -125,13 +125,13 @@ public: protected: struct measure_context_t { - uint32_t cc_idx = 0; ///< Component carrier index - std::set active_pci = {}; ///< Set with the active PCIs - uint32_t sf_len = 0; ///< Subframe length in samples - uint32_t meas_len_ms = 20; ///< Measure length in milliseconds/sub-frames - uint32_t meas_period_ms = 200; ///< Minimum time between measurements - uint32_t trigger_tti_period = 0; ///< Measurement TTI trigger period - uint32_t trigger_tti_offset = 0; ///< Measurement TTI trigger offset + uint32_t cc_idx = 0; ///< Component carrier index + std::set active_pci = {}; ///< Set with the active PCIs + uint32_t sf_len = 0; ///< Subframe length in samples + uint32_t meas_len_ms = 20; ///< Measure length in milliseconds/sub-frames + uint32_t meas_period_ms = 200; ///< Minimum time between measurements + uint32_t trigger_tti_period = 0; ///< Measurement TTI trigger period + uint32_t trigger_tti_offset = 0; ///< Measurement TTI trigger offset meas_itf& new_cell_itf; explicit measure_context_t(meas_itf& new_cell_itf_) : new_cell_itf(new_cell_itf_) {} @@ -160,7 +160,11 @@ protected: * @brief Subframe length setter, the inherited class shall set the subframe length * @param new_sf_len New subframe length */ - void set_current_sf_len(uint32_t new_sf_len) { context.sf_len = new_sf_len; } + void set_current_sf_len(uint32_t new_sf_len) + { + std::lock_guard lock(mutex); + context.sf_len = new_sf_len; + } private: /** @@ -228,6 +232,8 @@ private: */ bool receive_tti_trigger(uint32_t tti) { + std::lock_guard lock(mutex); + // If the elapsed time does not satisfy with the minimum time, do not trigger uint32_t elapsed_tti = TTI_SUB(tti, last_measure_tti); if (elapsed_tti < context.meas_period_ms and state.get_state() != internal_state::wait_first) { @@ -281,9 +287,16 @@ private: ///< Internal Thread priority, low by default const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; + /// Returns a copy of the current used context. + measure_context_t get_context() const + { + std::lock_guard lock(mutex); + return context; + } + internal_state state; srslog::basic_logger& logger; - mutable std::mutex active_pci_mutex = {}; + mutable std::mutex mutex; uint32_t last_measure_tti = 0; measure_context_t context; diff --git a/srsue/src/phy/scell/intra_measure_base.cc b/srsue/src/phy/scell/intra_measure_base.cc index 11da6584d..eb4e1fb51 100644 --- a/srsue/src/phy/scell/intra_measure_base.cc +++ b/srsue/src/phy/scell/intra_measure_base.cc @@ -99,17 +99,20 @@ void intra_measure_base::meas_stop() void intra_measure_base::set_cells_to_meas(const std::set& pci) { - active_pci_mutex.lock(); + mutex.lock(); context.active_pci = pci; - active_pci_mutex.unlock(); + mutex.unlock(); state.set_state(internal_state::wait_first); Log(info, "Received list of %zd neighbour cells to measure", pci.size()); } void intra_measure_base::write(cf_t* data, uint32_t nsamples) { - int nbytes = (int)(nsamples * sizeof(cf_t)); + int nbytes = (int)(nsamples * sizeof(cf_t)); + + mutex.lock(); int required_nbytes = (int)(context.meas_len_ms * context.sf_len * sizeof(cf_t)); + mutex.unlock(); // As nbytes might not match the sub-frame size, make sure that buffer does not overflow nbytes = SRSRAN_MIN(srsran_ringbuffer_space(&ring_buffer), nbytes); @@ -162,9 +165,12 @@ void intra_measure_base::run_tti(uint32_t tti, cf_t* data, uint32_t nsamples) void intra_measure_base::measure_proc() { + // Grab a copy of the context and pass it to the measure_rat method. + measure_context_t context_copy = get_context(); + // Read data from buffer and find cells in it int ret = srsran_ringbuffer_read_timed( - &ring_buffer, search_buffer.data(), (int)(context.meas_len_ms * context.sf_len * sizeof(cf_t)), 1000); + &ring_buffer, search_buffer.data(), (int)(context_copy.meas_len_ms * context_copy.sf_len * sizeof(cf_t)), 1000); // As this function is called once the ring-buffer has enough data to process, it is not expected to fail if (ret < SRSRAN_SUCCESS) { @@ -179,7 +185,7 @@ void intra_measure_base::measure_proc() } // Perform measurements for the actual RAT - if (not measure_rat(context, search_buffer, rx_gain_offset_db)) { + if (not measure_rat(std::move(context_copy), search_buffer, rx_gain_offset_db)) { Log(error, "Error measuring RAT"); } }