From f970d46c56687d2570cc671733ff7736f9ae778b Mon Sep 17 00:00:00 2001 From: Aaron Rossetto Date: Thu, 19 Nov 2020 08:25:47 -0600 Subject: 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. --- host/lib/usrp/multi_usrp_rfnoc.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) 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(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, + std::owner_less>> + graph_to_musrp; + multi_usrp::sptr musrp; + + // Check if a multi_usrp was already created for this device + std::lock_guard 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(graph, dev_addr); + graph_to_musrp[graph] = musrp; + return musrp; } }}} // namespace uhd::rfnoc::detail -- cgit v1.2.3