From 807b60988d23867e6edb879e4348f113563a624a Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 28 May 2021 17:28:34 +0200 Subject: [PATCH] Wait for PHY workers to transmit before considering SYNC in IDLE --- srsue/hdr/phy/sync_state.h | 26 ++++++++++++++++++++++++++ srsue/src/phy/sync.cc | 26 ++++++++++---------------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/srsue/hdr/phy/sync_state.h b/srsue/hdr/phy/sync_state.h index af9d7c0c3..9e7715026 100644 --- a/srsue/hdr/phy/sync_state.h +++ b/srsue/hdr/phy/sync_state.h @@ -87,6 +87,32 @@ public: /* Helpers below this */ bool is_idle() { return cur_state == IDLE; } bool is_camping() { return cur_state == CAMPING; } + bool wait_idle(uint32_t timeout_ms) + { + std::unique_lock lock(outside); + + // Avoid wasting time if the next state will not be IDLE + if (next_state != IDLE) { + return false; + } + + // Calculate timeout + std::chrono::system_clock::time_point expire_time = std::chrono::system_clock::now(); + expire_time += std::chrono::milliseconds(timeout_ms); + + // Wait until the state is IDLE + while (cur_state != IDLE) { + std::cv_status cv_status = cvar.wait_until(lock, expire_time); + + // Returns false if it timeouts + if (cv_status != std::cv_status::timeout) { + return false; + } + } + + // Return true if the state is IDLE + return true; + } const char* to_string() { diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 603e8b9cc..567e27ea4 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -220,17 +220,14 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou rrc_proc_state = PROC_SEARCH_RUNNING; // Wait for SYNC thread to transition to IDLE (max. 2000ms) - uint32_t cnt = 0; - while (!phy_state.is_idle() && cnt <= 4000) { - Info("Cell Search: PHY state is_idle=%d, cnt=%d", phy_state.is_idle(), cnt); - usleep(500); - cnt++; - } - if (!phy_state.is_idle()) { - Error("Can not change Cell while not in IDLE"); + if (not phy_state.wait_idle(2)) { + Error("SYNC: Can not search while not in IDLE"); return ret; } + // Wait for workers to finish PHY processing + worker_com->semaphore.wait_all(); + // Reset worker once SYNC is IDLE to flush any worker states such as ACKs and pending grants worker_com->reset(); @@ -798,20 +795,17 @@ void sync::set_ue_sync_opts(srsran_ue_sync_t* q, float cfo) bool sync::set_cell(float cfo) { // Wait for SYNC thread to transition to IDLE (max. 2000ms) - uint32_t cnt = 0; - while (!phy_state.is_idle() && cnt <= 4000) { - Info("SYNC: PHY state is_idle=%d, cnt=%d", phy_state.is_idle(), cnt); - usleep(500); - cnt++; - } - if (!phy_state.is_idle()) { - Error("Can not change Cell while not in IDLE"); + if (not phy_state.wait_idle(2)) { + Error("SYNC: Can not change Cell while not in IDLE"); return false; } // Reset UE sync. Attention: doing this reset when the FSM is NOT IDLE can cause PSS/SSS out-of-sync srsran_ue_sync_reset(&ue_sync); + // Wait for workers to finish PHY processing + worker_com->semaphore.wait_all(); + // Reset worker once SYNC is IDLE to flush any worker states such as ACKs and pending grants worker_com->reset();