Fix race conditions in intra measure class.

This commit is contained in:
faluco 2021-10-01 11:13:44 +02:00 committed by Andre Puschmann
parent 782aefa553
commit 72088dadb5
2 changed files with 33 additions and 14 deletions

View File

@ -125,13 +125,13 @@ public:
protected:
struct measure_context_t {
uint32_t cc_idx = 0; ///< Component carrier index
std::set<uint32_t> 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<uint32_t> 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<std::mutex> lock(mutex);
context.sf_len = new_sf_len;
}
private:
/**
@ -228,6 +232,8 @@ private:
*/
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
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<std::mutex> 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;

View File

@ -99,17 +99,20 @@ void intra_measure_base::meas_stop()
void intra_measure_base::set_cells_to_meas(const std::set<uint32_t>& 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");
}
}