aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Rossetto <aaron.rossetto@ni.com>2020-11-19 08:25:47 -0600
committermichael-west <michael.west@ettus.com>2020-12-04 12:05:02 -0800
commitf970d46c56687d2570cc671733ff7736f9ae778b (patch)
tree7cf9ba018248729550efb1f54dbdaf7fa92d6adb
parentde3b48e89f2f9711b4b97c080d5c35baba45f573 (diff)
downloaduhd-f970d46c56687d2570cc671733ff7736f9ae778b.tar.gz
uhd-f970d46c56687d2570cc671733ff7736f9ae778b.tar.bz2
uhd-f970d46c56687d2570cc671733ff7736f9ae778b.zip
multi_usrp_rfnoc: Serialize make_rfnoc_device
In certain execution environments (e.g. NI's LabVIEW), the instantiation of multi_usrp objects may execute in parallel in two different threads. As the RFNoC block instances are shared between the multi_usrp instances, there is a risk that threads racing to configure the initial state of the Tx and Rx chains may operate on inconsistent or incomplete views of the state of the RFNoC blocks that make up the chain, leaving them in an invalid state that leads to client-facing errors. This commit serializes calls to make_rfnoc_device to prevent creating multiple multi_usrp objects in parallel. It also creates a map of existing multi_usrp devices and returns the existing multi_usrp object if it exists.
-rw-r--r--host/lib/usrp/multi_usrp_rfnoc.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/host/lib/usrp/multi_usrp_rfnoc.cpp b/host/lib/usrp/multi_usrp_rfnoc.cpp
index 71aca0856..0bef5cfcb 100644
--- a/host/lib/usrp/multi_usrp_rfnoc.cpp
+++ b/host/lib/usrp/multi_usrp_rfnoc.cpp
@@ -2543,7 +2543,30 @@ multi_usrp::sptr make_rfnoc_device(
detail::rfnoc_device::sptr rfnoc_device, const uhd::device_addr_t& dev_addr)
{
auto graph = uhd::rfnoc::detail::make_rfnoc_graph(rfnoc_device, dev_addr);
- return std::make_shared<multi_usrp_rfnoc>(graph, dev_addr);
+
+ // The serialization of this function is intended to protect against
+ // multiple threads instantiating multi_usrp objects for the same
+ // device in parallel.
+ static std::mutex _map_mutex;
+ static std::map<std::weak_ptr<rfnoc_graph>,
+ std::weak_ptr<multi_usrp>,
+ std::owner_less<std::weak_ptr<rfnoc_graph>>>
+ graph_to_musrp;
+ multi_usrp::sptr musrp;
+
+ // Check if a multi_usrp was already created for this device
+ std::lock_guard<std::mutex> lock(_map_mutex);
+ if (graph_to_musrp.count(graph) and not graph_to_musrp[graph].expired()) {
+ musrp = graph_to_musrp[graph].lock();
+ if (musrp) {
+ return musrp;
+ }
+ }
+
+ // Create a new musrp
+ musrp = std::make_shared<multi_usrp_rfnoc>(graph, dev_addr);
+ graph_to_musrp[graph] = musrp;
+ return musrp;
}
}}} // namespace uhd::rfnoc::detail