USRP Hardware Driver and USRP Manual Version: 3.15.0.0-MacPorts-Release
UHD and USRP Manual
 
Loading...
Searching...
No Matches
node_ctrl_base.ipp
Go to the documentation of this file.
1//
2// Copyright 2014 Ettus Research LLC
3// Copyright 2018 Ettus Research, a National Instruments Company
4//
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
7
8// Implements templated functions from node_ctrl_base.hpp
9
10#ifndef INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP
11#define INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP
12
13#include <uhd/exception.hpp>
14
15#include <boost/shared_ptr.hpp>
16#include <vector>
17
18namespace uhd {
19 namespace rfnoc {
20
21 template <typename T, bool downstream>
22 std::vector< boost::shared_ptr<T> > node_ctrl_base::_find_child_node(bool active_only)
23 {
24 typedef boost::shared_ptr<T> T_sptr;
25 static const size_t MAX_ITER = 20;
26 size_t iters = 0;
27 // List of return values:
28 std::set< T_sptr > results_s;
29 // To avoid cycles:
30 std::set < sptr > explored;
31 // Initialize our search queue with ourself:
32 std::set < node_map_pair_t > search_q;
33 // FIXME: Port is initialized to ANY_PORT, but it should really be
34 // passed in by the caller.
35 search_q.insert(node_map_pair_t(ANY_PORT, shared_from_this()));
36 std::set < node_map_pair_t > next_q;
37
38 while (iters++ < MAX_ITER) {
39 next_q.clear();
40 BOOST_FOREACH(const node_map_pair_t node_pair, search_q) {
41 sptr node = node_pair.second.lock();
42 if (not node)
43 {
44 continue;
45 }
46 size_t our_port = node_pair.first;
47 // Add this node to the list of explored nodes
48 explored.insert(node);
49 // Create set of all child nodes of this_node that are not in explored:
50 std::set< node_map_pair_t > next_nodes;
51 {
52 node_map_t all_next_nodes = downstream ?
53 node->list_downstream_nodes() :
54 node->list_upstream_nodes();
55 for (
56 node_map_t::iterator it = all_next_nodes.begin();
57 it != all_next_nodes.end();
58 ++it
59 ) {
60 size_t connected_port = it->first;
61 // If port is given, limit traversal to only that port.
62 if (our_port != ANY_PORT and our_port != connected_port)
63 {
64 continue;
65 }
66 if (active_only
67 and not (downstream ?
68 _tx_streamer_active[connected_port] :
69 _rx_streamer_active[connected_port] )) {
70 continue;
71 }
72 sptr one_next_node = it->second.lock();
73 if (not one_next_node or explored.count(one_next_node)) {
74 continue;
75 }
76 T_sptr next_node_sptr = boost::dynamic_pointer_cast<T>(one_next_node);
77 if (next_node_sptr) {
78 results_s.insert(next_node_sptr);
79 } else {
80 size_t next_port = ANY_PORT;
81 // FIXME: Need proper mapping from input port
82 // to output port.
83 // The code below assumes that blocks with the same
84 // number of connected upstream and downstream nodes
85 // map each input port directly to the same output
86 // port. This limits the graph traversal to prevent
87 // finding nodes that are not part of this chain.
88 if (one_next_node->_num_input_ports
89 and (one_next_node->_num_input_ports ==
90 one_next_node->_num_output_ports))
91 {
92 next_port = (downstream ?
93 node->get_downstream_port(connected_port) :
94 node->get_upstream_port(connected_port));
95 }
96 next_nodes.insert(node_map_pair_t(next_port, it->second));
97 }
98 }
99 }
100 // Add all of these nodes to the next search queue
101 next_q.insert(next_nodes.begin(), next_nodes.end());
102 }
103 // If next_q is empty, we've exhausted our graph
104 if (next_q.empty()) {
105 break;
106 }
107 // Re-init the search queue
108 search_q = next_q;
109 }
110
111 std::vector< T_sptr > results(results_s.begin(), results_s.end());
112 return results;
113 }
114
115 template <typename T, typename value_type, bool downstream>
116 value_type node_ctrl_base::_find_unique_property(
117 boost::function<value_type(boost::shared_ptr<T>, size_t)> get_property,
118 value_type NULL_VALUE,
119 const std::set< boost::shared_ptr<T> > &exclude_nodes
120 ) {
121 std::vector< boost::shared_ptr<T> > descendant_rate_nodes = _find_child_node<T, downstream>();
122 value_type ret_val = NULL_VALUE;
123 std::string first_node_id;
124 BOOST_FOREACH(const boost::shared_ptr<T> &node, descendant_rate_nodes) {
125 if (exclude_nodes.count(node)) {
126 continue;
127 }
128 // FIXME we need to know the port!!!
129 size_t port = ANY_PORT; // NOOO! this is wrong!!!! FIXME
130 value_type this_property = get_property(node, port);
131 if (this_property == NULL_VALUE) {
132 continue;
133 }
134 // We use the first property we find as reference
135 if (ret_val == NULL_VALUE) {
136 ret_val = this_property;
137 first_node_id = node->unique_id();
138 continue;
139 }
140 // In all subsequent finds, we make sure the property is equal to the reference
141 if (this_property != ret_val) {
142 throw uhd::runtime_error(
143 str(
144 boost::format("Node %1% specifies %2%, node %3% specifies %4%")
145 % first_node_id % ret_val % node->unique_id() % this_property
146 )
147 );
148 }
149 }
150 return ret_val;
151 }
152
153}} /* namespace uhd::rfnoc */
154
155#endif /* INCLUDED_LIBUHD_NODE_CTRL_BASE_IPP */
156// vim: sw=4 et:
std::map< size_t, wptr > node_map_t
Definition node_ctrl_base.hpp:46
std::map< size_t, bool > _tx_streamer_active
Definition node_ctrl_base.hpp:226
std::pair< size_t, wptr > node_map_pair_t
Definition node_ctrl_base.hpp:47
boost::shared_ptr< node_ctrl_base > sptr
Definition node_ctrl_base.hpp:44
std::map< size_t, bool > _rx_streamer_active
Definition node_ctrl_base.hpp:217
Definition build_info.hpp:13
Definition exception.hpp:134