aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/x300/x300_impl.cpp')
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp75
1 files changed, 63 insertions, 12 deletions
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index d6e2a6fdc..8164c79b6 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -381,7 +381,33 @@ static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string &file_nam
UHD_MSG(status) << " done!" << std::endl;
}
-x300_impl::x300_impl(const uhd::device_addr_t &dev_addr)
+static const std::string thread_final_msg = "Finished multi-threaded initialization\n";
+
+static void thread_msg_handler(uhd::msg::type_t type, const std::string &msg)
+{
+ static boost::mutex msg_mutex;
+ boost::mutex::scoped_lock lock(msg_mutex);
+
+ typedef std::pair<uhd::msg::type_t, std::string> msg_pair_t;
+ typedef std::map<boost::thread::id, std::vector<msg_pair_t> > thread_map_t;
+
+ static thread_map_t thread_list;
+ thread_list[boost::this_thread::get_id()].push_back(msg_pair_t(type, msg));
+
+ if (msg == thread_final_msg)
+ {
+ BOOST_FOREACH(const thread_map_t::value_type &thread_pair, thread_list)
+ {
+ BOOST_FOREACH(const msg_pair_t &msg_pair, thread_pair.second)
+ {
+ // Forward the message to the default handler
+ uhd::msg::default_msg_handler(msg_pair.first, msg_pair.second);
+ }
+ }
+ }
+}
+
+x300_impl::x300_impl(const uhd::device_addr_t &dev_addr)
: device3_impl()
, _sid_framer(0)
{
@@ -391,10 +417,33 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr)
const device_addrs_t device_args = separate_device_addr(dev_addr);
_mb.resize(device_args.size());
+
+ // Serialize the initialization process
+ if (dev_addr.has_key("serialize_init") or device_args.size() == 1) {
+ for (size_t i = 0; i < device_args.size(); i++)
+ {
+ this->setup_mb(i, device_args[i]);
+ }
+ return;
+ }
+
+ // Setup a custom messenger handler
+ uhd::msg::handler_t current_handler = uhd::msg::get_handler();
+ uhd::msg::register_handler(&thread_msg_handler);
+
+ // Thread the initialization process
+ boost::thread_group setup_threads;
for (size_t i = 0; i < device_args.size(); i++)
{
- this->setup_mb(i, device_args[i]);
+ setup_threads.create_thread(
+ boost::bind(&x300_impl::setup_mb, this, i, device_args[i])
+ );
}
+ setup_threads.join_all();
+
+ // restore the original message handler
+ UHD_MSG(status) << thread_final_msg;
+ uhd::msg::register_handler(current_handler);
}
void x300_impl::mboard_members_t::discover_eth(
@@ -505,6 +554,16 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
mboard_members_t &mb = _mb[mb_i];
mb.initialization_done = false;
+ const std::string thread_id(
+ boost::lexical_cast<std::string>(boost::this_thread::get_id())
+ );
+ const std::string thread_msg(
+ "Thread ID " + thread_id + " for motherboard "
+ + boost::lexical_cast<std::string>(mb_i)
+ );
+ UHD_MSG(status) << std::endl;
+ UHD_MSG(status) << thread_msg << std::endl;
+
std::vector<std::string> eth_addrs;
// Not choosing eth0 based on resource might cause user issues
std::string eth0_addr = dev_addr.has_key("resource") ? dev_addr["resource"] : dev_addr["addr"];
@@ -886,14 +945,6 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
}
////////////////////////////////////////////////////////////////////
- //clear router?
- ////////////////////////////////////////////////////////////////////
- for (size_t i = 0; i < 512; i++) {
- mb.zpu_ctrl->poke32(SR_ADDR(SETXB_BASE, i), 0);
- }
-
-
- ////////////////////////////////////////////////////////////////////
// setup time sources and properties
////////////////////////////////////////////////////////////////////
_tree->create<std::string>(mb_path / "time_source" / "value")
@@ -950,8 +1001,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
n_rfnoc_blocks,
X300_XB_DST_PCI + 1, /* base port */
uhd::sid_t(X300_SRC_ADDR0, 0, X300_DST_ADDR + mb_i, 0),
- dev_addr,
- mb.if_pkt_is_big_endian ? ENDIANNESS_BIG : ENDIANNESS_LITTLE
+ dev_addr
);
//////////////// RFNOC /////////////////
@@ -1070,6 +1120,7 @@ uhd::both_xports_t x300_impl::make_transport(
zero_copy_xport_params default_buff_args;
both_xports_t xports;
+ xports.endianness = mb.if_pkt_is_big_endian ? ENDIANNESS_BIG : ENDIANNESS_LITTLE;
if (mb.xport_path == "nirio") {
xports.send_sid = this->allocate_sid(mb, address, X300_SRC_ADDR0, X300_XB_DST_PCI);
xports.recv_sid = xports.send_sid.reversed();