aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul David <paul.david@ettus.com>2017-01-17 18:23:56 -0500
committerMartin Braun <martin.braun@ettus.com>2017-01-19 18:26:35 -0800
commitb95eccb40d4d603131f77f609f596c3032847cb0 (patch)
tree5623c50eafc7c62c98b2a0f8644ca10ea9b3e489
parent157b17049f2ffe407183900954f56b103eb710fb (diff)
downloaduhd-b95eccb40d4d603131f77f609f596c3032847cb0.tar.gz
uhd-b95eccb40d4d603131f77f609f596c3032847cb0.tar.bz2
uhd-b95eccb40d4d603131f77f609f596c3032847cb0.zip
x300: Output system messages in order for multi-threaded initialization
-rw-r--r--host/include/uhd/utils/msg.hpp13
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp46
-rw-r--r--host/lib/utils/msg.cpp9
3 files changed, 66 insertions, 2 deletions
diff --git a/host/include/uhd/utils/msg.hpp b/host/include/uhd/utils/msg.hpp
index 2cc5893e7..48ffb28a1 100644
--- a/host/include/uhd/utils/msg.hpp
+++ b/host/include/uhd/utils/msg.hpp
@@ -57,6 +57,13 @@ namespace uhd{ namespace msg{
typedef void (*handler_t)(type_t, const std::string &);
/*!
+ * Default message handler for printing uhd system messages
+ * \param type message type, such as status, warning, or error
+ * \param msg contents of the system message as a string
+ */
+ void default_msg_handler(type_t type, const std::string &msg);
+
+ /*!
* Register the handler for uhd system messages.
* Only one handler can be registered at once.
* This replaces the default std::cout/cerr handler.
@@ -64,6 +71,12 @@ namespace uhd{ namespace msg{
*/
UHD_API void register_handler(const handler_t &handler);
+ /*!
+ * Returns the current message handler for uhd system messages
+ * \returns the current message handler
+ */
+ UHD_API const handler_t& get_handler();
+
//! Internal message object (called by UHD_MSG macro)
class UHD_API _msg{
public:
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 313e070b3..8164c79b6 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -381,6 +381,32 @@ static void x300_load_fw(wb_iface::sptr fw_reg_ctrl, const std::string &file_nam
UHD_MSG(status) << " done!" << std::endl;
}
+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)
@@ -392,6 +418,7 @@ 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++)
{
@@ -400,6 +427,11 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr)
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++)
{
@@ -408,6 +440,10 @@ x300_impl::x300_impl(const uhd::device_addr_t &dev_addr)
);
}
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(
@@ -518,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"];
diff --git a/host/lib/utils/msg.cpp b/host/lib/utils/msg.cpp
index 95879a116..d9d2fb66a 100644
--- a/host/lib/utils/msg.cpp
+++ b/host/lib/utils/msg.cpp
@@ -78,7 +78,12 @@ void uhd::msg::register_handler(const handler_t &handler){
msg_rs().handler = handler;
}
-static void default_msg_handler(uhd::msg::type_t type, const std::string &msg){
+const uhd::msg::handler_t& uhd::msg::get_handler(){
+ boost::mutex::scoped_lock lock(msg_rs().mutex);
+ return msg_rs().handler;
+}
+
+void uhd::msg::default_msg_handler(uhd::msg::type_t type, const std::string &msg){
static boost::mutex msg_mutex;
boost::mutex::scoped_lock lock(msg_mutex);
switch(type){
@@ -104,7 +109,7 @@ static void default_msg_handler(uhd::msg::type_t type, const std::string &msg){
}
UHD_STATIC_BLOCK(msg_register_default_handler){
- uhd::msg::register_handler(&default_msg_handler);
+ uhd::msg::register_handler(&uhd::msg::default_msg_handler);
}
/***********************************************************************