diff options
author | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-11-17 12:18:49 -0600 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-11-20 07:21:52 -0600 |
commit | cdcdcf5fb2308ba1dd27fbb3c8a28f6e92e13a37 (patch) | |
tree | cf9a6ef2e64e776f887ebbab2ba7f2b25851273a /host/lib/include | |
parent | 3f5d5c47e2a31089bfba1f2bce096145578e6f38 (diff) | |
download | uhd-cdcdcf5fb2308ba1dd27fbb3c8a28f6e92e13a37.tar.gz uhd-cdcdcf5fb2308ba1dd27fbb3c8a28f6e92e13a37.tar.bz2 uhd-cdcdcf5fb2308ba1dd27fbb3c8a28f6e92e13a37.zip |
graph: Restore default resolver callback at node removal
The default resolve callback behavior for a newly-instantiated `node_t`
object resolves all dirty properties associated with the node, then
marks the properties as clean. When the node is added to a graph, its
resolver callback is updated to use the graph property propagation
algorithm in `graph_t::resolve_all_properties()`, which is considerably
more sophisticated and relies on the graph topology to do its work.
When a connection between two nodes is broken via the
`graph::disconnect()` method, nodes which no longer have incoming or
outgoing edges (connections) are removed from the graph. Prior to this
change, the removed node's resolver callback was left pointing at the
graph property propagation algorithm. In certain use cases, this could
result in unexpected client-facing behavior. Consider, for example, this
code (incomplete and for illustrative purposes only) which creates a
streamer on one transmit chain of a multi-channel device, destroys that
streamer, then creates a stream on the other transmit chain. Attempting
to set the TX rate on the first chain after destroying the streamer does
not result in the expected rate change, despite the same code working
correctly before creating the streamer:
constexpr size_t CH0 = ..., CH1 = ...;
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(...);
// Set a TX rate on both chains; this succeeds
usrp->set_tx_rate(initial_rate, CH0);
usrp->set_tx_rate(initial_rate, CH1);
assert(initial_rate == usrp->get_tx_rate(CH0));
assert(initial_rate == usrp->get_tx_rate(CH1));
// Create a TX streamer for channel 0
std::vector<size_t> chain0_chans{CH0};
stream_args_t sa;
sa.channels = chain0_chans;
sa.otw_format = ...;
sa.cpu_format = ...;
uhd::tx_streamer::sptr txs = usrp->get_tx_stream(sa);
// Destroy the first streamer (disconnecting the graph) and
// create a streamer for channel 1
txs.reset();
std::vector<size_t> chain1_chans{CH1};
sa.channels = chain1_chans;
txs = usrp->get_tx_stream(sa);
// Now try to set a new TX rate on both chains
usrp->set_tx_rate(updated_rate, CH0);
usrp->set_tx_rate(updated_rate, CH1);
assert(updated_rate == usrp->get_tx_rate(CH0)); // <--- FAILS
assert(updated_rate == usrp->get_tx_rate(CH1));
The reason this fails is because the second call to `set_tx_rate()` on
channel 0 internally sets the 'interp' (interpolation ratio) property on
the DUC node via the call to the DUC block controller's
`set_input_rate()` function. As the DUC node is no longer part of the
graph, having been removed from it when the first streamer instance was
destroyed, the graph property propagation algorithm doesn't 'see' the
node with the dirty property, and the 'interp' property resolver
callback is never invoked. As a result, the DUC's input rate property,
which depends on the interpolation ratio value, is never updated, and
thus calling the `get_tx_rate()` function to query the new rate of the
TX chain results in an unexpected value. In fact, in this particular
case, `set_tx_rate()` actually raises a warning that the TX rate
couldn't be set, and a message is printed to the console.
This commit remedies the situation by restoring the default resolve
callback behavior for a node when it is removed from the graph. This
allows the framework to be able to invoke the property resolver callback
on that node when a property is updated, the expected behavior of a
newly instantiated node.
Diffstat (limited to 'host/lib/include')
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/node_accessor.hpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/node_accessor.hpp b/host/lib/include/uhdlib/rfnoc/node_accessor.hpp index 4c63d29e2..5a9fd3a7f 100644 --- a/host/lib/include/uhdlib/rfnoc/node_accessor.hpp +++ b/host/lib/include/uhdlib/rfnoc/node_accessor.hpp @@ -69,6 +69,15 @@ public: node->set_resolve_all_callback(std::move(resolver)); } + /* Restore the resolver callback to its default implementation + * + * See node_t::clear_resolve_all_callback() for details. + */ + void clear_resolve_all_callback(node_t* node) + { + node->clear_resolve_all_callback(); + } + /*! Forward an edge property to \p dst_node * * See node_t::forward_edge_property() for details. |