From 25660c5c9e83e352e10d9fe9feb115d40a322353 Mon Sep 17 00:00:00 2001 From: Johannes Demel Date: Tue, 5 Nov 2013 13:56:00 -0800 Subject: b200/dtor-stall: fixed bug that stalled b200 on shutdown. --- host/lib/usrp/b200/b200_impl.cpp | 4 ++-- host/lib/usrp/b200/b200_impl.hpp | 4 ++-- host/lib/usrp/b200/b200_io_impl.cpp | 27 ++++++++++++++++++++++----- 3 files changed, 26 insertions(+), 9 deletions(-) (limited to 'host/lib/usrp/b200') diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index 0da388b93..66ab813c2 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -252,7 +252,7 @@ b200_impl::b200_impl(const device_addr_t &device_addr) //////////////////////////////////////////////////////////////////// _async_task_data.reset(new AsyncTaskData()); _async_task_data->async_md.reset(new async_md_type(1000/*messages deep*/)); - _async_task = uhd::task::make(boost::bind(&b200_impl::handle_async_task, this, _ctrl_transport, _async_task_data)); + _async_task = uhd::msg_task::make(boost::bind(&b200_impl::handle_async_task, this, _ctrl_transport, _async_task_data)); //////////////////////////////////////////////////////////////////// // Local control endpoint @@ -474,7 +474,7 @@ b200_impl::b200_impl(const device_addr_t &device_addr) b200_impl::~b200_impl(void) { - UHD_SAFE_CALL + UHD_SAFE_CALL ( _async_task.reset(); ) diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp index eced4a539..59a047e01 100644 --- a/host/lib/usrp/b200/b200_impl.hpp +++ b/host/lib/usrp/b200/b200_impl.hpp @@ -120,7 +120,7 @@ struct b200_impl : public uhd::device boost::weak_ptr _tx_streamer; //async ctrl + msgs - uhd::task::sptr _async_task; + uhd::msg_task::sptr _async_task; typedef uhd::transport::bounded_buffer async_md_type; struct AsyncTaskData { @@ -130,7 +130,7 @@ struct b200_impl : public uhd::device b200_uart::sptr gpsdo_uart; }; boost::shared_ptr _async_task_data; - void handle_async_task(uhd::transport::zero_copy_if::sptr, boost::shared_ptr); + boost::optional handle_async_task(uhd::transport::zero_copy_if::sptr, boost::shared_ptr); void register_loopback_self_test(uhd::wb_iface::sptr iface); void codec_loopback_self_test(uhd::wb_iface::sptr iface); diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp index d643ef855..069b8ff58 100644 --- a/host/lib/usrp/b200/b200_io_impl.cpp +++ b/host/lib/usrp/b200/b200_io_impl.cpp @@ -139,13 +139,24 @@ bool b200_impl::recv_async_msg( return _async_task_data->async_md->pop_with_timed_wait(async_metadata, timeout); } -void b200_impl::handle_async_task( +/* + * This method is constantly called in a msg_task loop. + * Incoming messages are dispatched in to the hosts radio_ctrl_cores. + * The radio_ctrl_core queues are accessed via a weak_ptr to them, stored in AsyncTaskData. + * During shutdown the radio_ctrl_core dtor's are called. + * An empty peek32(0) is sent out to flush pending async messages. + * The response to those messages can't be delivered to the ctrl_core queues anymore + * because the shared pointer corresponding to the weak_ptrs is no longer valid. + * Those stranded messages are put into a dump_queue implemented in msg_task. + * A radio_ctrl_core can search for missing messages there. + */ +boost::optional b200_impl::handle_async_task( uhd::transport::zero_copy_if::sptr xport, boost::shared_ptr data ) { - managed_recv_buffer::sptr buff = xport->get_recv_buff(); - if (not buff or buff->size() < 8) return; + managed_recv_buffer::sptr buff = xport->get_recv_buff(); + if (not buff or buff->size() < 8) return NULL; const boost::uint32_t sid = uhd::wtohx(buff->cast()[1]); switch (sid) { @@ -155,11 +166,16 @@ void b200_impl::handle_async_task( case B200_RESP1_MSG_SID: case B200_LOCAL_RESP_SID: { - radio_ctrl_core_3000::sptr ctrl; + radio_ctrl_core_3000::sptr ctrl; if (sid == B200_RESP0_MSG_SID) ctrl = data->radio_ctrl[0].lock(); if (sid == B200_RESP1_MSG_SID) ctrl = data->radio_ctrl[1].lock(); if (sid == B200_LOCAL_RESP_SID) ctrl = data->local_ctrl.lock(); - if (ctrl) ctrl->push_response(buff->cast()); + if (ctrl){ + ctrl->push_response(buff->cast()); + } + else{ + return std::make_pair(sid, uhd::msg_task::buff_to_vector(buff->cast(), buff->size() ) ); + } break; } @@ -204,6 +220,7 @@ void b200_impl::handle_async_task( default: UHD_MSG(error) << "Got a ctrl packet with unknown SID " << sid << std::endl; } + return NULL; } /*********************************************************************** -- cgit v1.2.3 From 8a78802c10fa64af5d1ec7cf39ce389f003cce11 Mon Sep 17 00:00:00 2001 From: Johannes Demel Date: Tue, 19 Nov 2013 13:17:52 -0800 Subject: b200/dtor-stall: final fixes for stall bug --- host/lib/usrp/b200/b200_io_impl.cpp | 9 +++++---- host/lib/usrp/cores/radio_ctrl_core_3000.cpp | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'host/lib/usrp/b200') diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp index 069b8ff58..1eddeb8bc 100644 --- a/host/lib/usrp/b200/b200_io_impl.cpp +++ b/host/lib/usrp/b200/b200_io_impl.cpp @@ -155,11 +155,12 @@ boost::optional b200_impl::handle_async_task( boost::shared_ptr data ) { - managed_recv_buffer::sptr buff = xport->get_recv_buff(); - if (not buff or buff->size() < 8) return NULL; + managed_recv_buffer::sptr buff = xport->get_recv_buff(); + if (not buff or buff->size() < 8) + return NULL; + const boost::uint32_t sid = uhd::wtohx(buff->cast()[1]); - switch (sid) - { + switch (sid) { //if the packet is a control response case B200_RESP0_MSG_SID: diff --git a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp index 13b346cc6..0d6e1c665 100644 --- a/host/lib/usrp/cores/radio_ctrl_core_3000.cpp +++ b/host/lib/usrp/cores/radio_ctrl_core_3000.cpp @@ -66,8 +66,8 @@ public: UHD_LOG << "~radio_ctrl_core_3000_impl() " << _name << std::endl; _timeout = ACK_TIMEOUT; //reset timeout to something small UHD_SAFE_CALL( - this->peek32(0);//dummy peek with the purpose of ack'ing all packets - _async_task.reset();//now its ok to release the task + this->peek32(0);//dummy peek with the purpose of ack'ing all packets + _async_task.reset();//now its ok to release the task ) } -- cgit v1.2.3