aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-12-07 13:52:11 -0800
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:05:57 -0800
commitb4d8ef709c6c44b04a15bb88bd8caeb0ddf06736 (patch)
tree3ae3e74d4dc1fd73e544c3cadc6f08b616eaa7f8 /host/lib
parent06f6156f85cb11ff40e3abc0fa77eba388789a37 (diff)
downloaduhd-b4d8ef709c6c44b04a15bb88bd8caeb0ddf06736.tar.gz
uhd-b4d8ef709c6c44b04a15bb88bd8caeb0ddf06736.tar.bz2
uhd-b4d8ef709c6c44b04a15bb88bd8caeb0ddf06736.zip
mg: Lock access to setters
Magnesium APIs are not thread-safe and can take a while to execute in some cases. Adding a mutex to setters avoids invalid states of the hardware from API calls. Note that the lock applies to one block at a time. With the two-radios-per-dboard approach, two locks need to be applied and race conditions are still possible. Reviewed-By: Trung Tran <trung.tran@ettus.com>
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp12
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp4
2 files changed, 16 insertions, 0 deletions
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
index c1fc055af..ae7f68710 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
@@ -140,6 +140,7 @@ magnesium_radio_ctrl_impl::~magnesium_radio_ctrl_impl()
*****************************************************************************/
double magnesium_radio_ctrl_impl::set_rate(double rate)
{
+ std::lock_guard<std::mutex> l(_set_lock);
// TODO: implement
if (rate != get_rate()) {
UHD_LOG_WARNING(unique_id(),
@@ -167,6 +168,7 @@ void magnesium_radio_ctrl_impl::set_rx_antenna(
const size_t chan
) {
UHD_ASSERT_THROW(chan <= MAGNESIUM_NUM_CHANS);
+ std::lock_guard<std::mutex> l(_set_lock);
if (std::find(MAGNESIUM_RX_ANTENNAS.begin(),
MAGNESIUM_RX_ANTENNAS.end(),
ant) == MAGNESIUM_RX_ANTENNAS.end()) {
@@ -204,6 +206,8 @@ double magnesium_radio_ctrl_impl::set_tx_frequency(
.set(freq)
.get();
}
+
+ std::lock_guard<std::mutex> l(_set_lock);
// We need to set the switches on both channels, because they share an LO.
// This way, if we tune channel 0 it will not put channel 1 into a bad
// state.
@@ -248,6 +252,8 @@ double magnesium_radio_ctrl_impl::set_rx_frequency(
.set(freq)
.get();
}
+ // If we're on the slave, we use the master lock or we get a deadlock
+ std::lock_guard<std::mutex> l(_set_lock);
// We need to set the switches on both channels, because they share an LO.
// This way, if we tune channel 0 it will not put channel 1 into a bad
// state.
@@ -305,6 +311,7 @@ double magnesium_radio_ctrl_impl::set_rx_bandwidth(
const double bandwidth,
const size_t chan
) {
+ std::lock_guard<std::mutex> l(_set_lock);
radio_ctrl_impl::set_rx_bandwidth(bandwidth, chan);
return _ad9371->set_bandwidth(bandwidth, chan, RX_DIRECTION);
}
@@ -313,6 +320,7 @@ double magnesium_radio_ctrl_impl::set_tx_bandwidth(
const double bandwidth,
const size_t chan
) {
+ std::lock_guard<std::mutex> l(_set_lock);
//radio_ctrl_impl::set_rx_bandwidth(bandwidth, chan);
return _ad9371->set_bandwidth(bandwidth, chan, TX_DIRECTION);
}
@@ -321,6 +329,7 @@ double magnesium_radio_ctrl_impl::set_tx_gain(
const double gain,
const size_t chan
) {
+ std::lock_guard<std::mutex> l(_set_lock);
UHD_LOG_TRACE(unique_id(),
"set_tx_gain(gain=" << gain << ", chan=" << chan << ")");
const double coerced_gain = _set_all_gain(
@@ -337,6 +346,7 @@ double magnesium_radio_ctrl_impl::set_rx_gain(
const double gain,
const size_t chan
) {
+ std::lock_guard<std::mutex> l(_set_lock);
UHD_LOG_TRACE(unique_id(),
"set_rx_gain(gain=" << gain << ", chan=" << chan << ")");
const double coerced_gain = _set_all_gain(
@@ -374,6 +384,7 @@ void magnesium_radio_ctrl_impl::set_rx_lo_source(
const std::string &/*name*/,
const size_t /*chan*/
) {
+ std::lock_guard<std::mutex> l(_set_lock);
// FIXME
}
@@ -389,6 +400,7 @@ double magnesium_radio_ctrl_impl::set_rx_lo_freq(
const std::string &/*name*/,
const size_t /*chan*/
) {
+ std::lock_guard<std::mutex> l(_set_lock);
return 0.0; // FIXME
}
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
index aa70fa7ad..ce96eb200 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
@@ -28,6 +28,7 @@
#include <uhd/types/serial.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/usrp/gpio_defs.hpp>
+#include <mutex>
namespace uhd {
namespace rfnoc {
@@ -192,6 +193,9 @@ private:
/**************************************************************************
* Private attributes
*************************************************************************/
+ //! Locks access to setter APIs
+ std::mutex _set_lock;
+
//! Letter representation of the radio we're currently running
std::string _radio_slot;