From 369cffec00b247663b46d7ffb1cbab0f771c050e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 28 Oct 2020 16:28:07 +0100 Subject: [PATCH] More deterministic SCell search test --- srsue/hdr/phy/scell/intra_measure.h | 45 +++++++++++++++------------- srsue/src/phy/scell/intra_measure.cc | 20 ++++++++----- srsue/test/phy/CMakeLists.txt | 11 ------- srsue/test/phy/scell_search_test.cc | 10 ++----- 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/srsue/hdr/phy/scell/intra_measure.h b/srsue/hdr/phy/scell/intra_measure.h index dfc48eccf..32a4c23ce 100644 --- a/srsue/hdr/phy/scell/intra_measure.h +++ b/srsue/hdr/phy/scell/intra_measure.h @@ -40,7 +40,8 @@ class intra_measure : public srslte::thread * except quit can transition to idle. * - wait: waits for at least intra_freq_meas_period_ms since last receive start and goes to receive. * - receive: captures base-band samples for intra_freq_meas_len_ms and goes to measure. - * - measure: enables the inner thread to start the measuring function and goes to wait. + * - measure: enables the inner thread to start the measuring function. The asynchronous buffer will transition to + * wait as soon as it has read the data from the buffer. * - quit: stops the inner thread and quits. Transition from any state measure state. * * FSM abstraction: @@ -49,7 +50,7 @@ class intra_measure : public srslte::thread * | Idle | --------------------->| Wait |------------------------------>| Receive | * +------+ +------+ +---------+ * ^ ^ | stop +------+ - * | | | ----->| Quit | + * | Read buffer | | ----->| Quit | * init +---------+ intra_freq_meas_len_ms | +------+ * meas_stop | Measure |<----------------------------------+ * +---------+ @@ -125,11 +126,12 @@ public: uint32_t get_earfcn() { return current_earfcn; }; /** - * Synchronous wait mechanism, used for testing purposes, it waits for the inner thread to return a measurement. + * Synchronous wait mechanism, blocks the writer thread while it is in measure state. If the asynchonous thread is too + * slow, use this method for stalling the writing thread and wait the asynchronous thread to clear the buffer. */ void wait_meas() { // Only used by scell_search_test - meas_sync.wait(); + state.wait_change(internal_state::measure); } private: @@ -173,12 +175,14 @@ private: } /** - * Waits for a state transition change, used for blocking the inner thread + * Waits for a state transition to a state different than the provided, used for blocking the inner thread */ - void wait_change() + void wait_change(state_t s) { std::unique_lock lock(mutex); - cvar.wait(lock); + while (state == s) { + cvar.wait(lock); + } } }; @@ -198,20 +202,19 @@ private: ///< Internal Thread priority, low by default const static int INTRA_FREQ_MEAS_PRIO = DEFAULT_PRIORITY + 5; - scell_recv scell = {}; - meas_itf* new_cell_itf = nullptr; - srslte::log* log_h = nullptr; - uint32_t cc_idx = 0; - uint32_t current_earfcn = 0; - uint32_t current_sflen = 0; - srslte_cell_t serving_cell = {}; - std::set active_pci = {}; - std::mutex active_pci_mutex = {}; - uint32_t last_measure_tti = 0; - uint32_t intra_freq_meas_len_ms = 20; - uint32_t intra_freq_meas_period_ms = 200; - uint32_t rx_gain_offset_db = 0; - srslte::tti_sync_cv meas_sync; // Only used by scell_search_test + scell_recv scell = {}; + meas_itf* new_cell_itf = nullptr; + srslte::log* log_h = nullptr; + uint32_t cc_idx = 0; + uint32_t current_earfcn = 0; + uint32_t current_sflen = 0; + srslte_cell_t serving_cell = {}; + std::set active_pci = {}; + std::mutex active_pci_mutex = {}; + uint32_t last_measure_tti = 0; + uint32_t intra_freq_meas_len_ms = 20; + uint32_t intra_freq_meas_period_ms = 200; + uint32_t rx_gain_offset_db = 0; cf_t* search_buffer = nullptr; diff --git a/srsue/src/phy/scell/intra_measure.cc b/srsue/src/phy/scell/intra_measure.cc index af17a6122..28157c758 100644 --- a/srsue/src/phy/scell/intra_measure.cc +++ b/srsue/src/phy/scell/intra_measure.cc @@ -75,9 +75,14 @@ void intra_measure::init(uint32_t cc_idx_, phy_common* common, meas_itf* new_cel void intra_measure::stop() { + // Notify quit to asynchronous thread. If it is measuring, it will first finish the measure, report to stack and + // then it will finish state.set_state(internal_state::quit); - srslte_ringbuffer_stop(&ring_buffer); + + // Wait for the asynchronous thread to finish wait_thread_finish(); + + srslte_ringbuffer_stop(&ring_buffer); srslte_refsignal_dl_sync_free(&refsignal_dl_sync); } @@ -114,7 +119,7 @@ void intra_measure::set_cells_to_meas(const std::set& pci) void intra_measure::write(uint32_t tti, cf_t* data, uint32_t nsamples) { - uint32_t elapsed_tti = ((tti + 10240) - last_measure_tti) % 10240; + uint32_t elapsed_tti = TTI_SUB(tti, last_measure_tti); switch (state.get_state()) { @@ -213,9 +218,6 @@ void intra_measure::measure_proc() if (not neighbour_cells.empty()) { new_cell_itf->new_cell_meas(cc_idx, neighbour_cells); } - - // Inform that measurement has finished - meas_sync.increase(); } void intra_measure::run_thread() @@ -223,13 +225,15 @@ void intra_measure::run_thread() bool quit = false; do { - switch (state.get_state()) { + // Get state + internal_state::state_t s = state.get_state(); + switch (s) { case internal_state::idle: case internal_state::wait: case internal_state::receive: - // Wait for a state change - state.wait_change(); + // Wait for a different state + state.wait_change(s); break; case internal_state::measure: // Run the measurement process diff --git a/srsue/test/phy/CMakeLists.txt b/srsue/test/phy/CMakeLists.txt index 8e41dceb9..ce1f433ac 100644 --- a/srsue/test/phy/CMakeLists.txt +++ b/srsue/test/phy/CMakeLists.txt @@ -32,14 +32,9 @@ link_directories( add_executable(ue_phy_test ue_phy_test.cc) target_link_libraries(ue_phy_test srsue_phy - srsue_stack - srsue_upper - srsue_mac - srsue_rrc srslte_common srslte_phy srslte_radio - srslte_upper ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) # Test disabled, it is not 100 deterministic. @@ -48,15 +43,9 @@ target_link_libraries(ue_phy_test add_executable(scell_search_test scell_search_test.cc) target_link_libraries(scell_search_test srsue_phy - srsue_stack - srsue_upper - srsue_mac - srsue_rrc srslte_common srslte_phy srslte_radio - srslte_upper - rrc_asn1 ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) add_test(scell_search_test scell_search_test --duration=5 --cell.nof_prb=6 --active_cell_list=2,3,4,5,6 --simulation_cell_list=1,2,3,4,5,6 --channel_period_s=30 --channel.hst.fd=750 --channel.delay_max=10000) diff --git a/srsue/test/phy/scell_search_test.cc b/srsue/test/phy/scell_search_test.cc index e8afb37d0..d34fdea5a 100644 --- a/srsue/test/phy/scell_search_test.cc +++ b/srsue/test/phy/scell_search_test.cc @@ -641,12 +641,8 @@ int main(int argc, char** argv) enb->work(&sf_cfg_dl, nullptr, nullptr, nullptr, nullptr, baseband_buffer, ts); } } - // If it is time for a measurement, wait previous to finish - if (sf_idx > phy_args.intra_freq_meas_period_ms) { - if (sf_idx % phy_args.intra_freq_meas_period_ms == 0) { - intra_measure.wait_meas(); - } - } + // if it measuring, wait for avoiding overflowing + intra_measure.wait_meas(); } // Increase Time counter @@ -664,7 +660,7 @@ int main(int argc, char** argv) intra_measure.wait_meas(); } - // Stop + // Stop, it will block until the asynchronous thread quits intra_measure.stop(); ret = rrc.print_stats() ? SRSLTE_SUCCESS : SRSLTE_ERROR;