From ab6fc7345a0743543e62cd1b3d9681a78d72f8f1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 8 Mar 2011 12:41:23 -0800 Subject: uhd: thread safety notes and moved some docs to general --- host/docs/coding.rst | 29 ----------------------------- host/docs/general.rst | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 29 deletions(-) (limited to 'host') diff --git a/host/docs/coding.rst b/host/docs/coding.rst index ecca4e8b8..d5304c1c5 100644 --- a/host/docs/coding.rst +++ b/host/docs/coding.rst @@ -28,32 +28,3 @@ High-Level: The multi usrp The Multi-USRP class provides a FAT interface to a single USRP with one or more channels, or multiple USRPs in a homogeneous setup. See the documentation in *usrp/multi_usrp.hpp* for reference. - ------------------------------------------------------------------------- -Integrating custom hardware ------------------------------------------------------------------------- -Creators of custom hardware can create drivers that use the UHD API. -These drivers can be built as dynamically loadable modules that the UHD will load at runtime. - -For a module to be loaded at runtime, it must be: - -* found in the UHD_MODULE_PATH environment variable, -* installed into the /share/uhd/modules directory, -* or installed into /usr/share/uhd/modules directory (unix only). - -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Custom motherboard -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Create a new device driver when the driver in lib/usrp/ -cannot support your custom FPGA or hardware modifications. -Make a copy of the relevant driver code in lib/usrp/, make mods, and rename the class. -The new device code should register itself into the discovery and factory system. - -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Custom daughterboard -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Use code from an existing daughterboard in lib/usrp/dboard/* as an example. -Your daughterboard code should subclass an rx dboard, rx dboard, or xcvr dboard; -and it should respond to calls to get and set properties. -The new daughterboard code should register itself into the dboard manager -with a unique rx and/or tx 16 bit identification number. diff --git a/host/docs/general.rst b/host/docs/general.rst index 50ef24d6c..2894fbf88 100644 --- a/host/docs/general.rst +++ b/host/docs/general.rst @@ -8,6 +8,25 @@ UHD - General Application Notes Misc notes ------------------------------------------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Thread safety notes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +For the most part, UHD is thread-safe. +Please observe the following limitations: + +**Fast-path thread requirements:** +It is safe to call send() and recv() simultaneously. However, +it is not safe to call recv() simultaneously from different thread contexts. +The same rule applies for recv(), send(), and recv_async_msg(). +One thread context per fast-path device method at a time. + +**Slow-path thread requirements:** +It is safe to change multiple settings simultaneously. However, +this could leave the settings for a device in an uncertain state. +The is because changing one setting could have an impact on how a call affects other settings. +Example: setting the channel mapping affects how the antennas are set. +It is recommended to use at most one thread context for manipulating device settings. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Thread priority scheduling ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,3 +45,12 @@ Add the following line to */etc/security/limits.conf*: Replace with a group to which your user belongs. Settings will not take effect until the user has logged in and out. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Support for dynamically loadable modules +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +For a module to be loaded at runtime, it must be: + +* found in the UHD_MODULE_PATH environment variable, +* installed into the /share/uhd/modules directory, +* or installed into /usr/share/uhd/modules directory (unix only). -- cgit v1.2.3 From 668bdcad932eeee2b10a27d16ce5db377ba9942d Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Tue, 8 Mar 2011 17:40:37 -0800 Subject: TVRX: no longer muxing in noise on Q channel --- host/lib/usrp/dboard/db_tvrx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'host') diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index 578999432..af025952e 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -453,7 +453,7 @@ void tvrx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_CONNECTION: - val = SUBDEV_CONN_COMPLEX_IQ; + val = SUBDEV_CONN_REAL_I; return; case SUBDEV_PROP_ENABLED: -- cgit v1.2.3 From 5f4e14e87e03d6b69d67e73240b5aa713e337df0 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 9 Mar 2011 18:37:19 -0800 Subject: usrp2: save alignment indexes between state to fix the lost packet problem --- host/lib/usrp/usrp2/io_impl.cpp | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'host') diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 7258585d1..a22482271 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -110,6 +110,23 @@ private: boost::function _ready_fcn; }; +/*********************************************************************** + * Alignment indexes class: keeps track of indexes + **********************************************************************/ +class alignment_indexes{ +public: + alignment_indexes(void){_indexes = 0;} + void reset(size_t len){_indexes = (1 << len) - 1;} + size_t front(void){ //TODO replace with look-up table + size_t index = 0; + while ((_indexes & (1 << index)) == 0) index++; + return index; + } + void remove(size_t index){_indexes &= ~(1 << index);} + bool empty(void){return _indexes == 0;} +private: size_t _indexes; +}; + /*********************************************************************** * io impl details (internal to this file) * - pirate crew @@ -164,6 +181,7 @@ struct usrp2_impl::io_impl{ return true; } + alignment_indexes indexes_to_do; //used in alignment logic bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs); const std::vector &xports; @@ -366,19 +384,6 @@ static UHD_INLINE bool handle_msg_packet( return true; } -class alignment_indexes{ -public: - void reset(size_t len){_indexes = (1 << len) - 1;} - size_t front(void){ //TODO replace with look-up table - size_t index = 0; - while ((_indexes & (1 << index)) == 0) index++; - return index; - } - void remove(size_t index){_indexes &= ~(1 << index);} - bool empty(void){return _indexes == 0;} -private: size_t _indexes; -}; - UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( vrt_packet_handler::managed_recv_buffs_t &buffs ){ @@ -393,13 +398,18 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs( //-------------------- begin alignment logic ---------------------// boost::system_time exit_time = boost::get_system_time() + to_time_dur(recv_timeout); managed_recv_buffer::sptr buff_tmp; - alignment_indexes indexes_to_do; bool clear, msg; time_spec_t expected_time; + //If we did not enter this routine with an empty indexes set, + //jump to after the clear so we can preserve the previous state. + //This saves buffers from being lost when using non-blocking recv. + if (not indexes_to_do.empty()) goto skip_reset; + //respond to a clear by starting from scratch got_clear: indexes_to_do.reset(buffs.size()); + skip_reset: clear = false; //do an initial pop to load an initial sequence id -- cgit v1.2.3 From 7d140b0237b3fa4e07b364e912887f68c02839cb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 10 Mar 2011 12:49:05 -0800 Subject: usrp2: created safe call macro and handle usrp2 ~mboard throwing --- host/include/uhd/utils/CMakeLists.txt | 1 + host/include/uhd/utils/safe_call.hpp | 45 +++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/mboard_impl.cpp | 13 ++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 host/include/uhd/utils/safe_call.hpp (limited to 'host') diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index b39b6083c..0dee310a8 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -26,6 +26,7 @@ INSTALL(FILES images.hpp pimpl.hpp props.hpp + safe_call.hpp safe_main.hpp static.hpp thread_priority.hpp diff --git a/host/include/uhd/utils/safe_call.hpp b/host/include/uhd/utils/safe_call.hpp new file mode 100644 index 000000000..6b2c210af --- /dev/null +++ b/host/include/uhd/utils/safe_call.hpp @@ -0,0 +1,45 @@ +// +// Copyright 2011 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_UHD_UTILS_SAFE_CALL_HPP +#define INCLUDED_UHD_UTILS_SAFE_CALL_HPP + +#include +#include +#include + +//! helper macro for safe call to produce warnings +#define _UHD_SAFE_CALL_WARNING(code, what) uhd::warning::post( \ + UHD_THROW_SITE_INFO("Exception caught in safe-call.") + #code + " -> " + what \ +); + +/*! + * A safe-call catches all exceptions thrown by code, + * and creates a verbose warning about the exception. + * Usage: UHD_SAFE_CALL(some_code_to_call();) + * \param code the block of code to call safely + */ +#define UHD_SAFE_CALL(code) \ + try{code} \ + catch(const std::exception &e){ \ + _UHD_SAFE_CALL_WARNING(code, e.what()); \ + } \ + catch(...){ \ + _UHD_SAFE_CALL_WARNING(code, "unknown exception"); \ + } + +#endif /* INCLUDED_UHD_UTILS_SAFE_CALL_HPP */ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index f20d3ab46..92a7b2f93 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -18,6 +18,7 @@ #include "usrp2_impl.hpp" #include "usrp2_regs.hpp" #include "fw_common.h" +#include #include #include #include @@ -169,8 +170,16 @@ usrp2_mboard_impl::usrp2_mboard_impl( } usrp2_mboard_impl::~usrp2_mboard_impl(void){ - _iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, 0); - _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, 0); + //Safely destruct all RAII objects in an mboard. + //This prevents the mboard deconstructor from throwing, + //which allows the device to be safely deconstructed. + UHD_SAFE_CALL(_iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, 0);) + UHD_SAFE_CALL(_iface->poke32(_iface->regs.tx_ctrl_packets_per_up, 0);) + UHD_SAFE_CALL(_dboard_manager.reset();) + UHD_SAFE_CALL(_dboard_iface.reset();) + UHD_SAFE_CALL(_codec_ctrl.reset();) + UHD_SAFE_CALL(_clock_ctrl.reset();) + UHD_SAFE_CALL(_gps_ctrl.reset();) } /*********************************************************************** -- cgit v1.2.3