aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/rfnoc_graph.hpp16
-rw-r--r--host/lib/include/uhdlib/rfnoc/graph.hpp15
-rw-r--r--host/lib/rfnoc/graph.cpp23
-rw-r--r--host/lib/rfnoc/rfnoc_graph.cpp10
-rw-r--r--host/tests/actions_test.cpp2
-rw-r--r--host/tests/rfnoc_detailgraph_test.cpp4
-rw-r--r--host/tests/rfnoc_propprop_test.cpp15
7 files changed, 74 insertions, 11 deletions
diff --git a/host/include/uhd/rfnoc_graph.hpp b/host/include/uhd/rfnoc_graph.hpp
index 630f79751..a0a9bf907 100644
--- a/host/include/uhd/rfnoc_graph.hpp
+++ b/host/include/uhd/rfnoc_graph.hpp
@@ -203,6 +203,22 @@ public:
*/
std::vector<graph_edge_t> enumerate_connections();
+ /*! Commit graph and run initial checks
+ *
+ * This method needs to be called when the graph is ready for action.
+ * It will run checks on the graph and run a property propagation.
+ *
+ * \throws uhd::resolve_error if the properties fail to resolve.
+ */
+ virtual void commit() = 0;
+
+ /*! Release graph: Opposite of commit()
+ *
+ * Calling this will disable property propagation until commit() has been
+ * called an equal number of times.
+ */
+ virtual void release() = 0;
+
/******************************************
* Streaming
******************************************/
diff --git a/host/lib/include/uhdlib/rfnoc/graph.hpp b/host/lib/include/uhdlib/rfnoc/graph.hpp
index fdb4525d1..49dc62551 100644
--- a/host/lib/include/uhdlib/rfnoc/graph.hpp
+++ b/host/lib/include/uhdlib/rfnoc/graph.hpp
@@ -14,6 +14,7 @@
#include <tuple>
#include <memory>
#include <deque>
+#include <atomic>
namespace uhd { namespace rfnoc { namespace detail {
@@ -44,7 +45,7 @@ public:
//const size_t dst_port);
//
- /*! Run initial checks for graph
+ /*! Commit graph and run initial checks
*
* This method can be called anytime, but it's intended to be called when
* the graph has been committed. It will run checks on the graph and run a
@@ -52,8 +53,14 @@ public:
*
* \throws uhd::resolve_error if the properties fail to resolve.
*/
- void initialize();
+ void commit();
+ /*! Opposite of commit()
+ *
+ * Calling this will disable property propagation until commit() has been
+ * called an equal number of times.
+ */
+ void release();
private:
friend class graph_accessor_t;
@@ -254,6 +261,10 @@ private:
//! Mutex for to avoid the user from sending one message before another
// message is sent
std::recursive_mutex _action_mutex;
+
+ //! This counter gets decremented everytime commit() is called. When zero,
+ // the graph is committed.
+ std::atomic<size_t> _release_count{1};
};
diff --git a/host/lib/rfnoc/graph.cpp b/host/lib/rfnoc/graph.cpp
index d311a00bd..f687e8984 100644
--- a/host/lib/rfnoc/graph.cpp
+++ b/host/lib/rfnoc/graph.cpp
@@ -173,12 +173,21 @@ void graph_t::connect(node_ref_t src_node, node_ref_t dst_node, graph_edge_t edg
}
}
-void graph_t::initialize()
+void graph_t::commit()
{
- UHD_LOG_DEBUG(LOG_ID, "Initializing graph.");
+ if (_release_count) {
+ _release_count--;
+ }
+ UHD_LOG_TRACE(LOG_ID, "graph::commit() => " << _release_count.load());
resolve_all_properties();
}
+void graph_t::release()
+{
+ UHD_LOG_TRACE(LOG_ID, "graph::release() => " << _release_count.load());
+ _release_count++;
+}
+
/******************************************************************************
* Private methods to be called by friends
@@ -188,6 +197,9 @@ void graph_t::resolve_all_properties()
if (boost::num_vertices(_graph) == 0) {
return;
}
+ if (_release_count) {
+ return;
+ }
node_accessor_t node_accessor{};
// First, find the node on which we'll start.
@@ -323,6 +335,13 @@ void graph_t::resolve_all_properties()
void graph_t::enqueue_action(
node_ref_t src_node, res_source_info src_edge, action_info::sptr action)
{
+ if (_release_count) {
+ UHD_LOG_WARNING(LOG_ID,
+ "Action propagation is not enabled, graph is not committed! Will not "
+ "propagate action `"
+ << action->key << "'");
+ return;
+ }
// First, make sure that once we start action handling, no other node from
// a different thread can throw in their own actions
std::lock_guard<std::recursive_mutex> l(_action_mutex);
diff --git a/host/lib/rfnoc/rfnoc_graph.cpp b/host/lib/rfnoc/rfnoc_graph.cpp
index 22c9b7294..94d59da05 100644
--- a/host/lib/rfnoc/rfnoc_graph.cpp
+++ b/host/lib/rfnoc/rfnoc_graph.cpp
@@ -101,6 +101,16 @@ public:
return _mb_controllers.at(mb_index);
}
+ void commit()
+ {
+ _graph->commit();
+ }
+
+ void release()
+ {
+ _graph->release();
+ }
+
private:
/**************************************************************************
* Device Setup
diff --git a/host/tests/actions_test.cpp b/host/tests/actions_test.cpp
index b5feb2521..9218ad231 100644
--- a/host/tests/actions_test.cpp
+++ b/host/tests/actions_test.cpp
@@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(test_actions_simple_graph)
graph.connect(&mock_rx_radio, &mock_ddc, {0, 0, graph_edge_t::DYNAMIC, true});
graph.connect(&mock_ddc, &mock_fifo, {0, 0, graph_edge_t::DYNAMIC, true});
graph.connect(&mock_fifo, &mock_streamer, {0, 0, graph_edge_t::DYNAMIC, true});
- graph.initialize();
+ graph.commit();
// Force the DDC to actually set a decimation rate != 1
mock_streamer.set_property<double>("samp_rate", 10e6, 0);
diff --git a/host/tests/rfnoc_detailgraph_test.cpp b/host/tests/rfnoc_detailgraph_test.cpp
index 6273430e6..efae9ff4f 100644
--- a/host/tests/rfnoc_detailgraph_test.cpp
+++ b/host/tests/rfnoc_detailgraph_test.cpp
@@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(test_graph)
topo_sorted_nodes.at(0)->get_unique_id(), mock_rx_radio.get_unique_id());
// Now initialize the graph (will force a call to resolve_all_properties())
- graph.initialize();
+ graph.commit();
// This will be ignored
graph.connect(&mock_rx_radio, &mock_tx_radio, edge_info);
@@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(test_graph_unresolvable)
// Now create the graph and commit:
graph.connect(&mock_rx_radio, &mock_tx_radio, edge_info);
- graph.initialize();
+ graph.commit();
// Now set a property that will cause the graph to fail to resolve:
BOOST_REQUIRE_THROW(mock_tx_radio.set_property<double>("master_clock_rate", 100e6, 0),
diff --git a/host/tests/rfnoc_propprop_test.cpp b/host/tests/rfnoc_propprop_test.cpp
index 20d7d96f5..8942a59f0 100644
--- a/host/tests/rfnoc_propprop_test.cpp
+++ b/host/tests/rfnoc_propprop_test.cpp
@@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(test_graph_resolve_ddc_radio)
// Now create the graph and commit:
graph.connect(&mock_rx_radio, &mock_ddc, edge_info);
graph.connect(&mock_ddc, &mock_tx_radio, edge_info);
- graph.initialize();
+ graph.commit();
BOOST_CHECK_EQUAL(mock_ddc._decim.get(), 1);
mock_tx_radio.set_property<double>("master_clock_rate", 100e6, 0);
@@ -256,6 +256,13 @@ BOOST_AUTO_TEST_CASE(test_graph_resolve_ddc_radio)
mock_ddc.set_property<int>("decim", 42, 0);
// It will bounce back:
BOOST_CHECK_EQUAL(mock_ddc._decim.get(), 2);
+
+ graph.release();
+ mock_tx_radio.set_property<double>("master_clock_rate", 200e6, 0);
+ // Won't change yet:
+ BOOST_CHECK_EQUAL(mock_ddc._decim.get(), 2);
+ graph.commit();
+ BOOST_CHECK_EQUAL(mock_ddc._decim.get(), 1);
}
@@ -284,7 +291,7 @@ BOOST_AUTO_TEST_CASE(test_graph_catch_invalid_graph)
// Now create the graph and commit:
graph.connect(&mock_rx_radio, &mock_tx_radio, edge_info);
- BOOST_REQUIRE_THROW(graph.initialize(), uhd::resolve_error);
+ BOOST_REQUIRE_THROW(graph.commit(), uhd::resolve_error);
UHD_LOG_INFO("TEST", "^^^ Expected an error message.");
}
@@ -314,7 +321,7 @@ BOOST_AUTO_TEST_CASE(test_graph_ro_prop)
// Now create the graph and commit:
graph.connect(&mock_rx_radio, &mock_tx_radio, edge_info);
- graph.initialize();
+ graph.commit();
const size_t rx_rssi_resolver_count = mock_rx_radio.rssi_resolver_count;
UHD_LOG_DEBUG("TEST", "RX RSSI: " << mock_rx_radio.get_property<double>("rssi"));
@@ -408,7 +415,7 @@ BOOST_AUTO_TEST_CASE(test_graph_crisscross_fifo)
graph.connect(&mock_fifo, &mock_tx_radio0, {1, 0, graph_edge_t::DYNAMIC, true});
graph.connect(&mock_fifo, &mock_tx_radio1, {0, 0, graph_edge_t::DYNAMIC, true});
UHD_LOG_INFO("TEST", "Now testing criss-cross prop resolution");
- graph.initialize();
+ graph.commit();
}
BOOST_AUTO_TEST_CASE(test_circular_deps)