Batch of race fixes when running the UE and ENB with UHD.

Main fixes are in the UHD driver, fixing races and potential deadlocks.
master
faluco 3 years ago committed by Andre Puschmann
parent 1a64c6adad
commit 75af37bd4b

@ -10,6 +10,7 @@
*
*/
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <string>
@ -155,7 +156,7 @@ struct rf_uhd_handler_t {
#if HAVE_ASYNC_THREAD
// Asynchronous transmission message thread
bool async_thread_running = false;
std::atomic<bool> async_thread_running{false};
std::thread async_thread;
std::mutex async_mutex;
std::condition_variable async_cvar;
@ -226,9 +227,12 @@ static void log_late(rf_uhd_handler_t* h, bool is_rx)
#if HAVE_ASYNC_THREAD
static void log_underflow(rf_uhd_handler_t* h)
{
// Flag underflow
if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) {
h->tx_state = RF_UHD_IMP_TX_STATE_END_OF_BURST;
{
std::lock_guard<std::mutex> tx_lock(h->tx_mutex);
// Flag underflow
if (h->tx_state == RF_UHD_IMP_TX_STATE_BURST) {
h->tx_state = RF_UHD_IMP_TX_STATE_END_OF_BURST;
}
}
if (h->uhd_error_handler != nullptr) {
srsran_rf_error_t error;
@ -289,6 +293,7 @@ static void* async_thread(void* h)
}
} else if (event_code == uhd::async_metadata_t::EVENT_CODE_BURST_ACK) {
// Makes sure next block will be start of burst
std::lock_guard<std::mutex> tx_lock(handler->tx_mutex);
if (handler->tx_state == RF_UHD_IMP_TX_STATE_WAIT_EOB_ACK) {
handler->tx_state = RF_UHD_IMP_TX_STATE_START_BURST;
}
@ -1023,11 +1028,12 @@ double rf_uhd_set_rx_srate(void* h, double freq)
double rf_uhd_set_tx_srate(void* h, double freq)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
std::unique_lock<std::mutex> lock(handler->tx_mutex);
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
// Locking order should be kept the same with the async worker.
#if HAVE_ASYNC_THREAD
std::unique_lock<std::mutex> lock_async(handler->async_mutex);
#endif /* HAVE_ASYNC_THREAD */
std::unique_lock<std::mutex> lock(handler->tx_mutex);
// Early return if the current rate matches and Tx stream has been created
if (freq == handler->tx_rate and handler->uhd->is_tx_ready()) {
@ -1409,6 +1415,8 @@ int rf_uhd_send_timed_multi(void* h,
// Flush receiver only if allowed
if (RF_UHD_IMP_PROHIBITED_EOB_FLUSH.count(handler->devname) == 0) {
// Avoid holding the tx lock while in the rf_uhd_flush_buffer function to avoid potential deadlocks.
lock.unlock();
rf_uhd_flush_buffer(h);
}

@ -152,14 +152,14 @@ void enb::stop()
{
if (started) {
// tear down in reverse order
if (radio) {
radio->stop();
}
if (phy) {
phy->stop();
}
if (radio) {
radio->stop();
}
if (eutra_stack) {
eutra_stack->stop();
}

Loading…
Cancel
Save