Fix race conditions in intra measure class.

master
faluco 3 years ago committed by Andre Puschmann
parent 782aefa553
commit 72088dadb5

@ -125,13 +125,13 @@ public:
protected: protected:
struct measure_context_t { struct measure_context_t {
uint32_t cc_idx = 0; ///< Component carrier index uint32_t cc_idx = 0; ///< Component carrier index
std::set<uint32_t> active_pci = {}; ///< Set with the active PCIs std::set<uint32_t> active_pci = {}; ///< Set with the active PCIs
uint32_t sf_len = 0; ///< Subframe length in samples uint32_t sf_len = 0; ///< Subframe length in samples
uint32_t meas_len_ms = 20; ///< Measure length in milliseconds/sub-frames uint32_t meas_len_ms = 20; ///< Measure length in milliseconds/sub-frames
uint32_t meas_period_ms = 200; ///< Minimum time between measurements uint32_t meas_period_ms = 200; ///< Minimum time between measurements
uint32_t trigger_tti_period = 0; ///< Measurement TTI trigger period uint32_t trigger_tti_period = 0; ///< Measurement TTI trigger period
uint32_t trigger_tti_offset = 0; ///< Measurement TTI trigger offset uint32_t trigger_tti_offset = 0; ///< Measurement TTI trigger offset
meas_itf& new_cell_itf; meas_itf& new_cell_itf;
explicit measure_context_t(meas_itf& new_cell_itf_) : new_cell_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 * @brief Subframe length setter, the inherited class shall set the subframe length
* @param new_sf_len New 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<std::mutex> lock(mutex);
context.sf_len = new_sf_len;
}
private: private:
/** /**
@ -228,6 +232,8 @@ private:
*/ */
bool receive_tti_trigger(uint32_t tti) bool receive_tti_trigger(uint32_t tti)
{ {
std::lock_guard<std::mutex> lock(mutex);
// If the elapsed time does not satisfy with the minimum time, do not trigger // If the elapsed time does not satisfy with the minimum time, do not trigger
uint32_t elapsed_tti = TTI_SUB(tti, last_measure_tti); 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) { 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 ///< Internal Thread priority, low by default
const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; 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<std::mutex> lock(mutex);
return context;
}
internal_state state; internal_state state;
srslog::basic_logger& logger; srslog::basic_logger& logger;
mutable std::mutex active_pci_mutex = {}; mutable std::mutex mutex;
uint32_t last_measure_tti = 0; uint32_t last_measure_tti = 0;
measure_context_t context; measure_context_t context;

@ -99,17 +99,20 @@ void intra_measure_base::meas_stop()
void intra_measure_base::set_cells_to_meas(const std::set<uint32_t>& pci) void intra_measure_base::set_cells_to_meas(const std::set<uint32_t>& pci)
{ {
active_pci_mutex.lock(); mutex.lock();
context.active_pci = pci; context.active_pci = pci;
active_pci_mutex.unlock(); mutex.unlock();
state.set_state(internal_state::wait_first); state.set_state(internal_state::wait_first);
Log(info, "Received list of %zd neighbour cells to measure", pci.size()); Log(info, "Received list of %zd neighbour cells to measure", pci.size());
} }
void intra_measure_base::write(cf_t* data, uint32_t nsamples) 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)); 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 // 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); 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() 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 // Read data from buffer and find cells in it
int ret = srsran_ringbuffer_read_timed( 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 // As this function is called once the ring-buffer has enough data to process, it is not expected to fail
if (ret < SRSRAN_SUCCESS) { if (ret < SRSRAN_SUCCESS) {
@ -179,7 +185,7 @@ void intra_measure_base::measure_proc()
} }
// Perform measurements for the actual RAT // 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"); Log(error, "Error measuring RAT");
} }
} }

Loading…
Cancel
Save