diff options
Diffstat (limited to 'host/lib')
25 files changed, 2745 insertions, 2326 deletions
| diff --git a/host/lib/transport/buffer_pool.cpp b/host/lib/transport/buffer_pool.cpp index 5d1ce37ab..c481b9d02 100644 --- a/host/lib/transport/buffer_pool.cpp +++ b/host/lib/transport/buffer_pool.cpp @@ -22,31 +22,35 @@ boost::detail::atomic_count managed_buffer::s_buffer_count(0);  #endif // UHD_TXRX_DEBUG_PRINTS  //! pad the byte count to a multiple of alignment -static size_t pad_to_boundary(const size_t bytes, const size_t alignment){ -    return bytes + (alignment - bytes)%alignment; +static size_t pad_to_boundary(const size_t bytes, const size_t alignment) +{ +    return bytes + (alignment - bytes) % alignment;  } -buffer_pool::~buffer_pool(void){ +buffer_pool::~buffer_pool(void) +{      /* NOP */  }  /***********************************************************************   * Buffer pool implementation   **********************************************************************/ -class buffer_pool_impl : public buffer_pool{ +class buffer_pool_impl : public buffer_pool +{  public: -    buffer_pool_impl( -        const std::vector<ptr_type> &ptrs, -        boost::shared_array<char> mem -    ): _ptrs(ptrs), _mem(mem){ +    buffer_pool_impl(const std::vector<ptr_type>& ptrs, boost::shared_array<char> mem) +        : _ptrs(ptrs), _mem(mem) +    {          /* NOP */      } -    ptr_type at(const size_t index) const{ +    ptr_type at(const size_t index) const +    {          return _ptrs.at(index);      } -    size_t size(void) const{ +    size_t size(void) const +    {          return _ptrs.size();      } @@ -59,26 +63,23 @@ private:   * Buffer pool factor function   **********************************************************************/  buffer_pool::sptr buffer_pool::make( -    const size_t num_buffs, -    const size_t buff_size, -    const size_t alignment -){ -    //1) pad the buffer size to be a multiple of alignment -    //2) pad the overall memory size for room after alignment -    //3) allocate the memory in one block of sufficient size +    const size_t num_buffs, const size_t buff_size, const size_t alignment) +{ +    // 1) pad the buffer size to be a multiple of alignment +    // 2) pad the overall memory size for room after alignment +    // 3) allocate the memory in one block of sufficient size      const size_t padded_buff_size = pad_to_boundary(buff_size, alignment); -    boost::shared_array<char> mem(new char[padded_buff_size*num_buffs + alignment-1]); +    boost::shared_array<char> mem(new char[padded_buff_size * num_buffs + alignment - 1]); -    //Fill a vector with boundary-aligned points in the memory +    // Fill a vector with boundary-aligned points in the memory      const size_t mem_start = pad_to_boundary(size_t(mem.get()), alignment);      std::vector<ptr_type> ptrs(num_buffs); -    for (size_t i = 0; i < num_buffs; i++){ -        ptrs[i] = ptr_type(mem_start + padded_buff_size*i); +    for (size_t i = 0; i < num_buffs; i++) { +        ptrs[i] = ptr_type(mem_start + padded_buff_size * i);      } -    //Create a new buffer pool implementation with: +    // Create a new buffer pool implementation with:      // - the pre-computed pointers, and      // - the reference to allocated memory.      return sptr(new buffer_pool_impl(ptrs, mem));  } - diff --git a/host/lib/transport/chdr.cpp b/host/lib/transport/chdr.cpp index 36f380d62..ff3b6475a 100644 --- a/host/lib/transport/chdr.cpp +++ b/host/lib/transport/chdr.cpp @@ -5,23 +5,23 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // +#include <uhd/exception.hpp>  #include <uhd/transport/chdr.hpp>  #include <uhd/utils/byteswap.hpp> -#include <uhd/exception.hpp> -//define the endian macros to convert integers +// define the endian macros to convert integers  #ifdef BOOST_BIG_ENDIAN -    #define BE_MACRO(x) (x) -    #define LE_MACRO(x) uhd::byteswap(x) +#    define BE_MACRO(x) (x) +#    define LE_MACRO(x) uhd::byteswap(x)  #else -    #define BE_MACRO(x) uhd::byteswap(x) -    #define LE_MACRO(x) (x) +#    define BE_MACRO(x) uhd::byteswap(x) +#    define LE_MACRO(x) (x)  #endif  using namespace uhd::transport::vrt; -static const uint32_t HDR_FLAG_TSF = (1 << 29); -static const uint32_t HDR_FLAG_EOB = (1 << 28); +static const uint32_t HDR_FLAG_TSF   = (1 << 29); +static const uint32_t HDR_FLAG_EOB   = (1 << 28);  static const uint32_t HDR_FLAG_ERROR = (1 << 28);  static const uint32_t HDR_FLAG_FCACK = (1 << 28); @@ -30,24 +30,25 @@ static const uint32_t HDR_FLAG_FCACK = (1 << 28);  /***************************************************************************/  /*! Translate the contents of \p if_packet_info into a 32-Bit word and return it.   */ -UHD_INLINE uint32_t _hdr_pack_chdr( -        if_packet_info_t &if_packet_info -) { +UHD_INLINE uint32_t _hdr_pack_chdr(if_packet_info_t& if_packet_info) +{      // Set fields in if_packet_info      if_packet_info.num_header_words32 = 2 + (if_packet_info.has_tsf ? 2 : 0);      if_packet_info.num_packet_words32 = -            if_packet_info.num_header_words32 + -            if_packet_info.num_payload_words32; +        if_packet_info.num_header_words32 + if_packet_info.num_payload_words32;      uint16_t pkt_length =          if_packet_info.num_payload_bytes + (4 * if_packet_info.num_header_words32); -    uint32_t chdr = 0 +    uint32_t chdr = +        0          // 2 Bits: Packet type          | (if_packet_info.packet_type << 30)          // 1 Bit: Has time          | (if_packet_info.has_tsf ? HDR_FLAG_TSF : 0)          // 1 Bit: EOB or Error or FC ACK -        | ((if_packet_info.eob or if_packet_info.error or if_packet_info.fc_ack) ? HDR_FLAG_EOB : 0) +        | ((if_packet_info.eob or if_packet_info.error or if_packet_info.fc_ack) +                  ? HDR_FLAG_EOB +                  : 0)          // 12 Bits: Sequence number          | ((if_packet_info.packet_count & 0xFFF) << 16)          // 16 Bits: Total packet length @@ -55,10 +56,8 @@ UHD_INLINE uint32_t _hdr_pack_chdr(      return chdr;  } -void chdr::if_hdr_pack_be( -        uint32_t *packet_buff, -        if_packet_info_t &if_packet_info -) { +void chdr::if_hdr_pack_be(uint32_t* packet_buff, if_packet_info_t& if_packet_info) +{      // Write header and update if_packet_info      packet_buff[0] = BE_MACRO(_hdr_pack_chdr(if_packet_info)); @@ -72,10 +71,8 @@ void chdr::if_hdr_pack_be(      }  } -void chdr::if_hdr_pack_le( -        uint32_t *packet_buff, -        if_packet_info_t &if_packet_info -) { +void chdr::if_hdr_pack_le(uint32_t* packet_buff, if_packet_info_t& if_packet_info) +{      // Write header and update if_packet_info      packet_buff[0] = LE_MACRO(_hdr_pack_chdr(if_packet_info)); @@ -93,27 +90,28 @@ void chdr::if_hdr_pack_le(  /***************************************************************************/  /* Unpacking                                                               */  /***************************************************************************/ -UHD_INLINE void _hdr_unpack_chdr( -        const uint32_t chdr, -        if_packet_info_t &if_packet_info -) { +UHD_INLINE void _hdr_unpack_chdr(const uint32_t chdr, if_packet_info_t& if_packet_info) +{      // Set constant members      if_packet_info.link_type = if_packet_info_t::LINK_TYPE_CHDR; -    if_packet_info.has_cid = false; -    if_packet_info.has_sid = true; -    if_packet_info.has_tsi = false; -    if_packet_info.has_tlr = false; -    if_packet_info.sob = false; +    if_packet_info.has_cid   = false; +    if_packet_info.has_sid   = true; +    if_packet_info.has_tsi   = false; +    if_packet_info.has_tlr   = false; +    if_packet_info.sob       = false;      // Set configurable members -    if_packet_info.has_tsf = (chdr & HDR_FLAG_TSF) > 0; +    if_packet_info.has_tsf     = (chdr & HDR_FLAG_TSF) > 0;      if_packet_info.packet_type = if_packet_info_t::packet_type_t((chdr >> 30) & 0x3); -    if_packet_info.eob = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_DATA) -                         && ((chdr & HDR_FLAG_EOB) > 0); -    if_packet_info.error = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_RESP) -                         && ((chdr & HDR_FLAG_ERROR) > 0); -    if_packet_info.fc_ack = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_FC) -                         && ((chdr & HDR_FLAG_FCACK) > 0); +    if_packet_info.eob = +        (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_DATA) +        && ((chdr & HDR_FLAG_EOB) > 0); +    if_packet_info.error = +        (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_RESP) +        && ((chdr & HDR_FLAG_ERROR) > 0); +    if_packet_info.fc_ack = +        (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_FC) +        && ((chdr & HDR_FLAG_FCACK) > 0);      if_packet_info.packet_count = (chdr >> 16) & 0xFFF;      // Set packet length variables @@ -122,7 +120,7 @@ UHD_INLINE void _hdr_unpack_chdr(      } else {          if_packet_info.num_header_words32 = 2;      } -    size_t pkt_size_bytes = (chdr & 0xFFFF); +    size_t pkt_size_bytes  = (chdr & 0xFFFF);      size_t pkt_size_word32 = (pkt_size_bytes / 4) + ((pkt_size_bytes % 4) ? 1 : 0);      // Check lengths match:      if (pkt_size_word32 < if_packet_info.num_header_words32) { @@ -131,14 +129,14 @@ UHD_INLINE void _hdr_unpack_chdr(      if (if_packet_info.num_packet_words32 < pkt_size_word32) {          throw uhd::value_error("Bad CHDR or packet fragment");      } -    if_packet_info.num_payload_bytes = pkt_size_bytes - (4 * if_packet_info.num_header_words32); -    if_packet_info.num_payload_words32 = pkt_size_word32 - if_packet_info.num_header_words32; +    if_packet_info.num_payload_bytes = +        pkt_size_bytes - (4 * if_packet_info.num_header_words32); +    if_packet_info.num_payload_words32 = +        pkt_size_word32 - if_packet_info.num_header_words32;  } -void chdr::if_hdr_unpack_be( -        const uint32_t *packet_buff, -        if_packet_info_t &if_packet_info -) { +void chdr::if_hdr_unpack_be(const uint32_t* packet_buff, if_packet_info_t& if_packet_info) +{      // Read header and update if_packet_info      uint32_t chdr = BE_MACRO(packet_buff[0]);      _hdr_unpack_chdr(chdr, if_packet_info); @@ -148,16 +146,13 @@ void chdr::if_hdr_unpack_be(      // Read time (has_tsf was updated earlier)      if (if_packet_info.has_tsf) { -        if_packet_info.tsf = 0 -            | uint64_t(BE_MACRO(packet_buff[2])) << 32 -            | BE_MACRO(packet_buff[3]); +        if_packet_info.tsf = 0 | uint64_t(BE_MACRO(packet_buff[2])) << 32 +                             | BE_MACRO(packet_buff[3]);      }  } -void chdr::if_hdr_unpack_le( -        const uint32_t *packet_buff, -        if_packet_info_t &if_packet_info -) { +void chdr::if_hdr_unpack_le(const uint32_t* packet_buff, if_packet_info_t& if_packet_info) +{      // Read header and update if_packet_info      uint32_t chdr = LE_MACRO(packet_buff[0]);      _hdr_unpack_chdr(chdr, if_packet_info); @@ -167,9 +162,7 @@ void chdr::if_hdr_unpack_le(      // Read time (has_tsf was updated earlier)      if (if_packet_info.has_tsf) { -        if_packet_info.tsf = 0 -            | uint64_t(LE_MACRO(packet_buff[2])) << 32 -            | LE_MACRO(packet_buff[3]); +        if_packet_info.tsf = 0 | uint64_t(LE_MACRO(packet_buff[2])) << 32 +                             | LE_MACRO(packet_buff[3]);      }  } - diff --git a/host/lib/transport/dpdk_zero_copy.cpp b/host/lib/transport/dpdk_zero_copy.cpp index 2e95efd81..51c9b9dba 100644 --- a/host/lib/transport/dpdk_zero_copy.cpp +++ b/host/lib/transport/dpdk_zero_copy.cpp @@ -6,106 +6,104 @@  #include "dpdk_zero_copy.hpp"  #include <uhd/config.hpp> -#include <uhd/utils/static.hpp>  #include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp>  #include <uhdlib/transport/uhd-dpdk.h> -#include <boost/make_shared.hpp> +#include <arpa/inet.h>  #include <sys/syslog.h> +#include <boost/make_shared.hpp>  #include <stack> -#include <arpa/inet.h>  namespace uhd { namespace transport {  namespace { -    static constexpr uint64_t USEC = 1000000; -    // FIXME: Make configurable and have uhd-dpdk library track buffer sizes -    static constexpr size_t DEFAULT_FRAME_SIZE = 8000; +static constexpr uint64_t USEC = 1000000; +// FIXME: Make configurable and have uhd-dpdk library track buffer sizes +static constexpr size_t DEFAULT_FRAME_SIZE = 8000; -    inline char * eal_add_opt(std::vector<const char*>& argv, size_t n, -                              char *dst, const char *opt, const char *arg) -    { -        char *ptr = dst; -        strncpy(ptr, opt, n); -        argv.push_back(ptr); -        ptr += strlen(opt) + 1; -        n -= ptr - dst; -        strncpy(ptr, arg, n); -        argv.push_back(ptr); -        ptr += strlen(arg) + 1; -        return ptr; -    } +inline char* eal_add_opt( +    std::vector<const char*>& argv, size_t n, char* dst, const char* opt, const char* arg) +{ +    char* ptr = dst; +    strncpy(ptr, opt, n); +    argv.push_back(ptr); +    ptr += strlen(opt) + 1; +    n -= ptr - dst; +    strncpy(ptr, arg, n); +    argv.push_back(ptr); +    ptr += strlen(arg) + 1; +    return ptr;  } +} // namespace  uhd_dpdk_ctx::uhd_dpdk_ctx(void) : _init_done(false) {}  uhd_dpdk_ctx::~uhd_dpdk_ctx(void) {}  /* Initialize uhd-dpdk (and do only once) */ -void uhd_dpdk_ctx::init(const dict<std::string, std::string> &eal_args, -                        unsigned int num_ports, int *port_thread_mapping, -                        int num_mbufs, int mbuf_cache_size, size_t mtu) +void uhd_dpdk_ctx::init(const dict<std::string, std::string>& eal_args, +    unsigned int num_ports, +    int* port_thread_mapping, +    int num_mbufs, +    int mbuf_cache_size, +    size_t mtu)  {      std::lock_guard<std::mutex> lock(_init_mutex);      if (!_init_done) {          _mtu = mtu;          /* Build up argc and argv */ -        std::vector<const char *> argv; +        std::vector<const char*> argv;          argv.push_back("uhd-dpdk"); -        char *args = new char[4096]; -        char *opt = args; -        char *end = args + sizeof(args); -        for (std::string &key : eal_args.keys()) { +        char* args = new char[4096]; +        char* opt  = args; +        char* end  = args + sizeof(args); +        for (std::string& key : eal_args.keys()) {              std::string val = eal_args[key];              if (key == "coremask") { -                opt = eal_add_opt(argv, end - opt, opt, "-c", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "-c", val.c_str());              } else if (key == "corelist") {                  /* NOTE: This arg may have commas, so limited to config file */ -                opt = eal_add_opt(argv, end - opt, opt, "-l", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "-l", val.c_str());              } else if (key == "coremap") { -                opt = eal_add_opt(argv, end - opt, opt, "--lcores", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "--lcores", val.c_str());              } else if (key == "master-lcore") { -                opt = eal_add_opt(argv, end - opt, opt, "--master-lcore", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "--master-lcore", val.c_str());              } else if (key == "pci-blacklist") { -                opt = eal_add_opt(argv, end - opt, opt, "-b", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "-b", val.c_str());              } else if (key == "pci-whitelist") { -                opt = eal_add_opt(argv, end - opt, opt, "-w", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "-w", val.c_str());              } else if (key == "log-level") { -                opt = eal_add_opt(argv, end - opt, opt, "--log-level", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "--log-level", val.c_str());              } else if (key == "huge-dir") { -                opt = eal_add_opt(argv, end - opt, opt, "--huge-dir", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "--huge-dir", val.c_str());              } else if (key == "file-prefix") { -                opt = eal_add_opt(argv, end - opt, opt, "--file-prefix", -                                  val.c_str()); +                opt = eal_add_opt(argv, end - opt, opt, "--file-prefix", val.c_str());              }          } -        uhd_dpdk_init(argv.size(), argv.data(), num_ports, port_thread_mapping, num_mbufs, -                      mbuf_cache_size, _mtu); +        uhd_dpdk_init(argv.size(), +            argv.data(), +            num_ports, +            port_thread_mapping, +            num_mbufs, +            mbuf_cache_size, +            _mtu);          delete args;          _init_done = true;      }  } -int uhd_dpdk_ctx::get_port_id(std::array<uint8_t, 6> mac_addr, -                              unsigned int &port_id) +int uhd_dpdk_ctx::get_port_id(std::array<uint8_t, 6> mac_addr, unsigned int& port_id)  {      UHD_ASSERT_THROW(is_init_done());      int num_ports = uhd_dpdk_port_count();      for (int i = 0; i < num_ports; i++) { -        struct eth_addr port_mac_addr = uhd_dpdk_get_eth_addr((unsigned int) i); +        struct eth_addr port_mac_addr = uhd_dpdk_get_eth_addr((unsigned int)i);          for (int j = 0; j < 6; j++) {              if (mac_addr[j] != port_mac_addr.addr[j]) {                  break;              }              if (j == 5) { -                port_id = (unsigned int) i; +                port_id = (unsigned int)i;                  return 0;              }          } @@ -113,23 +111,23 @@ int uhd_dpdk_ctx::get_port_id(std::array<uint8_t, 6> mac_addr,      return -1;  } -int uhd_dpdk_ctx::get_route(const std::string &addr) const +int uhd_dpdk_ctx::get_route(const std::string& addr) const  { -    const uint32_t dst_ipv4 = (uint32_t) inet_addr(addr.c_str()); +    const uint32_t dst_ipv4      = (uint32_t)inet_addr(addr.c_str());      const unsigned int num_ports = uhd_dpdk_port_count();      for (unsigned int port = 0; port < num_ports; port++) {          uint32_t src_ipv4;          uint32_t netmask;          uhd_dpdk_get_ipv4_addr(port, &src_ipv4, &netmask);          if ((src_ipv4 & netmask) == (dst_ipv4 & netmask)) { -            return (int) port; -	} +            return (int)port; +        }      }      return -ENODEV;  } -int uhd_dpdk_ctx::set_ipv4_addr(unsigned int port_id, uint32_t ipv4_addr, -                                uint32_t netmask) +int uhd_dpdk_ctx::set_ipv4_addr( +    unsigned int port_id, uint32_t ipv4_addr, uint32_t netmask)  {      return uhd_dpdk_set_ipv4_addr(port_id, ipv4_addr, netmask);  } @@ -140,23 +138,25 @@ bool uhd_dpdk_ctx::is_init_done(void)  } -class dpdk_zero_copy_msb : public managed_send_buffer { +class dpdk_zero_copy_msb : public managed_send_buffer +{  public: -    dpdk_zero_copy_msb(struct uhd_dpdk_socket *sock, -                      std::stack<dpdk_zero_copy_msb *, std::vector<dpdk_zero_copy_msb *>> &free_bufs) -                      : _sock(sock), _buf(nullptr), _free_bufs(free_bufs) {}; +    dpdk_zero_copy_msb(struct uhd_dpdk_socket* sock, +        std::stack<dpdk_zero_copy_msb*, std::vector<dpdk_zero_copy_msb*>>& free_bufs) +        : _sock(sock), _buf(nullptr), _free_bufs(free_bufs){};      ~dpdk_zero_copy_msb(void) {}      void release(void)      {          if (_buf) { -            _buf->pkt_len = _length; +            _buf->pkt_len  = _length;              _buf->data_len = _length; -            int num_tx = uhd_dpdk_send(_sock, &_buf, 1); +            int num_tx     = uhd_dpdk_send(_sock, &_buf, 1);              if (num_tx == 0) {                  /* Drop packet and free buffer (do not share sockets!) */ -                UHD_LOG_ERROR("DPDK", "Invalid shared socket usage detected. Dropping packet..."); +                UHD_LOG_ERROR( +                    "DPDK", "Invalid shared socket usage detected. Dropping packet...");                  uhd_dpdk_free_buf(_buf);              }              // Push back into pool @@ -170,21 +170,21 @@ public:          if (bufs != 1 || !_buf)              return sptr(); -        return make(this, uhd_dpdk_buf_to_data(_sock, _buf), -                    DEFAULT_FRAME_SIZE); +        return make(this, uhd_dpdk_buf_to_data(_sock, _buf), DEFAULT_FRAME_SIZE);      }  private: -    struct uhd_dpdk_socket *_sock; -    struct rte_mbuf *_buf; -    std::stack<dpdk_zero_copy_msb *, std::vector<dpdk_zero_copy_msb *>> &_free_bufs; +    struct uhd_dpdk_socket* _sock; +    struct rte_mbuf* _buf; +    std::stack<dpdk_zero_copy_msb*, std::vector<dpdk_zero_copy_msb*>>& _free_bufs;  }; -class dpdk_zero_copy_mrb : public managed_recv_buffer { +class dpdk_zero_copy_mrb : public managed_recv_buffer +{  public: -    dpdk_zero_copy_mrb(struct uhd_dpdk_socket *sock, -                      std::stack<dpdk_zero_copy_mrb *, std::vector<dpdk_zero_copy_mrb *>> &free_bufs) -                      : _sock(sock), _buf(nullptr), _free_bufs(free_bufs) {}; +    dpdk_zero_copy_mrb(struct uhd_dpdk_socket* sock, +        std::stack<dpdk_zero_copy_mrb*, std::vector<dpdk_zero_copy_mrb*>>& free_bufs) +        : _sock(sock), _buf(nullptr), _free_bufs(free_bufs){};      ~dpdk_zero_copy_mrb(void) {}      void release(void) @@ -197,7 +197,7 @@ public:      sptr get_new(double timeout)      { -        int bufs = uhd_dpdk_recv(_sock, &_buf, 1, (int) (timeout*USEC)); +        int bufs = uhd_dpdk_recv(_sock, &_buf, 1, (int)(timeout * USEC));          if (bufs != 1 || _buf == nullptr) {              // Push back into pool if we didn't get a real buffer              _free_bufs.push(this); @@ -210,32 +210,32 @@ public:              return sptr();          } -        return make(this, uhd_dpdk_buf_to_data(_sock, _buf), -                    uhd_dpdk_get_len(_sock, _buf)); +        return make( +            this, uhd_dpdk_buf_to_data(_sock, _buf), uhd_dpdk_get_len(_sock, _buf));      }  private: -    struct uhd_dpdk_socket *_sock; -    struct rte_mbuf *_buf; -    std::stack<dpdk_zero_copy_mrb *, std::vector<dpdk_zero_copy_mrb *>> &_free_bufs; +    struct uhd_dpdk_socket* _sock; +    struct rte_mbuf* _buf; +    std::stack<dpdk_zero_copy_mrb*, std::vector<dpdk_zero_copy_mrb*>>& _free_bufs;  }; -class dpdk_zero_copy_impl : public dpdk_zero_copy { +class dpdk_zero_copy_impl : public dpdk_zero_copy +{  public: - -    dpdk_zero_copy_impl(struct uhd_dpdk_ctx &ctx, -                        const unsigned int dpdk_port_id, -                        const std::string &addr, -                        const std::string &remote_port, -                        const std::string &local_port, -                        const zero_copy_xport_params& xport_params) -                          : _num_send_frames(xport_params.num_send_frames), -                            _send_frame_size(xport_params.send_frame_size), -                            _num_recv_frames(xport_params.num_recv_frames), -                            _recv_frame_size(xport_params.recv_frame_size), -                            _port_id(dpdk_port_id), -                            _rx_empty_count(0), -                            _tx_empty_count(0) +    dpdk_zero_copy_impl(struct uhd_dpdk_ctx& ctx, +        const unsigned int dpdk_port_id, +        const std::string& addr, +        const std::string& remote_port, +        const std::string& local_port, +        const zero_copy_xport_params& xport_params) +        : _num_send_frames(xport_params.num_send_frames) +        , _send_frame_size(xport_params.send_frame_size) +        , _num_recv_frames(xport_params.num_recv_frames) +        , _recv_frame_size(xport_params.recv_frame_size) +        , _port_id(dpdk_port_id) +        , _rx_empty_count(0) +        , _tx_empty_count(0)      {          // TODO: Handle xport_params          UHD_ASSERT_THROW(xport_params.recv_frame_size > 0); @@ -247,30 +247,28 @@ public:          const int num_ports = uhd_dpdk_port_count();          UHD_ASSERT_THROW(num_ports > 0); -        UHD_ASSERT_THROW(dpdk_port_id < (unsigned int) num_ports); +        UHD_ASSERT_THROW(dpdk_port_id < (unsigned int)num_ports);          // Convert ipv4 addr from string to uint32_t, network format -        uint32_t dst_ipv4 = (uint32_t) inet_addr(addr.c_str()); +        uint32_t dst_ipv4 = (uint32_t)inet_addr(addr.c_str());          // Convert port from string to uint16_t, network format          uint16_t dst_port = htons(std::stoi(remote_port, NULL, 0));          uint16_t src_port = htons(std::stoi(local_port, NULL, 0));          // Create RX socket first -        struct uhd_dpdk_sockarg_udp sockarg = { -            .is_tx = false, -            .local_port = src_port, -            .remote_port = dst_port, -            .dst_addr = dst_ipv4 -        }; +        struct uhd_dpdk_sockarg_udp sockarg = {.is_tx = false, +            .local_port                               = src_port, +            .remote_port                              = dst_port, +            .dst_addr                                 = dst_ipv4};          _rx_sock = uhd_dpdk_sock_open(dpdk_port_id, UHD_DPDK_SOCK_UDP, &sockarg);          UHD_ASSERT_THROW(_rx_sock != nullptr);          // Backfill the local port, in case it was auto-assigned          uhd_dpdk_udp_get_info(_rx_sock, &sockarg); -        sockarg.is_tx = true; +        sockarg.is_tx       = true;          sockarg.remote_port = dst_port; -        sockarg.dst_addr = dst_ipv4; +        sockarg.dst_addr    = dst_ipv4;          _tx_sock = uhd_dpdk_sock_open(dpdk_port_id, UHD_DPDK_SOCK_UDP, &sockarg);          UHD_ASSERT_THROW(_tx_sock != nullptr); @@ -282,9 +280,10 @@ public:              _msb_pool.push(new dpdk_zero_copy_msb(_tx_sock, _msb_pool));          } -        UHD_LOG_TRACE("DPDK", "Created transports between " << addr << ":" -                               << remote_port << " and NIC(" << dpdk_port_id -                               << "):" << ntohs(sockarg.local_port)); +        UHD_LOG_TRACE("DPDK", +            "Created transports between " << addr << ":" << remote_port << " and NIC(" +                                          << dpdk_port_id +                                          << "):" << ntohs(sockarg.local_port));      }      ~dpdk_zero_copy_impl(void) @@ -293,18 +292,23 @@ public:          size_t count;          uhd_dpdk_udp_get_info(_rx_sock, &sockarg);          uhd_dpdk_get_drop_count(_rx_sock, &count); -        UHD_LOG_TRACE("DPDK", "Closing transports between " << sockarg.dst_addr << ":" -                               << ntohs(sockarg.remote_port) << " and local:" -                               << ntohs(sockarg.local_port)); -        UHD_LOG_TRACE("DPDK", "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " -                              << " Dropped "<< count << " packets"); +        UHD_LOG_TRACE("DPDK", +            "Closing transports between " << sockarg.dst_addr << ":" +                                          << ntohs(sockarg.remote_port) +                                          << " and local:" << ntohs(sockarg.local_port)); +        UHD_LOG_TRACE("DPDK", +            "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " +                << " Dropped " << count << " packets");          uhd_dpdk_get_xfer_count(_rx_sock, &count); -        UHD_LOG_TRACE("DPDK", "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " -                              << " Received "<< count << " packets"); -        UHD_LOG_TRACE("DPDK", "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " -                              << "RX empty count is " << _rx_empty_count); -        UHD_LOG_TRACE("DPDK", "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " -                              << "TX empty count is " << _tx_empty_count); +        UHD_LOG_TRACE("DPDK", +            "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " +                << " Received " << count << " packets"); +        UHD_LOG_TRACE("DPDK", +            "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " +                << "RX empty count is " << _rx_empty_count); +        UHD_LOG_TRACE("DPDK", +            "(" << ntohs(sockarg.remote_port) << "," << ntohs(sockarg.local_port) << ") " +                << "TX empty count is " << _tx_empty_count);          uhd_dpdk_sock_close(_rx_sock);          uhd_dpdk_sock_close(_tx_sock);      } @@ -316,7 +320,7 @@ public:              return managed_recv_buffer::sptr();          } -        dpdk_zero_copy_mrb *mrb = _mrb_pool.top(); +        dpdk_zero_copy_mrb* mrb = _mrb_pool.top();          _mrb_pool.pop();          managed_recv_buffer::sptr buff = mrb->get_new(timeout);          if (!buff) @@ -341,7 +345,7 @@ public:              return managed_send_buffer::sptr();          } -        dpdk_zero_copy_msb *msb = _msb_pool.top(); +        dpdk_zero_copy_msb* msb = _msb_pool.top();          _msb_pool.pop();          managed_send_buffer::sptr buff = msb->get_new(timeout);          if (!buff) @@ -369,14 +373,11 @@ public:      std::string get_local_addr(void) const      {          uint32_t ipv4_addr; -        int status = uhd_dpdk_get_ipv4_addr(_port_id, &ipv4_addr, NULL); -        auto retval = std::to_string(ipv4_addr >> 0 & 0xff) + -                      "." + -                      std::to_string(ipv4_addr >> 8 & 0xff) + -                      "." + -                      std::to_string(ipv4_addr >> 16 & 0xff) + -                      "." + -                      std::to_string(ipv4_addr >> 24 & 0xff); +        int status  = uhd_dpdk_get_ipv4_addr(_port_id, &ipv4_addr, NULL); +        auto retval = std::to_string(ipv4_addr >> 0 & 0xff) + "." +                      + std::to_string(ipv4_addr >> 8 & 0xff) + "." +                      + std::to_string(ipv4_addr >> 16 & 0xff) + "." +                      + std::to_string(ipv4_addr >> 24 & 0xff);          return retval;      } @@ -386,9 +387,10 @@ public:          uhd_dpdk_get_drop_count(_rx_sock, &drop_count);          return drop_count;      } +  private: -    struct uhd_dpdk_socket *_rx_sock; -    struct uhd_dpdk_socket *_tx_sock; +    struct uhd_dpdk_socket* _rx_sock; +    struct uhd_dpdk_socket* _tx_sock;      const size_t _num_send_frames;      const size_t _send_frame_size;      const size_t _num_recv_frames; @@ -397,22 +399,20 @@ private:      unsigned int _rx_empty_count;      unsigned int _tx_empty_count; -    std::stack<dpdk_zero_copy_mrb *, std::vector<dpdk_zero_copy_mrb *>> _mrb_pool; -    std::stack<dpdk_zero_copy_msb *, std::vector<dpdk_zero_copy_msb *>> _msb_pool; +    std::stack<dpdk_zero_copy_mrb*, std::vector<dpdk_zero_copy_mrb*>> _mrb_pool; +    std::stack<dpdk_zero_copy_msb*, std::vector<dpdk_zero_copy_msb*>> _msb_pool;  }; -dpdk_zero_copy::sptr dpdk_zero_copy::make( -    struct uhd_dpdk_ctx &ctx, +dpdk_zero_copy::sptr dpdk_zero_copy::make(struct uhd_dpdk_ctx& ctx,      const unsigned int dpdk_port_id, -    const std::string &addr, -    const std::string &remote_port, -    const std::string &local_port, -    const zero_copy_xport_params &default_buff_args, -    const device_addr_t &hints) +    const std::string& addr, +    const std::string& remote_port, +    const std::string& local_port, +    const zero_copy_xport_params& default_buff_args, +    const device_addr_t& hints)  { -    return dpdk_zero_copy::sptr( -        new dpdk_zero_copy_impl(ctx, dpdk_port_id, addr, remote_port, local_port, default_buff_args) -    ); +    return dpdk_zero_copy::sptr(new dpdk_zero_copy_impl( +        ctx, dpdk_port_id, addr, remote_port, local_port, default_buff_args));  } -}} +}} // namespace uhd::transport diff --git a/host/lib/transport/dpdk_zero_copy.hpp b/host/lib/transport/dpdk_zero_copy.hpp index a4b5b4879..f90e73d0e 100644 --- a/host/lib/transport/dpdk_zero_copy.hpp +++ b/host/lib/transport/dpdk_zero_copy.hpp @@ -8,19 +8,20 @@  #define DPDK_ZERO_COPY_HPP  #include <uhd/config.hpp> +#include <uhd/transport/zero_copy.hpp>  #include <uhd/types/device_addr.hpp> -#include <uhd/utils/static.hpp>  #include <uhd/utils/log.hpp> -#include <uhd/transport/zero_copy.hpp> +#include <uhd/utils/static.hpp>  #include <boost/shared_ptr.hpp> +#include <mutex>  #include <string>  #include <vector> -#include <mutex>  namespace uhd { namespace transport { -class uhd_dpdk_ctx : boost::noncopyable { +class uhd_dpdk_ctx : boost::noncopyable +{  public:      UHD_SINGLETON_FCN(uhd_dpdk_ctx, get); @@ -35,9 +36,12 @@ public:       * \param mbuf_cache_size Size of per-core packet buffer cache from mempool       * \param mtu MTU of NIC ports       */ -    void init(const dict<std::string, std::string> &eal_args, unsigned int num_ports, -              int *port_thread_mapping, int num_mbufs, int mbuf_cache_size, -              size_t mtu); +    void init(const dict<std::string, std::string>& eal_args, +        unsigned int num_ports, +        int* port_thread_mapping, +        int num_mbufs, +        int mbuf_cache_size, +        size_t mtu);      /*!       * Get port ID from provided MAC address @@ -45,14 +49,14 @@ public:       * \param port_id Int to write ID of port corresponding to MAC address       * \return 0 if match found, else no match       */ -    int get_port_id(std::array<uint8_t, 6> mac_addr, unsigned int &port_id); +    int get_port_id(std::array<uint8_t, 6> mac_addr, unsigned int& port_id);      /*!       * Get port ID for routing packet destined for given address       * \param addr Destination address       * \return port ID from routing table       */ -    int get_route(const std::string &addr) const; +    int get_route(const std::string& addr) const;      /*!       * Set IPv4 address and subnet mask of given NIC port @@ -80,19 +84,18 @@ private:  /*!   * A zero copy transport interface to the dpdk DMA library.   */ -class dpdk_zero_copy : public virtual zero_copy_if { +class dpdk_zero_copy : public virtual zero_copy_if +{  public:      typedef boost::shared_ptr<dpdk_zero_copy> sptr; -    static sptr make( -        struct uhd_dpdk_ctx &ctx, +    static sptr make(struct uhd_dpdk_ctx& ctx,          const unsigned int dpdk_port_id, -        const std::string &addr, -        const std::string &remote_port, -        const std::string &local_port, /* 0 = auto-assign */ -        const zero_copy_xport_params &default_buff_args, -        const device_addr_t &hints -    ); +        const std::string& addr, +        const std::string& remote_port, +        const std::string& local_port, /* 0 = auto-assign */ +        const zero_copy_xport_params& default_buff_args, +        const device_addr_t& hints);      virtual uint16_t get_local_port(void) const = 0; @@ -101,6 +104,6 @@ public:      virtual uint32_t get_drop_count(void) const = 0;  }; -}} +}} // namespace uhd::transport  #endif /* DPDK_ZERO_COPY_HPP */ diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp index 109619601..a1cb6909f 100644 --- a/host/lib/transport/if_addrs.cpp +++ b/host/lib/transport/if_addrs.cpp @@ -6,47 +6,54 @@  //  #include <uhd/transport/if_addrs.hpp> -#include <boost/asio/ip/address_v4.hpp>  #include <stdint.h> +#include <boost/asio/ip/address_v4.hpp>  #include <iostream>  /***********************************************************************   * Interface address discovery through ifaddrs api   **********************************************************************/  #ifdef HAVE_GETIFADDRS -#include <ifaddrs.h> +#    include <ifaddrs.h> -static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ -    return boost::asio::ip::address_v4(ntohl( -        reinterpret_cast<sockaddr_in*>(addr)->sin_addr.s_addr -    )); +static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr* addr) +{ +    return boost::asio::ip::address_v4( +        ntohl(reinterpret_cast<sockaddr_in*>(addr)->sin_addr.s_addr));  } -std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){ +std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void) +{      std::vector<if_addrs_t> if_addrs; -    struct ifaddrs *ifap; -    if (getifaddrs(&ifap) == 0){ -        for (struct ifaddrs *iter = ifap; iter != nullptr; iter = iter->ifa_next){ -            //ensure that the entries are valid -            if (iter->ifa_addr == nullptr) continue; -            if (iter->ifa_addr->sa_family != AF_INET) continue; -            if (iter->ifa_netmask->sa_family != AF_INET) continue; -            if (iter->ifa_broadaddr->sa_family != AF_INET) continue; - -            //append a new set of interface addresses +    struct ifaddrs* ifap; +    if (getifaddrs(&ifap) == 0) { +        for (struct ifaddrs* iter = ifap; iter != nullptr; iter = iter->ifa_next) { +            // ensure that the entries are valid +            if (iter->ifa_addr == nullptr) +                continue; +            if (iter->ifa_addr->sa_family != AF_INET) +                continue; +            if (iter->ifa_netmask->sa_family != AF_INET) +                continue; +            if (iter->ifa_broadaddr->sa_family != AF_INET) +                continue; + +            // append a new set of interface addresses              if_addrs_t if_addr; -            if_addr.inet = sockaddr_to_ip_addr(iter->ifa_addr).to_string(); -            if_addr.mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_string(); +            if_addr.inet  = sockaddr_to_ip_addr(iter->ifa_addr).to_string(); +            if_addr.mask  = sockaddr_to_ip_addr(iter->ifa_netmask).to_string();              if_addr.bcast = sockaddr_to_ip_addr(iter->ifa_broadaddr).to_string(); -            //correct the bcast address when its same as the gateway -            if (if_addr.inet == if_addr.bcast or sockaddr_to_ip_addr(iter->ifa_broadaddr) == boost::asio::ip::address_v4(0)){ -                //manually calculate broadcast address -                //https://svn.boost.org/trac/boost/ticket/5198 -                const uint32_t addr = sockaddr_to_ip_addr(iter->ifa_addr).to_ulong(); -                const uint32_t mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_ulong(); +            // correct the bcast address when its same as the gateway +            if (if_addr.inet == if_addr.bcast +                or sockaddr_to_ip_addr(iter->ifa_broadaddr) +                       == boost::asio::ip::address_v4(0)) { +                // manually calculate broadcast address +                // https://svn.boost.org/trac/boost/ticket/5198 +                const uint32_t addr  = sockaddr_to_ip_addr(iter->ifa_addr).to_ulong(); +                const uint32_t mask  = sockaddr_to_ip_addr(iter->ifa_netmask).to_ulong();                  const uint32_t bcast = (addr & mask) | ~mask; -                if_addr.bcast = boost::asio::ip::address_v4(bcast).to_string(); +                if_addr.bcast        = boost::asio::ip::address_v4(bcast).to_string();              }              if_addrs.push_back(if_addr); @@ -62,34 +69,44 @@ std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){   * Interface address discovery through windows api   **********************************************************************/  #ifdef HAVE_SIO_GET_INTERFACE_LIST -#include <winsock2.h> +#    include <winsock2.h> -std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){ +std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void) +{      std::vector<if_addrs_t> if_addrs;      SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);      if (sd == SOCKET_ERROR) { -        std::cerr << "Failed to get a socket. Error " << WSAGetLastError() << -            std::endl; return if_addrs; +        std::cerr << "Failed to get a socket. Error " << WSAGetLastError() << std::endl; +        return if_addrs;      }      INTERFACE_INFO InterfaceList[20];      unsigned long nBytesReturned; -    if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, -			sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) { -        std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() << -				std::endl; -		return if_addrs; +    if (WSAIoctl(sd, +            SIO_GET_INTERFACE_LIST, +            0, +            0, +            &InterfaceList, +            sizeof(InterfaceList), +            &nBytesReturned, +            0, +            0) +        == SOCKET_ERROR) { +        std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() << std::endl; +        return if_addrs;      }      int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);      for (int i = 0; i < nNumInterfaces; ++i) { -        uint32_t iiAddress = ntohl(reinterpret_cast<sockaddr_in&>(InterfaceList[i].iiAddress).sin_addr.s_addr); -        uint32_t iiNetmask = ntohl(reinterpret_cast<sockaddr_in&>(InterfaceList[i].iiNetmask).sin_addr.s_addr); +        uint32_t iiAddress = ntohl( +            reinterpret_cast<sockaddr_in&>(InterfaceList[i].iiAddress).sin_addr.s_addr); +        uint32_t iiNetmask = ntohl( +            reinterpret_cast<sockaddr_in&>(InterfaceList[i].iiNetmask).sin_addr.s_addr);          uint32_t iiBroadcastAddress = (iiAddress & iiNetmask) | ~iiNetmask;          if_addrs_t if_addr; -        if_addr.inet = boost::asio::ip::address_v4(iiAddress).to_string(); -        if_addr.mask = boost::asio::ip::address_v4(iiNetmask).to_string(); +        if_addr.inet  = boost::asio::ip::address_v4(iiAddress).to_string(); +        if_addr.mask  = boost::asio::ip::address_v4(iiNetmask).to_string();          if_addr.bcast = boost::asio::ip::address_v4(iiBroadcastAddress).to_string();          if_addrs.push_back(if_addr);      } @@ -104,7 +121,8 @@ std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){   **********************************************************************/  #ifdef HAVE_IF_ADDRS_DUMMY -std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){ +std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void) +{      return std::vector<if_addrs_t>();  } diff --git a/host/lib/transport/liberio_zero_copy.cpp b/host/lib/transport/liberio_zero_copy.cpp index 0999d78cf..989480382 100644 --- a/host/lib/transport/liberio_zero_copy.cpp +++ b/host/lib/transport/liberio_zero_copy.cpp @@ -7,33 +7,34 @@  #include "liberio_zero_copy.hpp"  #include <uhd/config.hpp> -#include <uhd/utils/static.hpp>  #include <uhd/utils/log.hpp> +#include <uhd/utils/static.hpp>  #include <liberio/liberio.h> -#include <boost/make_shared.hpp>  #include <sys/syslog.h> +#include <boost/make_shared.hpp>  #include <mutex>  namespace uhd { namespace transport {  static const uint64_t USEC = 1000000; -static void liberio_log_cb(int severity, const char *msg, void *) +static void liberio_log_cb(int severity, const char* msg, void*)  {      switch (severity) { -    case LOG_WARNING: -        UHD_LOG_WARNING("LIBERIO", msg); -        return; -    case LOG_NOTICE: -    case LOG_INFO: -        UHD_LOG_INFO("LIBERIO", msg); -        return; -    default: -        UHD_LOG_INFO("LIBERIO", msg); +        case LOG_WARNING: +            UHD_LOG_WARNING("LIBERIO", msg); +            return; +        case LOG_NOTICE: +        case LOG_INFO: +            UHD_LOG_INFO("LIBERIO", msg); +            return; +        default: +            UHD_LOG_INFO("LIBERIO", msg);      };  } -class liberio_context_holder { +class liberio_context_holder +{  public:      liberio_context_holder(void)      { @@ -41,22 +42,27 @@ public:          liberio_ctx_register_logger(_ctx, &liberio_log_cb, nullptr);      } -    ~liberio_context_holder(void) { liberio_ctx_put(_ctx); } +    ~liberio_context_holder(void) +    { +        liberio_ctx_put(_ctx); +    }      liberio_ctx* get(void)      {          liberio_ctx_get(_ctx);          return _ctx;      } +  private: -    liberio_ctx *_ctx; +    liberio_ctx* _ctx;  };  UHD_SINGLETON_FCN(liberio_context_holder, get_liberio_context_holder); -class liberio_zero_copy_msb : public virtual managed_send_buffer { +class liberio_zero_copy_msb : public virtual managed_send_buffer +{  public: -    liberio_zero_copy_msb(liberio_chan *chan) : _chan(chan), _buf(nullptr) {} +    liberio_zero_copy_msb(liberio_chan* chan) : _chan(chan), _buf(nullptr) {}      ~liberio_zero_copy_msb(void)      {          liberio_chan_put(_chan); @@ -70,7 +76,7 @@ public:          }      } -    sptr get_new(double timeout, size_t &index) +    sptr get_new(double timeout, size_t& index)      {          _buf = liberio_chan_buf_dequeue(_chan, timeout * USEC);          if (!_buf) @@ -78,18 +84,18 @@ public:          index++; -        return make(this, liberio_buf_get_mem(_buf, 0), -                    liberio_buf_get_len(_buf, 0)); +        return make(this, liberio_buf_get_mem(_buf, 0), liberio_buf_get_len(_buf, 0));      }  private: -    liberio_chan *_chan; -    liberio_buf *_buf; +    liberio_chan* _chan; +    liberio_buf* _buf;  }; -class liberio_zero_copy_mrb : public virtual managed_recv_buffer { +class liberio_zero_copy_mrb : public virtual managed_recv_buffer +{  public: -    liberio_zero_copy_mrb(liberio_chan *chan) : _chan(chan), _buf(nullptr) {} +    liberio_zero_copy_mrb(liberio_chan* chan) : _chan(chan), _buf(nullptr) {}      ~liberio_zero_copy_mrb(void)      {          liberio_chan_put(_chan); @@ -101,7 +107,7 @@ public:              liberio_chan_buf_enqueue(_chan, _buf);      } -    sptr get_new(double timeout, size_t &index) +    sptr get_new(double timeout, size_t& index)      {          _buf = liberio_chan_buf_dequeue(_chan, timeout * USEC);          if (!_buf) @@ -109,65 +115,55 @@ public:          index++; -        return make(this, liberio_buf_get_mem(_buf, 0), -                    liberio_buf_get_payload(_buf, 0)); +        return make(this, liberio_buf_get_mem(_buf, 0), liberio_buf_get_payload(_buf, 0));      }  private: -    liberio_chan *_chan; -    liberio_buf *_buf; +    liberio_chan* _chan; +    liberio_buf* _buf;  }; -class liberio_zero_copy_impl : public liberio_zero_copy { +class liberio_zero_copy_impl : public liberio_zero_copy +{  public: - -    liberio_zero_copy_impl(const std::string &tx_path, -                           const std::string &rx_path, -                           const zero_copy_xport_params& xport_params) -                          : _tx_buf_size(xport_params.send_frame_size), -                            _rx_buf_size(xport_params.recv_frame_size), -                            _next_recv_buff_index(0), -                            _next_send_buff_index(0) +    liberio_zero_copy_impl(const std::string& tx_path, +        const std::string& rx_path, +        const zero_copy_xport_params& xport_params) +        : _tx_buf_size(xport_params.send_frame_size) +        , _rx_buf_size(xport_params.recv_frame_size) +        , _next_recv_buff_index(0) +        , _next_send_buff_index(0)      {          UHD_ASSERT_THROW(xport_params.recv_frame_size > 0);          UHD_ASSERT_THROW(xport_params.send_frame_size > 0);          UHD_ASSERT_THROW(xport_params.num_send_frames > 0);          UHD_ASSERT_THROW(xport_params.num_recv_frames > 0); -        liberio_ctx *ctx = get_liberio_context_holder().get(); +        liberio_ctx* ctx = get_liberio_context_holder().get();          /* we hold a reference, that we'd drop immediately after,           * so no requirement to get another one here ...           */ -        _tx_chan = liberio_ctx_alloc_chan(ctx, tx_path.c_str(), TX, -                           USRP_MEMORY_MMAP); +        _tx_chan = liberio_ctx_alloc_chan(ctx, tx_path.c_str(), TX, USRP_MEMORY_MMAP);          UHD_ASSERT_THROW(_tx_chan);          liberio_chan_stop_streaming(_tx_chan);          liberio_chan_request_buffers(_tx_chan, 0);          UHD_ASSERT_THROW( -            !liberio_chan_set_fixed_size(_tx_chan, 0, -                xport_params.send_frame_size -            ) -        ); +            !liberio_chan_set_fixed_size(_tx_chan, 0, xport_params.send_frame_size));          UHD_ASSERT_THROW( -            !liberio_chan_request_buffers( -                _tx_chan, xport_params.num_send_frames -            ) -        ); +            !liberio_chan_request_buffers(_tx_chan, xport_params.num_send_frames));          _num_send_bufs = liberio_chan_get_num_bufs(_tx_chan);          for (size_t i = 0; i < xport_params.num_send_frames; i++) {              liberio_chan_get(_tx_chan); -            _msb_pool.push_back( -                boost::make_shared<liberio_zero_copy_msb>(_tx_chan)); +            _msb_pool.push_back(boost::make_shared<liberio_zero_copy_msb>(_tx_chan));          }          /* we hold a reference, that we'd drop immediately after,           * so no requirement to get another one here ...           */ -        _rx_chan = liberio_ctx_alloc_chan(ctx, rx_path.c_str(), -                          RX, USRP_MEMORY_MMAP); +        _rx_chan = liberio_ctx_alloc_chan(ctx, rx_path.c_str(), RX, USRP_MEMORY_MMAP);          UHD_ASSERT_THROW(_rx_chan);          /* done with the local reference, the channel keeps its own */ @@ -177,18 +173,14 @@ public:          liberio_chan_stop_streaming(_rx_chan);          liberio_chan_request_buffers(_rx_chan, 0);          UHD_ASSERT_THROW( -            !liberio_chan_set_fixed_size(_rx_chan, 0, -                xport_params.recv_frame_size -            ) -        ); -        UHD_ASSERT_THROW(!liberio_chan_request_buffers( -                _rx_chan, xport_params.num_recv_frames)); +            !liberio_chan_set_fixed_size(_rx_chan, 0, xport_params.recv_frame_size)); +        UHD_ASSERT_THROW( +            !liberio_chan_request_buffers(_rx_chan, xport_params.num_recv_frames));          _num_recv_bufs = liberio_chan_get_num_bufs(_rx_chan);          for (size_t i = 0; i < xport_params.num_recv_frames; i++) {              liberio_chan_get(_rx_chan); -            _mrb_pool.push_back( -                boost::make_shared<liberio_zero_copy_mrb>(_rx_chan)); +            _mrb_pool.push_back(boost::make_shared<liberio_zero_copy_mrb>(_rx_chan));          }          UHD_ASSERT_THROW(!liberio_chan_enqueue_all(_rx_chan)); @@ -208,8 +200,7 @@ public:          std::lock_guard<std::mutex> lock(_rx_mutex);          if (_next_recv_buff_index == _num_recv_bufs)              _next_recv_buff_index = 0; -        return _mrb_pool[_next_recv_buff_index]->get_new( -            timeout, _next_recv_buff_index); +        return _mrb_pool[_next_recv_buff_index]->get_new(timeout, _next_recv_buff_index);      }      size_t get_num_recv_frames(void) const @@ -223,12 +214,11 @@ public:      }      managed_send_buffer::sptr get_send_buff(double timeout = 0.1) -    {  +    {          std::lock_guard<std::mutex> lock(_tx_mutex);          if (_next_send_buff_index == _num_send_bufs)              _next_send_buff_index = 0; -        return _msb_pool[_next_send_buff_index]->get_new( -            timeout, _next_send_buff_index); +        return _msb_pool[_next_send_buff_index]->get_new(timeout, _next_send_buff_index);      }      size_t get_num_send_frames(void) const @@ -242,29 +232,27 @@ public:      }  private: -    liberio_chan *_tx_chan; +    liberio_chan* _tx_chan;      const size_t _tx_buf_size;      size_t _num_send_bufs; -    liberio_chan *_rx_chan; +    liberio_chan* _rx_chan;      const size_t _rx_buf_size;      size_t _num_recv_bufs; -    std::vector<boost::shared_ptr<liberio_zero_copy_mrb> > _mrb_pool; +    std::vector<boost::shared_ptr<liberio_zero_copy_mrb>> _mrb_pool;      size_t _next_recv_buff_index; -    std::vector<boost::shared_ptr<liberio_zero_copy_msb> > _msb_pool; +    std::vector<boost::shared_ptr<liberio_zero_copy_msb>> _msb_pool;      size_t _next_send_buff_index;      std::mutex _rx_mutex;      std::mutex _tx_mutex;  }; -liberio_zero_copy::sptr liberio_zero_copy::make( -    const std::string &tx_path, -    const std::string &rx_path, -    const zero_copy_xport_params &default_buff_args) +liberio_zero_copy::sptr liberio_zero_copy::make(const std::string& tx_path, +    const std::string& rx_path, +    const zero_copy_xport_params& default_buff_args)  {      return liberio_zero_copy::sptr( -        new liberio_zero_copy_impl(tx_path, rx_path, default_buff_args) -    ); +        new liberio_zero_copy_impl(tx_path, rx_path, default_buff_args));  } -}} +}} // namespace uhd::transport diff --git a/host/lib/transport/liberio_zero_copy.hpp b/host/lib/transport/liberio_zero_copy.hpp index 1dfa3af71..b41b6416c 100644 --- a/host/lib/transport/liberio_zero_copy.hpp +++ b/host/lib/transport/liberio_zero_copy.hpp @@ -8,30 +8,28 @@  #ifndef LIBERIO_HPP  #define LIBERIO_HPP -#include <string> -#include <vector> -  #include <uhd/config.hpp>  #include <uhd/transport/zero_copy.hpp>  #include <uhd/types/device_addr.hpp>  #include <boost/shared_ptr.hpp> +#include <string> +#include <vector>  namespace uhd { namespace transport {  /*!   * A zero copy transport interface to the liberio DMA library.   */ -class liberio_zero_copy : public virtual zero_copy_if { +class liberio_zero_copy : public virtual zero_copy_if +{  public:      typedef boost::shared_ptr<liberio_zero_copy> sptr; -    static sptr make( -        const std::string &tx_path, -        const std::string &rx_path, -        const zero_copy_xport_params &default_buff_args -    ); +    static sptr make(const std::string& tx_path, +        const std::string& rx_path, +        const zero_copy_xport_params& default_buff_args);  }; -}} +}} // namespace uhd::transport  #endif /* LIBERIO_HPP */ diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp index 03d99aa47..83d9fe1df 100644 --- a/host/lib/transport/libusb1_base.cpp +++ b/host/lib/transport/libusb1_base.cpp @@ -7,14 +7,13 @@  #include "libusb1_base.hpp"  #include <uhd/exception.hpp> - -#include <uhd/utils/log.hpp> -#include <uhd/utils/tasks.hpp>  #include <uhd/types/dict.hpp>  #include <uhd/types/serial.hpp> -#include <boost/weak_ptr.hpp> -#include <boost/thread/mutex.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/tasks.hpp>  #include <boost/bind.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/weak_ptr.hpp>  #include <cstdlib>  #include <iostream> @@ -24,75 +23,84 @@ using namespace uhd::transport;  /***********************************************************************   * libusb session   **********************************************************************/ -libusb::session::~session(void) { +libusb::session::~session(void) +{      /* NOP */  } -class libusb_session_impl : public libusb::session{ +class libusb_session_impl : public libusb::session +{  public: -    libusb_session_impl(void){ +    libusb_session_impl(void) +    {          UHD_ASSERT_THROW(libusb_init(&_context) == 0);          libusb_set_debug(_context, debug_level); -        task_handler = task::make(boost::bind(&libusb_session_impl::libusb_event_handler_task, this, _context)); +        task_handler = task::make( +            boost::bind(&libusb_session_impl::libusb_event_handler_task, this, _context));      }      virtual ~libusb_session_impl(void); -    libusb_context *get_context(void) const{ +    libusb_context* get_context(void) const +    {          return _context;      }  private: -    libusb_context *_context; +    libusb_context* _context;      task::sptr task_handler;      /* -     * Task to handle libusb events.  There should only be one thread per libusb_context handling events. -     * Using more than one thread can result in excessive CPU usage in kernel space (presumably from locking/waiting). -     * The libusb documentation says it is safe, which it is, but it neglects to state the cost in CPU usage. -     * Just don't do it! +     * Task to handle libusb events.  There should only be one thread per libusb_context +     * handling events. Using more than one thread can result in excessive CPU usage in +     * kernel space (presumably from locking/waiting). The libusb documentation says it is +     * safe, which it is, but it neglects to state the cost in CPU usage. Just don't do +     * it!       */ -    UHD_INLINE void libusb_event_handler_task(libusb_context *context) +    UHD_INLINE void libusb_event_handler_task(libusb_context* context)      {          timeval tv; -        tv.tv_sec = 0; +        tv.tv_sec  = 0;          tv.tv_usec = 100000; -        int ret = libusb_handle_events_timeout(context, &tv); -        switch (ret) -        { -        case LIBUSB_SUCCESS: -        case LIBUSB_ERROR_TIMEOUT: -            break; -        case LIBUSB_ERROR_NO_DEVICE: -            throw uhd::io_error(libusb_strerror(LIBUSB_ERROR_NO_DEVICE)); -        default: -            UHD_LOGGER_ERROR("USB") << __FUNCTION__ << ": " << libusb_strerror((libusb_error)ret) ; -            break; +        int ret    = libusb_handle_events_timeout(context, &tv); +        switch (ret) { +            case LIBUSB_SUCCESS: +            case LIBUSB_ERROR_TIMEOUT: +                break; +            case LIBUSB_ERROR_NO_DEVICE: +                throw uhd::io_error(libusb_strerror(LIBUSB_ERROR_NO_DEVICE)); +            default: +                UHD_LOGGER_ERROR("USB") +                    << __FUNCTION__ << ": " << libusb_strerror((libusb_error)ret); +                break;          }      }  }; -libusb_session_impl::~libusb_session_impl(void){ +libusb_session_impl::~libusb_session_impl(void) +{      task_handler.reset();      libusb_exit(_context);  } -libusb::session::sptr libusb::session::get_global_session(void){ +libusb::session::sptr libusb::session::get_global_session(void) +{      static boost::weak_ptr<session> global_session; -    //not expired -> get existing session -    if (not global_session.expired()) return global_session.lock(); +    // not expired -> get existing session +    if (not global_session.expired()) +        return global_session.lock(); -    //create a new global session +    // create a new global session      sptr new_global_session(new libusb_session_impl());      global_session = new_global_session; -    //set logging if envvar is set -    const char *level_string = getenv("LIBUSB_DEBUG_LEVEL"); -    if (level_string != NULL) -    { -        const int level = int(level_string[0] - '0'); //easy conversion to integer -        if (level >= 0 and level <= 3) libusb_set_debug(new_global_session->get_context(), level); +    // set logging if envvar is set +    const char* level_string = getenv("LIBUSB_DEBUG_LEVEL"); +    if (level_string != NULL) { +        const int level = int(level_string[0] - '0'); // easy conversion to integer +        if (level >= 0 and level <= 3) +            libusb_set_debug(new_global_session->get_context(), level);      }      return new_global_session; @@ -101,65 +109,75 @@ libusb::session::sptr libusb::session::get_global_session(void){  /***********************************************************************   * libusb device   **********************************************************************/ -libusb::device::~device(void) { +libusb::device::~device(void) +{      /* NOP */  } -class libusb_device_impl : public libusb::device{ +class libusb_device_impl : public libusb::device +{  public: -    libusb_device_impl(libusb_device *dev){ +    libusb_device_impl(libusb_device* dev) +    {          _session = libusb::session::get_global_session(); -        _dev = dev; +        _dev     = dev;      }      virtual ~libusb_device_impl(void); -    libusb_device *get(void) const{ +    libusb_device* get(void) const +    {          return _dev;      }  private: -    libusb::session::sptr _session; //always keep a reference to session -    libusb_device *_dev; +    libusb::session::sptr _session; // always keep a reference to session +    libusb_device* _dev;  }; -libusb_device_impl::~libusb_device_impl(void){ +libusb_device_impl::~libusb_device_impl(void) +{      libusb_unref_device(this->get());  }  /***********************************************************************   * libusb device list   **********************************************************************/ -libusb::device_list::~device_list(void){ +libusb::device_list::~device_list(void) +{      /* NOP */  } -class libusb_device_list_impl : public libusb::device_list{ +class libusb_device_list_impl : public libusb::device_list +{  public: -    libusb_device_list_impl(void){ +    libusb_device_list_impl(void) +    {          libusb::session::sptr sess = libusb::session::get_global_session(); -        //allocate a new list of devices +        // allocate a new list of devices          libusb_device** dev_list;          ssize_t ret = libusb_get_device_list(sess->get_context(), &dev_list); -        if (ret < 0) throw uhd::os_error("cannot enumerate usb devices"); +        if (ret < 0) +            throw uhd::os_error("cannot enumerate usb devices"); -        //fill the vector of device references -        for (size_t i = 0; i < size_t(ret); i++) _devs.push_back( -            libusb::device::sptr(new libusb_device_impl(dev_list[i])) -        ); +        // fill the vector of device references +        for (size_t i = 0; i < size_t(ret); i++) +            _devs.push_back(libusb::device::sptr(new libusb_device_impl(dev_list[i]))); -        //free the device list but dont unref (done in ~device) -        libusb_free_device_list(dev_list, false/*dont unref*/); +        // free the device list but dont unref (done in ~device) +        libusb_free_device_list(dev_list, false /*dont unref*/);      }      virtual ~libusb_device_list_impl(void); -    size_t size(void) const{ +    size_t size(void) const +    {          return _devs.size();      } -    libusb::device::sptr at(size_t i) const{ +    libusb::device::sptr at(size_t i) const +    {          return _devs.at(i);      } @@ -167,96 +185,113 @@ private:      std::vector<libusb::device::sptr> _devs;  }; -libusb_device_list_impl::~libusb_device_list_impl(void){ +libusb_device_list_impl::~libusb_device_list_impl(void) +{      /* NOP */  } -libusb::device_list::sptr libusb::device_list::make(void){ +libusb::device_list::sptr libusb::device_list::make(void) +{      return sptr(new libusb_device_list_impl());  }  /***********************************************************************   * libusb device descriptor   **********************************************************************/ -libusb::device_descriptor::~device_descriptor(void){ +libusb::device_descriptor::~device_descriptor(void) +{      /* NOP */  } -class libusb_device_descriptor_impl : public libusb::device_descriptor{ +class libusb_device_descriptor_impl : public libusb::device_descriptor +{  public: -    libusb_device_descriptor_impl(libusb::device::sptr dev){ +    libusb_device_descriptor_impl(libusb::device::sptr dev) +    {          _dev = dev;          UHD_ASSERT_THROW(libusb_get_device_descriptor(_dev->get(), &_desc) == 0);      }      virtual ~libusb_device_descriptor_impl(void); -    const libusb_device_descriptor &get(void) const{ +    const libusb_device_descriptor& get(void) const +    {          return _desc;      } -    std::string get_ascii_property(const std::string &what) const +    std::string get_ascii_property(const std::string& what) const      {          uint8_t off = 0; -        if (what == "serial") off = this->get().iSerialNumber; -        if (what == "product") off = this->get().iProduct; -        if (what == "manufacturer") off = this->get().iManufacturer; -        if (off == 0) return ""; +        if (what == "serial") +            off = this->get().iSerialNumber; +        if (what == "product") +            off = this->get().iProduct; +        if (what == "manufacturer") +            off = this->get().iManufacturer; +        if (off == 0) +            return "";          libusb::device_handle::sptr handle( -            libusb::device_handle::get_cached_handle(_dev) -        ); +            libusb::device_handle::get_cached_handle(_dev));          unsigned char buff[512];          int ret = libusb_get_string_descriptor_ascii( -            handle->get(), off, buff, int(sizeof(buff)) -        ); -        if (ret < 0) return ""; //on error, just return empty string +            handle->get(), off, buff, int(sizeof(buff))); +        if (ret < 0) +            return ""; // on error, just return empty string -        std::string string_descriptor((char *)buff, size_t(ret)); +        std::string string_descriptor((char*)buff, size_t(ret));          byte_vector_t string_vec(string_descriptor.begin(), string_descriptor.end());          std::string out; -        for(uint8_t byte:  string_vec){ -            if (byte < 32 or byte > 127) return out; +        for (uint8_t byte : string_vec) { +            if (byte < 32 or byte > 127) +                return out;              out += byte;          }          return out;      }  private: -    libusb::device::sptr _dev; //always keep a reference to device +    libusb::device::sptr _dev; // always keep a reference to device      libusb_device_descriptor _desc;  }; -libusb_device_descriptor_impl::~libusb_device_descriptor_impl(void){ +libusb_device_descriptor_impl::~libusb_device_descriptor_impl(void) +{      /* NOP */  } -libusb::device_descriptor::sptr libusb::device_descriptor::make(device::sptr dev){ +libusb::device_descriptor::sptr libusb::device_descriptor::make(device::sptr dev) +{      return sptr(new libusb_device_descriptor_impl(dev));  }  /***********************************************************************   * libusb device handle   **********************************************************************/ -libusb::device_handle::~device_handle(void){ +libusb::device_handle::~device_handle(void) +{      /* NOP */  } -class libusb_device_handle_impl : public libusb::device_handle{ +class libusb_device_handle_impl : public libusb::device_handle +{  public: -    libusb_device_handle_impl(libusb::device::sptr dev){ +    libusb_device_handle_impl(libusb::device::sptr dev) +    {          _dev = dev;          UHD_ASSERT_THROW(libusb_open(_dev->get(), &_handle) == 0);      }      virtual ~libusb_device_handle_impl(void); -    libusb_device_handle *get(void) const{ +    libusb_device_handle* get(void) const +    {          return _handle;      } -    void claim_interface(int interface){ +    void claim_interface(int interface) +    {          UHD_ASSERT_THROW(libusb_claim_interface(this->get(), interface) == 0);          _claimed.push_back(interface);      } @@ -264,59 +299,61 @@ public:      void clear_endpoints(unsigned char recv_endpoint, unsigned char send_endpoint)      {          int ret; -        ret = libusb_clear_halt(this->get(), recv_endpoint  | 0x80); -        UHD_LOGGER_TRACE("USB") << "usb device handle: recv endpoint clear: " << libusb_error_name(ret) ; +        ret = libusb_clear_halt(this->get(), recv_endpoint | 0x80); +        UHD_LOGGER_TRACE("USB") +            << "usb device handle: recv endpoint clear: " << libusb_error_name(ret);          ret = libusb_clear_halt(this->get(), send_endpoint | 0x00); -        UHD_LOGGER_TRACE("USB") << "usb device handle: send endpoint clear: " << libusb_error_name(ret) ; +        UHD_LOGGER_TRACE("USB") +            << "usb device handle: send endpoint clear: " << libusb_error_name(ret);      }      void reset_device(void)      {          int ret = libusb_reset_device(this->get()); -        UHD_LOGGER_TRACE("USB") << "usb device handle: dev Reset: " << libusb_error_name(ret) ; +        UHD_LOGGER_TRACE("USB") +            << "usb device handle: dev Reset: " << libusb_error_name(ret);      }  private: -    libusb::device::sptr _dev; //always keep a reference to device -    libusb_device_handle *_handle; +    libusb::device::sptr _dev; // always keep a reference to device +    libusb_device_handle* _handle;      std::vector<int> _claimed;  }; -libusb_device_handle_impl::~libusb_device_handle_impl(void){ -    //release all claimed interfaces -    for (size_t i = 0; i < _claimed.size(); i++){ +libusb_device_handle_impl::~libusb_device_handle_impl(void) +{ +    // release all claimed interfaces +    for (size_t i = 0; i < _claimed.size(); i++) {          libusb_release_interface(this->get(), _claimed[i]);      }      libusb_close(_handle);  } -libusb::device_handle::sptr libusb::device_handle::get_cached_handle(device::sptr dev){ -    static uhd::dict<libusb_device *, boost::weak_ptr<device_handle> > handles; +libusb::device_handle::sptr libusb::device_handle::get_cached_handle(device::sptr dev) +{ +    static uhd::dict<libusb_device*, boost::weak_ptr<device_handle>> handles; -    //lock for atomic access to static table above +    // lock for atomic access to static table above      static boost::mutex mutex;      boost::mutex::scoped_lock lock(mutex); -    //not expired -> get existing handle -    if (handles.has_key(dev->get()) and not handles[dev->get()].expired()){ +    // not expired -> get existing handle +    if (handles.has_key(dev->get()) and not handles[dev->get()].expired()) {          return handles[dev->get()].lock();      } -    //create a new cached handle -    try{ +    // create a new cached handle +    try {          sptr new_handle(new libusb_device_handle_impl(dev));          handles[dev->get()] = new_handle;          return new_handle; -    } -    catch(const uhd::exception &){ -        #ifdef UHD_PLATFORM_LINUX -        UHD_LOGGER_ERROR("USB") << -            "USB open failed: insufficient permissions.\n" -            "See the application notes for your device.\n" -        ; -        #else -        UHD_LOGGER_DEBUG("USB") << "USB open failed: device already claimed." ; -        #endif +    } catch (const uhd::exception&) { +#ifdef UHD_PLATFORM_LINUX +        UHD_LOGGER_ERROR("USB") << "USB open failed: insufficient permissions.\n" +                                   "See the application notes for your device.\n"; +#else +        UHD_LOGGER_DEBUG("USB") << "USB open failed: device already claimed."; +#endif          throw;      }  } @@ -324,85 +361,105 @@ libusb::device_handle::sptr libusb::device_handle::get_cached_handle(device::spt  /***********************************************************************   * libusb special handle   **********************************************************************/ -libusb::special_handle::~special_handle(void){ +libusb::special_handle::~special_handle(void) +{      /* NOP */  } -class libusb_special_handle_impl : public libusb::special_handle{ +class libusb_special_handle_impl : public libusb::special_handle +{  public: -    libusb_special_handle_impl(libusb::device::sptr dev){ +    libusb_special_handle_impl(libusb::device::sptr dev) +    {          _dev = dev;      }      virtual ~libusb_special_handle_impl(void); -    libusb::device::sptr get_device(void) const{ +    libusb::device::sptr get_device(void) const +    {          return _dev;      } -    std::string get_serial(void) const{ -        return libusb::device_descriptor::make(this->get_device())->get_ascii_property("serial"); +    std::string get_serial(void) const +    { +        return libusb::device_descriptor::make(this->get_device()) +            ->get_ascii_property("serial");      } -    std::string get_manufacturer() const{ -        return libusb::device_descriptor::make(this->get_device())->get_ascii_property("manufacturer"); +    std::string get_manufacturer() const +    { +        return libusb::device_descriptor::make(this->get_device()) +            ->get_ascii_property("manufacturer");      } -    std::string get_product() const{ -        return libusb::device_descriptor::make(this->get_device())->get_ascii_property("product"); +    std::string get_product() const +    { +        return libusb::device_descriptor::make(this->get_device()) +            ->get_ascii_property("product");      } -    uint16_t get_vendor_id(void) const{ +    uint16_t get_vendor_id(void) const +    {          return libusb::device_descriptor::make(this->get_device())->get().idVendor;      } -    uint16_t get_product_id(void) const{ +    uint16_t get_product_id(void) const +    {          return libusb::device_descriptor::make(this->get_device())->get().idProduct;      } -    bool firmware_loaded() { -        return (get_manufacturer() == "Ettus Research LLC") or -               (get_manufacturer() == "National Instruments Corp.") or -               (get_manufacturer() == "Free Software Folks"); +    bool firmware_loaded() +    { +        return (get_manufacturer() == "Ettus Research LLC") +               or (get_manufacturer() == "National Instruments Corp.") +               or (get_manufacturer() == "Free Software Folks");      }  private: -    libusb::device::sptr _dev; //always keep a reference to device +    libusb::device::sptr _dev; // always keep a reference to device  }; -libusb_special_handle_impl::~libusb_special_handle_impl(void){ +libusb_special_handle_impl::~libusb_special_handle_impl(void) +{      /* NOP */  } -libusb::special_handle::sptr libusb::special_handle::make(device::sptr dev){ +libusb::special_handle::sptr libusb::special_handle::make(device::sptr dev) +{      return sptr(new libusb_special_handle_impl(dev));  }  /***********************************************************************   * list device handles implementations   **********************************************************************/ -usb_device_handle::~usb_device_handle(void) { +usb_device_handle::~usb_device_handle(void) +{      /* NOP */  }  std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list( -    uint16_t vid, uint16_t pid -){ -    return usb_device_handle::get_device_list(std::vector<usb_device_handle::vid_pid_pair_t>(1,usb_device_handle::vid_pid_pair_t(vid,pid))); +    uint16_t vid, uint16_t pid) +{ +    return usb_device_handle::get_device_list( +        std::vector<usb_device_handle::vid_pid_pair_t>( +            1, usb_device_handle::vid_pid_pair_t(vid, pid)));  } -std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list) +std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list( +    const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list)  {      std::vector<usb_device_handle::sptr> handles;      libusb::device_list::sptr dev_list = libusb::device_list::make(); -    for(size_t iter = 0; iter < vid_pid_pair_list.size(); ++iter) -    { -       for (size_t i = 0; i < dev_list->size(); i++){ -           usb_device_handle::sptr handle = libusb::special_handle::make(dev_list->at(i)); -           if (handle->get_vendor_id() == vid_pid_pair_list[iter].first and handle->get_product_id() == vid_pid_pair_list[iter].second){ -               handles.push_back(handle); -           } -       } +    for (size_t iter = 0; iter < vid_pid_pair_list.size(); ++iter) { +        for (size_t i = 0; i < dev_list->size(); i++) { +            usb_device_handle::sptr handle = +                libusb::special_handle::make(dev_list->at(i)); +            if (handle->get_vendor_id() == vid_pid_pair_list[iter].first +                and handle->get_product_id() == vid_pid_pair_list[iter].second) { +                handles.push_back(handle); +            } +        }      }      return handles;  } diff --git a/host/lib/transport/libusb1_base.hpp b/host/lib/transport/libusb1_base.hpp index 958248a5c..8ff1cf4cc 100644 --- a/host/lib/transport/libusb1_base.hpp +++ b/host/lib/transport/libusb1_base.hpp @@ -9,32 +9,30 @@  #define INCLUDED_LIBUHD_TRANSPORT_LIBUSB_HPP  #include <uhd/config.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp>  #include <uhd/transport/usb_device_handle.hpp>  #include <libusb.h> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp>  //! Define LIBUSB_CALL when its missing (non-windows)  #ifndef LIBUSB_CALL -    #define LIBUSB_CALL +#    define LIBUSB_CALL  #endif /*LIBUSB_CALL*/  //! libusb_handle_events_timeout_completed is only in newer API  #ifndef HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED -    #define libusb_handle_events_timeout_completed(ctx, tx, completed) \ +#    define libusb_handle_events_timeout_completed(ctx, tx, completed) \          libusb_handle_events_timeout(ctx, tx)  #endif /* HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED */  //! libusb_error_name is only in newer API  #ifndef HAVE_LIBUSB_ERROR_NAME -    #define libusb_error_name(code) \ -        str(boost::format("LIBUSB_ERROR_CODE %d") % code) +#    define libusb_error_name(code) str(boost::format("LIBUSB_ERROR_CODE %d") % code)  #endif /* HAVE_LIBUSB_ERROR_NAME */  //! libusb_strerror is only in newer API  #ifndef HAVE_LIBUSB_STRERROR -    #define libusb_strerror(code) \ -        libusb_error_name(code) +#    define libusb_strerror(code) libusb_error_name(code)  #endif /* HAVE_LIBUSB_STRERROR */  /*********************************************************************** @@ -44,135 +42,138 @@   * also store tables of already allocated structures to avoid multiple   * occurrences of opened handles (for example).   **********************************************************************/ -namespace uhd { namespace transport { - -namespace libusb { - -    /*! -     * This session class holds a global libusb context for this process. -     * The get global session call will create a new context if none exists. -     * When all references to session are destroyed, the context will be freed. -     */ -    class session : boost::noncopyable { -    public: -        typedef boost::shared_ptr<session> sptr; - -        virtual ~session(void); +namespace uhd { namespace transport { namespace libusb { -        /*! -         *   Level 0: no messages ever printed by the library (default) -         *   Level 1: error messages are printed to stderr -         *   Level 2: warning and error messages are printed to stderr -         *   Level 3: informational messages are printed to stdout, warning -         *            and error messages are printed to stderr -         */ -        static const int debug_level = 0; +/*! + * This session class holds a global libusb context for this process. + * The get global session call will create a new context if none exists. + * When all references to session are destroyed, the context will be freed. + */ +class session : boost::noncopyable +{ +public: +    typedef boost::shared_ptr<session> sptr; -        //! get a shared pointer to the global session -        static sptr get_global_session(void); - -        //! get the underlying libusb context pointer -        virtual libusb_context *get_context(void) const = 0; -    }; +    virtual ~session(void);      /*! -     * Holds a device pointer with a reference to the session. +     *   Level 0: no messages ever printed by the library (default) +     *   Level 1: error messages are printed to stderr +     *   Level 2: warning and error messages are printed to stderr +     *   Level 3: informational messages are printed to stdout, warning +     *            and error messages are printed to stderr       */ -    class device : boost::noncopyable { -    public: -        typedef boost::shared_ptr<device> sptr; +    static const int debug_level = 0; -        virtual ~device(void); +    //! get a shared pointer to the global session +    static sptr get_global_session(void); -        //! get the underlying device pointer -        virtual libusb_device *get(void) const = 0; -    }; +    //! get the underlying libusb context pointer +    virtual libusb_context* get_context(void) const = 0; +}; -    /*! -     * This device list class holds a device list that will be -     * automatically freed when the last reference is destroyed. -     */ -    class device_list : boost::noncopyable { -    public: -        typedef boost::shared_ptr<device_list> sptr; +/*! + * Holds a device pointer with a reference to the session. + */ +class device : boost::noncopyable +{ +public: +    typedef boost::shared_ptr<device> sptr; -        virtual ~device_list(void); +    virtual ~device(void); -        //! make a new device list -        static sptr make(void); +    //! get the underlying device pointer +    virtual libusb_device* get(void) const = 0; +}; -        //! the number of devices in this list -        virtual size_t size() const = 0; +/*! + * This device list class holds a device list that will be + * automatically freed when the last reference is destroyed. + */ +class device_list : boost::noncopyable +{ +public: +    typedef boost::shared_ptr<device_list> sptr; -        //! get the device pointer at a particular index -        virtual device::sptr at(size_t index) const = 0; -    }; +    virtual ~device_list(void); -    /*! -     * Holds a device descriptor and a reference to the device. -     */ -    class device_descriptor : boost::noncopyable { -    public: -        typedef boost::shared_ptr<device_descriptor> sptr; +    //! make a new device list +    static sptr make(void); -        virtual ~device_descriptor(void); +    //! the number of devices in this list +    virtual size_t size() const = 0; -        //! make a new descriptor from a device reference -        static sptr make(device::sptr); +    //! get the device pointer at a particular index +    virtual device::sptr at(size_t index) const = 0; +}; -        //! get the underlying device descriptor -        virtual const libusb_device_descriptor &get(void) const = 0; +/*! + * Holds a device descriptor and a reference to the device. + */ +class device_descriptor : boost::noncopyable +{ +public: +    typedef boost::shared_ptr<device_descriptor> sptr; -        virtual std::string get_ascii_property(const std::string &what) const = 0; -    }; +    virtual ~device_descriptor(void); -    /*! -     * Holds a device handle and a reference to the device. -     */ -    class device_handle : boost::noncopyable { -    public: -        typedef boost::shared_ptr<device_handle> sptr; +    //! make a new descriptor from a device reference +    static sptr make(device::sptr); -        virtual ~device_handle(void); +    //! get the underlying device descriptor +    virtual const libusb_device_descriptor& get(void) const = 0; -        //! get a cached handle or make a new one given the device -        static sptr get_cached_handle(device::sptr); +    virtual std::string get_ascii_property(const std::string& what) const = 0; +}; -        //! get the underlying device handle -        virtual libusb_device_handle *get(void) const = 0; +/*! + * Holds a device handle and a reference to the device. + */ +class device_handle : boost::noncopyable +{ +public: +    typedef boost::shared_ptr<device_handle> sptr; -        /*! -         * Open USB interfaces for control using magic value -         * IN interface:      2 -         * OUT interface:     1 -         * Control interface: 0 -         */ -        virtual void claim_interface(int) = 0; +    virtual ~device_handle(void); -        virtual void clear_endpoints(unsigned char recv_endpoint, unsigned char send_endpoint) = 0; +    //! get a cached handle or make a new one given the device +    static sptr get_cached_handle(device::sptr); -        virtual void reset_device(void) = 0; -    }; +    //! get the underlying device handle +    virtual libusb_device_handle* get(void) const = 0;      /*! -     * The special handle is our internal implementation of the -     * usb device handle which is used publicly to identify a device. +     * Open USB interfaces for control using magic value +     * IN interface:      2 +     * OUT interface:     1 +     * Control interface: 0       */ -    class special_handle : public usb_device_handle { -    public: -        typedef boost::shared_ptr<special_handle> sptr; +    virtual void claim_interface(int) = 0; + +    virtual void clear_endpoints( +        unsigned char recv_endpoint, unsigned char send_endpoint) = 0; + +    virtual void reset_device(void) = 0; +}; -        virtual ~special_handle(void); +/*! + * The special handle is our internal implementation of the + * usb device handle which is used publicly to identify a device. + */ +class special_handle : public usb_device_handle +{ +public: +    typedef boost::shared_ptr<special_handle> sptr; -        //! make a new special handle from device -        static sptr make(device::sptr); +    virtual ~special_handle(void); -        //! get the underlying device reference -        virtual device::sptr get_device(void) const = 0; -    }; +    //! make a new special handle from device +    static sptr make(device::sptr); -} +    //! get the underlying device reference +    virtual device::sptr get_device(void) const = 0; +}; -}} //namespace +}}} // namespace uhd::transport::libusb  #endif /* INCLUDED_LIBUHD_TRANSPORT_LIBUSB_HPP */ diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp index 2a338bba1..10ab53553 100644 --- a/host/lib/transport/libusb1_control.cpp +++ b/host/lib/transport/libusb1_control.cpp @@ -11,17 +11,19 @@  using namespace uhd::transport; -usb_control::~usb_control(void){ +usb_control::~usb_control(void) +{      /* NOP */  }  /***********************************************************************   * libusb-1.0 implementation of USB control transport   **********************************************************************/ -class libusb_control_impl : public usb_control { +class libusb_control_impl : public usb_control +{  public: -    libusb_control_impl(libusb::device_handle::sptr handle, const int interface): -        _handle(handle) +    libusb_control_impl(libusb::device_handle::sptr handle, const int interface) +        : _handle(handle)      {          _handle->claim_interface(interface);      } @@ -29,22 +31,22 @@ public:      virtual ~libusb_control_impl(void);      int submit(uint8_t request_type, -               uint8_t request, -               uint16_t value, -               uint16_t index, -               unsigned char *buff, -               uint16_t length, -               uint32_t libusb_timeout = 0 -    ){ +        uint8_t request, +        uint16_t value, +        uint16_t index, +        unsigned char* buff, +        uint16_t length, +        uint32_t libusb_timeout = 0) +    {          boost::mutex::scoped_lock lock(_mutex);          return libusb_control_transfer(_handle->get(), -                                       request_type, -                                       request, -                                       value, -                                       index, -                                       buff, -                                       length, -                                       libusb_timeout); +            request_type, +            request, +            value, +            index, +            buff, +            length, +            libusb_timeout);      }  private: @@ -52,15 +54,18 @@ private:      boost::mutex _mutex;  }; -libusb_control_impl::~libusb_control_impl(void)  { -  /* NOP */ +libusb_control_impl::~libusb_control_impl(void) +{ +    /* NOP */  }  /***********************************************************************   * USB control public make functions   **********************************************************************/ -usb_control::sptr usb_control::make(usb_device_handle::sptr handle, const int interface){ -    return sptr(new libusb_control_impl(libusb::device_handle::get_cached_handle( -        boost::static_pointer_cast<libusb::special_handle>(handle)->get_device() -    ), interface)); +usb_control::sptr usb_control::make(usb_device_handle::sptr handle, const int interface) +{ +    return sptr(new libusb_control_impl( +        libusb::device_handle::get_cached_handle( +            boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()), +        interface));  } diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 9e91ae2fc..5b03aa86f 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -6,35 +6,35 @@  //  #include "libusb1_base.hpp" -#include <uhd/transport/usb_zero_copy.hpp> -#include <uhd/transport/buffer_pool.hpp> +#include <uhd/exception.hpp>  #include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/buffer_pool.hpp> +#include <uhd/transport/usb_zero_copy.hpp>  #include <uhd/utils/log.hpp> -#include <uhd/exception.hpp> +#include <boost/bind.hpp> +#include <boost/circular_buffer.hpp>  #include <boost/format.hpp>  #include <boost/function.hpp> -#include <boost/bind.hpp>  #include <boost/make_shared.hpp> -#include <boost/circular_buffer.hpp> -#include <boost/thread/mutex.hpp>  #include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp>  #include <list>  #ifdef UHD_TXRX_DEBUG_PRINTS -#include <vector> -#include <fstream> -#include <boost/format.hpp> +#    include <boost/format.hpp> +#    include <fstream> +#    include <vector>  #endif  using namespace uhd;  using namespace uhd::transport; -static const size_t DEFAULT_NUM_XFERS = 16;     //num xfers -static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes +static const size_t DEFAULT_NUM_XFERS = 16; // num xfers +static const size_t DEFAULT_XFER_SIZE = 32 * 512; // bytes  //! type for sharing the release queue with managed buffers  class libusb_zero_copy_mb; -typedef boost::shared_ptr<bounded_buffer<libusb_zero_copy_mb *> > mb_queue_sptr; +typedef boost::shared_ptr<bounded_buffer<libusb_zero_copy_mb*>> mb_queue_sptr;  /*!   * The libusb docs state that status and actual length can only be read in the callback. @@ -44,12 +44,12 @@ struct lut_result_t  {      lut_result_t(void)      { -        completed = 0; -        status = LIBUSB_TRANSFER_COMPLETED; +        completed     = 0; +        status        = LIBUSB_TRANSFER_COMPLETED;          actual_length = 0;  #ifdef UHD_TXRX_DEBUG_PRINTS          start_time = 0; -        buff_num = -1; +        buff_num   = -1;  #endif      }      int completed; @@ -67,17 +67,22 @@ struct lut_result_t  };  // Created to be used as an argument to boost::condition_variable::timed_wait() function -struct lut_result_completed { +struct lut_result_completed +{      const lut_result_t& _result; -    lut_result_completed(const lut_result_t& result):_result(result) {} -    bool operator()() const {return (_result.completed ? true : false);} +    lut_result_completed(const lut_result_t& result) : _result(result) {} +    bool operator()() const +    { +        return (_result.completed ? true : false); +    }  };  #ifdef UHD_TXRX_DEBUG_PRINTS  static std::string dbg_prefix("libusb1_zero_copy,"); -static void libusb1_zerocopy_dbg_print_err(std::string msg){ -	msg = dbg_prefix + msg; -	fprintf(stderr, "%s\n", msg.c_str()); +static void libusb1_zerocopy_dbg_print_err(std::string msg) +{ +    msg = dbg_prefix + msg; +    fprintf(stderr, "%s\n", msg.c_str());  }  #endif @@ -87,17 +92,21 @@ static void libusb1_zerocopy_dbg_print_err(std::string msg){   */  //! helper function: handles all async callbacks -static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut) +static void LIBUSB_CALL libusb_async_cb(libusb_transfer* lut)  { -    lut_result_t *r = (lut_result_t *)lut->user_data; +    lut_result_t* r = (lut_result_t*)lut->user_data;      boost::lock_guard<boost::mutex> lock(r->mut); -    r->status = lut->status; +    r->status        = lut->status;      r->actual_length = lut->actual_length; -    r->completed = 1; -    r->usb_transfer_complete.notify_one();  // wake up thread waiting in wait_for_completion() member function below +    r->completed     = 1; +    r->usb_transfer_complete.notify_one(); // wake up thread waiting in +                                           // wait_for_completion() member function below  #ifdef UHD_TXRX_DEBUG_PRINTS      long end_time = boost::get_system_time().time_of_day().total_microseconds(); -    libusb1_zerocopy_dbg_print_err( (boost::format("libusb_async_cb,%s,%i,%i,%i,%ld,%ld") % (r->is_recv ? "rx":"tx") % r->buff_num % r->actual_length % r->status % end_time % r->start_time).str() ); +    libusb1_zerocopy_dbg_print_err( +        (boost::format("libusb_async_cb,%s,%i,%i,%i,%ld,%ld") % (r->is_recv ? "rx" : "tx") +            % r->buff_num % r->actual_length % r->status % end_time % r->start_time) +            .str());  #endif  } @@ -109,41 +118,53 @@ static void LIBUSB_CALL libusb_async_cb(libusb_transfer *lut)  class libusb_zero_copy_mb : public managed_buffer  {  public: -    libusb_zero_copy_mb(libusb_transfer *lut, const size_t frame_size, boost::function<void(libusb_zero_copy_mb *)> release_cb, const bool is_recv, const std::string &name): -        _release_cb(release_cb), _is_recv(is_recv), _name(name), -        _ctx(libusb::session::get_global_session()->get_context()), -        _lut(lut), _frame_size(frame_size) { /* NOP */ } +    libusb_zero_copy_mb(libusb_transfer* lut, +        const size_t frame_size, +        boost::function<void(libusb_zero_copy_mb*)> release_cb, +        const bool is_recv, +        const std::string& name) +        : _release_cb(release_cb) +        , _is_recv(is_recv) +        , _name(name) +        , _ctx(libusb::session::get_global_session()->get_context()) +        , _lut(lut) +        , _frame_size(frame_size) +    { /* NOP */ +    }      virtual ~libusb_zero_copy_mb(void); -    void release(void){ -    	_release_cb(this); +    void release(void) +    { +        _release_cb(this);      }      UHD_INLINE void submit(void)      { -        _lut->length = int((_is_recv)? _frame_size : size()); //always set length +        _lut->length = int((_is_recv) ? _frame_size : size()); // always set length  #ifdef UHD_TXRX_DEBUG_PRINTS          result.start_time = boost::get_system_time().time_of_day().total_microseconds(); -        result.buff_num = num(); -        result.is_recv = _is_recv; +        result.buff_num   = num(); +        result.is_recv    = _is_recv;  #endif -	int ret = libusb_submit_transfer(_lut); +        int ret = libusb_submit_transfer(_lut);          if (ret != LIBUSB_SUCCESS) -	  throw uhd::usb_error(ret, str(boost::format( -            "usb %s submit failed: %s") % _name % libusb_error_name(ret))); +            throw uhd::usb_error(ret, +                str(boost::format("usb %s submit failed: %s") % _name +                    % libusb_error_name(ret)));      }      template <typename buffer_type>      UHD_INLINE typename buffer_type::sptr get_new(const double timeout)      { -        if (wait_for_completion(timeout)) -        { +        if (wait_for_completion(timeout)) {              if (result.status != LIBUSB_TRANSFER_COMPLETED)                  throw uhd::io_error(str(boost::format("usb %s transfer status: %d")                                          % _name % libusb_error_name(result.status)));              result.completed = 0; -            return make(reinterpret_cast<buffer_type *>(this), _lut->buffer, (_is_recv)? size_t(result.actual_length) : _frame_size); +            return make(reinterpret_cast<buffer_type*>(this), +                _lut->buffer, +                (_is_recv) ? size_t(result.actual_length) : _frame_size);          }          return typename buffer_type::sptr();      } @@ -164,23 +185,27 @@ public:              if (timeout < 0.0) {                  result.usb_transfer_complete.wait(lock);              } else { -                const boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::microseconds(long(timeout*1000000)); -                result.usb_transfer_complete.timed_wait(lock, timeout_time, lut_result_completed(result)); +                const boost::system_time timeout_time = +                    boost::get_system_time() +                    + boost::posix_time::microseconds(long(timeout * 1000000)); +                result.usb_transfer_complete.timed_wait( +                    lock, timeout_time, lut_result_completed(result));              }          }          return (result.completed > 0);      }  private: -    boost::function<void(libusb_zero_copy_mb *)> _release_cb; +    boost::function<void(libusb_zero_copy_mb*)> _release_cb;      const bool _is_recv;      const std::string _name; -    libusb_context *_ctx; -    libusb_transfer *_lut; +    libusb_context* _ctx; +    libusb_transfer* _lut;      const size_t _frame_size;  }; -libusb_zero_copy_mb::~libusb_zero_copy_mb(void) { +libusb_zero_copy_mb::~libusb_zero_copy_mb(void) +{      /* NOP */  } @@ -190,70 +215,71 @@ libusb_zero_copy_mb::~libusb_zero_copy_mb(void) {  class libusb_zero_copy_single  {  public: -    libusb_zero_copy_single( -        libusb::device_handle::sptr handle, -        const int interface, const unsigned char endpoint, -        const size_t num_frames, const size_t frame_size -    ): -        _handle(handle), -        _num_frames(num_frames), -        _frame_size(frame_size), -        _buffer_pool(buffer_pool::make(_num_frames, _frame_size)), -        _enqueued(_num_frames), _released(_num_frames), -        _status(STATUS_RUNNING) +    libusb_zero_copy_single(libusb::device_handle::sptr handle, +        const int interface, +        const unsigned char endpoint, +        const size_t num_frames, +        const size_t frame_size) +        : _handle(handle) +        , _num_frames(num_frames) +        , _frame_size(frame_size) +        , _buffer_pool(buffer_pool::make(_num_frames, _frame_size)) +        , _enqueued(_num_frames) +        , _released(_num_frames) +        , _status(STATUS_RUNNING)      {          const bool is_recv = (endpoint & 0x80) != 0; -        const std::string name = str(boost::format("%s%d") % ((is_recv)? "rx" : "tx") % int(endpoint & 0x7f)); +        const std::string name = +            str(boost::format("%s%d") % ((is_recv) ? "rx" : "tx") % int(endpoint & 0x7f));          _handle->claim_interface(interface); -        //flush the buffers out of the recv endpoint -        //limit the flushing to at most one second -        if (is_recv) for (size_t i = 0; i < 100; i++) -        { -            unsigned char buff[512]; -            int transfered = 0; -            const int status = libusb_bulk_transfer( -                _handle->get(), // dev_handle -                endpoint, // endpoint -                static_cast<unsigned char *>(buff), -                int(sizeof(buff)), -                &transfered, //bytes xfered -                10 //timeout ms -            ); -            if (status == LIBUSB_ERROR_TIMEOUT) break; -        } +        // flush the buffers out of the recv endpoint +        // limit the flushing to at most one second +        if (is_recv) +            for (size_t i = 0; i < 100; i++) { +                unsigned char buff[512]; +                int transfered   = 0; +                const int status = libusb_bulk_transfer(_handle->get(), // dev_handle +                    endpoint, // endpoint +                    static_cast<unsigned char*>(buff), +                    int(sizeof(buff)), +                    &transfered, // bytes xfered +                    10 // timeout ms +                ); +                if (status == LIBUSB_ERROR_TIMEOUT) +                    break; +            } -        //allocate libusb transfer structs and managed buffers -        for (size_t i = 0; i < get_num_frames(); i++) -        { -            libusb_transfer *lut = libusb_alloc_transfer(0); +        // allocate libusb transfer structs and managed buffers +        for (size_t i = 0; i < get_num_frames(); i++) { +            libusb_transfer* lut = libusb_alloc_transfer(0);              UHD_ASSERT_THROW(lut != NULL); -            _mb_pool.push_back(boost::make_shared<libusb_zero_copy_mb>( -                lut, this->get_frame_size(), boost::bind(&libusb_zero_copy_single::enqueue_buffer, this, _1), is_recv, name -            )); - -            libusb_fill_bulk_transfer( -                lut,                                                    // transfer -                _handle->get(),                                         // dev_handle -                endpoint,                                               // endpoint -                static_cast<unsigned char *>(_buffer_pool->at(i)),      // buffer -                int(this->get_frame_size()),                            // length -                libusb_transfer_cb_fn(&libusb_async_cb),                // callback -                static_cast<void *>(&_mb_pool.back()->result),          // user_data -                0                                                       // timeout (ms) +            _mb_pool.push_back(boost::make_shared<libusb_zero_copy_mb>(lut, +                this->get_frame_size(), +                boost::bind(&libusb_zero_copy_single::enqueue_buffer, this, _1), +                is_recv, +                name)); + +            libusb_fill_bulk_transfer(lut, // transfer +                _handle->get(), // dev_handle +                endpoint, // endpoint +                static_cast<unsigned char*>(_buffer_pool->at(i)), // buffer +                int(this->get_frame_size()), // length +                libusb_transfer_cb_fn(&libusb_async_cb), // callback +                static_cast<void*>(&_mb_pool.back()->result), // user_data +                0 // timeout (ms)              );              _all_luts.push_back(lut);          } -        //initial release for all buffers -        for (size_t i = 0; i < get_num_frames(); i++) -        { -            libusb_zero_copy_mb &mb = *(_mb_pool[i]); -            if (is_recv) mb.release(); -            else -            { +        // initial release for all buffers +        for (size_t i = 0; i < get_num_frames(); i++) { +            libusb_zero_copy_mb& mb = *(_mb_pool[i]); +            if (is_recv) +                mb.release(); +            else {                  mb.result.completed = 1;                  _enqueued.push_back(&mb);              } @@ -262,21 +288,18 @@ public:      ~libusb_zero_copy_single(void)      { -        //cancel all transfers -        for(libusb_transfer *lut:  _all_luts) -        { +        // cancel all transfers +        for (libusb_transfer* lut : _all_luts) {              libusb_cancel_transfer(lut);          } -        //process all transfers until timeout occurs -        for(libusb_zero_copy_mb *mb:  _enqueued) -        { +        // process all transfers until timeout occurs +        for (libusb_zero_copy_mb* mb : _enqueued) {              mb->wait_for_completion(0.01);          } -        //free all transfers -        for(libusb_transfer *lut:  _all_luts) -        { +        // free all transfers +        for (libusb_transfer* lut : _all_luts) {              libusb_free_transfer(lut);          }      } @@ -293,24 +316,32 @@ public:          boost::mutex::scoped_lock get_buff_lock(_get_buff_mutex);          boost::mutex::scoped_lock queue_lock(_queue_mutex); -        if (_enqueued.empty()) -        { -            _buff_ready_cond.timed_wait(queue_lock, boost::posix_time::microseconds(long(timeout*1e6))); +        if (_enqueued.empty()) { +            _buff_ready_cond.timed_wait( +                queue_lock, boost::posix_time::microseconds(long(timeout * 1e6)));          } -        if (_enqueued.empty()) return buff; -        libusb_zero_copy_mb *front = _enqueued.front(); +        if (_enqueued.empty()) +            return buff; +        libusb_zero_copy_mb* front = _enqueued.front();          queue_lock.unlock();          buff = front->get_new<buffer_type>(timeout);          queue_lock.lock(); -        if (buff) _enqueued.pop_front(); +        if (buff) +            _enqueued.pop_front();          this->submit_what_we_can();          return buff;      } -    UHD_INLINE size_t get_num_frames(void) const { return _num_frames; } -    UHD_INLINE size_t get_frame_size(void) const { return _frame_size; } +    UHD_INLINE size_t get_num_frames(void) const +    { +        return _num_frames; +    } +    UHD_INLINE size_t get_frame_size(void) const +    { +        return _frame_size; +    }  private:      libusb::device_handle::sptr _handle; @@ -318,18 +349,18 @@ private:      //! Storage for transfer related objects      buffer_pool::sptr _buffer_pool; -    std::vector<boost::shared_ptr<libusb_zero_copy_mb> > _mb_pool; +    std::vector<boost::shared_ptr<libusb_zero_copy_mb>> _mb_pool;      boost::mutex _queue_mutex;      boost::condition_variable _buff_ready_cond;      boost::mutex _get_buff_mutex;      //! why 2 queues? there is room in the future to have > N buffers but only N in flight -    boost::circular_buffer<libusb_zero_copy_mb *> _enqueued, _released; +    boost::circular_buffer<libusb_zero_copy_mb*> _enqueued, _released; -    enum {STATUS_RUNNING, STATUS_ERROR} _status; +    enum { STATUS_RUNNING, STATUS_ERROR } _status; -    void enqueue_buffer(libusb_zero_copy_mb *mb) +    void enqueue_buffer(libusb_zero_copy_mb* mb)      {          boost::mutex::scoped_lock l(_queue_mutex);          _released.push_back(mb); @@ -341,15 +372,12 @@ private:      {          if (_status == STATUS_ERROR)              return; -        while (not _released.empty() and not _enqueued.full()) -        { +        while (not _released.empty() and not _enqueued.full()) {              try {                  _released.front()->submit();                  _enqueued.push_back(_released.front());                  _released.pop_front(); -            } -            catch (uhd::usb_error& e) -            { +            } catch (uhd::usb_error& e) {                  _status = STATUS_ERROR;                  throw e;              } @@ -357,7 +385,7 @@ private:      }      //! a list of all transfer structs we allocated -    std::list<libusb_transfer *> _all_luts; +    std::list<libusb_transfer*> _all_luts;  };  /*********************************************************************** @@ -365,20 +393,21 @@ private:   **********************************************************************/  struct libusb_zero_copy_impl : usb_zero_copy  { -    libusb_zero_copy_impl( -        libusb::device_handle::sptr handle, +    libusb_zero_copy_impl(libusb::device_handle::sptr handle,          const int recv_interface,          const unsigned char recv_endpoint,          const int send_interface,          const unsigned char send_endpoint, -        const device_addr_t &hints -    ){ -        _recv_impl.reset(new libusb_zero_copy_single( -            handle, recv_interface, (recv_endpoint & 0x7f) | 0x80, +        const device_addr_t& hints) +    { +        _recv_impl.reset(new libusb_zero_copy_single(handle, +            recv_interface, +            (recv_endpoint & 0x7f) | 0x80,              size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_XFERS)),              size_t(hints.cast<double>("recv_frame_size", DEFAULT_XFER_SIZE)))); -        _send_impl.reset(new libusb_zero_copy_single( -            handle, send_interface, (send_endpoint & 0x7f) | 0x00, +        _send_impl.reset(new libusb_zero_copy_single(handle, +            send_interface, +            (send_endpoint & 0x7f) | 0x00,              size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_XFERS)),              size_t(hints.cast<double>("send_frame_size", DEFAULT_XFER_SIZE))));      } @@ -397,42 +426,53 @@ struct libusb_zero_copy_impl : usb_zero_copy          return _send_impl->get_buff<managed_send_buffer>(timeout);      } -    size_t get_num_recv_frames(void) const { return _recv_impl->get_num_frames(); } -    size_t get_num_send_frames(void) const { return _send_impl->get_num_frames(); } +    size_t get_num_recv_frames(void) const +    { +        return _recv_impl->get_num_frames(); +    } +    size_t get_num_send_frames(void) const +    { +        return _send_impl->get_num_frames(); +    } -    size_t get_recv_frame_size(void) const { return _recv_impl->get_frame_size(); } -    size_t get_send_frame_size(void) const { return _send_impl->get_frame_size(); } +    size_t get_recv_frame_size(void) const +    { +        return _recv_impl->get_frame_size(); +    } +    size_t get_send_frame_size(void) const +    { +        return _send_impl->get_frame_size(); +    }      boost::shared_ptr<libusb_zero_copy_single> _recv_impl, _send_impl;      boost::mutex _recv_mutex, _send_mutex;  }; -libusb_zero_copy_impl::~libusb_zero_copy_impl(void) { +libusb_zero_copy_impl::~libusb_zero_copy_impl(void) +{      /* NOP */  }  /***********************************************************************   * USB zero_copy destructor   **********************************************************************/ -usb_zero_copy::~usb_zero_copy(void) { +usb_zero_copy::~usb_zero_copy(void) +{      /* NOP */  }  /***********************************************************************   * USB zero_copy make functions   **********************************************************************/ -usb_zero_copy::sptr usb_zero_copy::make( -    usb_device_handle::sptr handle, +usb_zero_copy::sptr usb_zero_copy::make(usb_device_handle::sptr handle,      const int recv_interface,      const unsigned char recv_endpoint,      const int send_interface,      const unsigned char send_endpoint, -    const device_addr_t &hints -){ +    const device_addr_t& hints) +{      libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle( -        boost::static_pointer_cast<libusb::special_handle>(handle)->get_device() -    )); +        boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()));      return sptr(new libusb_zero_copy_impl( -        dev_handle, recv_interface, recv_endpoint, send_interface, send_endpoint, hints -    )); +        dev_handle, recv_interface, recv_endpoint, send_interface, send_endpoint, hints));  } diff --git a/host/lib/transport/muxed_zero_copy_if.cpp b/host/lib/transport/muxed_zero_copy_if.cpp index 2e7583276..b26d2097c 100644 --- a/host/lib/transport/muxed_zero_copy_if.cpp +++ b/host/lib/transport/muxed_zero_copy_if.cpp @@ -5,73 +5,75 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <uhd/transport/muxed_zero_copy_if.hpp> -#include <uhd/transport/bounded_buffer.hpp>  #include <uhd/exception.hpp> +#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/muxed_zero_copy_if.hpp>  #include <uhd/utils/safe_call.hpp>  #include <boost/enable_shared_from_this.hpp>  #include <boost/make_shared.hpp>  #include <boost/thread.hpp>  #include <boost/thread/locks.hpp> -#include <map>  #include <chrono> +#include <map>  #include <thread>  using namespace uhd;  using namespace uhd::transport; -class muxed_zero_copy_if_impl : public muxed_zero_copy_if, -                                public boost::enable_shared_from_this<muxed_zero_copy_if_impl> +class muxed_zero_copy_if_impl +    : public muxed_zero_copy_if, +      public boost::enable_shared_from_this<muxed_zero_copy_if_impl>  {  public:      typedef boost::shared_ptr<muxed_zero_copy_if_impl> sptr; -    muxed_zero_copy_if_impl( -        zero_copy_if::sptr base_xport, +    muxed_zero_copy_if_impl(zero_copy_if::sptr base_xport,          stream_classifier_fn classify_fn, -        size_t max_streams -    ): -        _base_xport(base_xport), _classify(classify_fn), -        _max_num_streams(max_streams), _num_dropped_frames(0) +        size_t max_streams) +        : _base_xport(base_xport) +        , _classify(classify_fn) +        , _max_num_streams(max_streams) +        , _num_dropped_frames(0)      { -        //Create the receive thread to poll the underlying transport -        //and classify packets into queues -        _recv_thread = boost::thread( -            boost::bind(&muxed_zero_copy_if_impl::_update_queues, this)); +        // Create the receive thread to poll the underlying transport +        // and classify packets into queues +        _recv_thread = +            boost::thread(boost::bind(&muxed_zero_copy_if_impl::_update_queues, this));      }      virtual ~muxed_zero_copy_if_impl()      {          UHD_SAFE_CALL( -            //Interrupt buffer updater loop +            // Interrupt buffer updater loop              _recv_thread.interrupt(); -            //Wait for loop to finish -            //No timeout on join. The recv loop is guaranteed -            //to terminate in a reasonable amount of time because -            //there are no timed blocks on the underlying. +            // Wait for loop to finish +            // No timeout on join. The recv loop is guaranteed +            // to terminate in a reasonable amount of time because +            // there are no timed blocks on the underlying.              _recv_thread.join(); -            //Flush base transport +            // Flush base transport              while (_base_xport->get_recv_buff(0.0001)) /*NOP*/; -            //Release child streams -            //Note that this will not delete or flush the child streams -            //until the owners of the streams have released the respective -            //shared pointers. This ensures that packets are not dropped. -            _streams.clear(); -        ); +            // Release child streams +            // Note that this will not delete or flush the child streams +            // until the owners of the streams have released the respective +            // shared pointers. This ensures that packets are not dropped. +            _streams.clear(););      }      virtual zero_copy_if::sptr make_stream(const uint32_t stream_num)      {          boost::lock_guard<boost::mutex> lock(_mutex);          if (_streams.size() >= _max_num_streams) { -            throw uhd::runtime_error("muxed_zero_copy_if: stream capacity exceeded. cannot create more streams."); +            throw uhd::runtime_error("muxed_zero_copy_if: stream capacity exceeded. " +                                     "cannot create more streams.");          }          // Only allocate a portion of the base transport's frames to each stream          // to prevent all streams from attempting to use all the frames. -        stream_impl::sptr stream = boost::make_shared<stream_impl>( -            this->shared_from_this(), stream_num, -            _base_xport->get_num_send_frames() / _max_num_streams, -            _base_xport->get_num_recv_frames() / _max_num_streams); +        stream_impl::sptr stream = +            boost::make_shared<stream_impl>(this->shared_from_this(), +                stream_num, +                _base_xport->get_num_send_frames() / _max_num_streams, +                _base_xport->get_num_recv_frames() / _max_num_streams);          _streams[stream_num] = stream;          return stream;      } @@ -97,20 +99,21 @@ private:      public:          stream_mrb(size_t size) : _buff(new char[size]) {} -        ~stream_mrb() { +        ~stream_mrb() +        {              delete[] _buff;          }          void release() {} -        UHD_INLINE sptr get_new(char *buff, size_t len) +        UHD_INLINE sptr get_new(char* buff, size_t len)          {              memcpy(_buff, buff, len);              return make(this, _buff, len);          }      private: -        char *_buff; +        char* _buff;      };      class stream_impl : public zero_copy_if @@ -119,20 +122,19 @@ private:          typedef boost::shared_ptr<stream_impl> sptr;          typedef boost::weak_ptr<stream_impl> wptr; -        stream_impl( -            muxed_zero_copy_if_impl::sptr muxed_xport, +        stream_impl(muxed_zero_copy_if_impl::sptr muxed_xport,              const uint32_t stream_num,              const size_t num_send_frames, -            const size_t num_recv_frames -            ) : -            _stream_num(stream_num), _muxed_xport(muxed_xport), -            _num_send_frames(num_send_frames), -            _send_frame_size(_muxed_xport->base_xport()->get_send_frame_size()), -            _num_recv_frames(num_recv_frames), -            _recv_frame_size(_muxed_xport->base_xport()->get_recv_frame_size()), -            _buff_queue(num_recv_frames), -            _buffers(num_recv_frames), -            _buffer_index(0) +            const size_t num_recv_frames) +            : _stream_num(stream_num) +            , _muxed_xport(muxed_xport) +            , _num_send_frames(num_send_frames) +            , _send_frame_size(_muxed_xport->base_xport()->get_send_frame_size()) +            , _num_recv_frames(num_recv_frames) +            , _recv_frame_size(_muxed_xport->base_xport()->get_recv_frame_size()) +            , _buff_queue(num_recv_frames) +            , _buffers(num_recv_frames) +            , _buffer_index(0)          {              for (size_t i = 0; i < num_recv_frames; i++) {                  _buffers[i] = boost::make_shared<stream_mrb>(_recv_frame_size); @@ -141,25 +143,28 @@ private:          ~stream_impl(void)          { -            //First remove the stream from muxed transport -            //so no more frames are pushed in +            // First remove the stream from muxed transport +            // so no more frames are pushed in              _muxed_xport->remove_stream(_stream_num); -            //Flush the transport +            // Flush the transport              managed_recv_buffer::sptr buff;              while (_buff_queue.pop_with_haste(buff)) { -                //NOP +                // NOP              }          } -        size_t get_num_recv_frames(void) const { +        size_t get_num_recv_frames(void) const +        {              return _num_recv_frames;          } -        size_t get_recv_frame_size(void) const { +        size_t get_recv_frame_size(void) const +        {              return _recv_frame_size;          } -        managed_recv_buffer::sptr get_recv_buff(double timeout) { +        managed_recv_buffer::sptr get_recv_buff(double timeout) +        {              managed_recv_buffer::sptr buff;              if (_buff_queue.pop_with_timed_wait(buff, timeout)) {                  return buff; @@ -168,16 +173,20 @@ private:              }          } -        void push_recv_buff(managed_recv_buffer::sptr buff) { -            _buff_queue.push_with_wait(_buffers.at(_buffer_index++)->get_new(buff->cast<char*>(), buff->size())); +        void push_recv_buff(managed_recv_buffer::sptr buff) +        { +            _buff_queue.push_with_wait( +                _buffers.at(_buffer_index++)->get_new(buff->cast<char*>(), buff->size()));              _buffer_index %= _buffers.size();          } -        size_t get_num_send_frames(void) const { +        size_t get_num_send_frames(void) const +        {              return _num_send_frames;          } -        size_t get_send_frame_size(void) const { +        size_t get_send_frame_size(void) const +        {              return _send_frame_size;          } @@ -187,51 +196,55 @@ private:          }      private: -        const uint32_t                              _stream_num; -        muxed_zero_copy_if_impl::sptr               _muxed_xport; -        const size_t                                _num_send_frames; -        const size_t                                _send_frame_size; -        const size_t                                _num_recv_frames; -        const size_t                                _recv_frame_size; -        bounded_buffer<managed_recv_buffer::sptr>   _buff_queue; -        std::vector< boost::shared_ptr<stream_mrb> >    _buffers; -        size_t                                      _buffer_index; +        const uint32_t _stream_num; +        muxed_zero_copy_if_impl::sptr _muxed_xport; +        const size_t _num_send_frames; +        const size_t _send_frame_size; +        const size_t _num_recv_frames; +        const size_t _recv_frame_size; +        bounded_buffer<managed_recv_buffer::sptr> _buff_queue; +        std::vector<boost::shared_ptr<stream_mrb>> _buffers; +        size_t _buffer_index;      }; -    inline zero_copy_if::sptr& base_xport() { return _base_xport; } +    inline zero_copy_if::sptr& base_xport() +    { +        return _base_xport; +    }      void _update_queues()      { -        //Run forever: +        // Run forever:          // - Pull packets from the base transport          // - Classify them          // - Push them to the appropriate receive queue          while (true) { -            {   //Uninterruptable block of code +            { // Uninterruptable block of code                  boost::this_thread::disable_interruption interrupt_disabler;                  if (not _process_next_buffer()) { -                    //Be a good citizen and yield if no packet is processed +                    // Be a good citizen and yield if no packet is processed                      static const size_t MIN_DUR = 1;                      std::this_thread::sleep_for(std::chrono::nanoseconds(MIN_DUR)); -                    //We call sleep(MIN_DUR) above instead of yield() to ensure that we -                    //relinquish the current scheduler time slot. -                    //yield() is a hint to the scheduler to end the time -                    //slice early and schedule in another thread that is ready to run. -                    //However in most situations, there will be no other thread and -                    //this thread will continue to run which will rail a CPU core. -                    //We call sleep(MIN_DUR=1) instead which will sleep for a minimum time. -                    //Ideally we would like to use boost::chrono::.*seconds::min() but that -                    //is bound to 0, which causes the sleep_for call to be a no-op and -                    //thus useless to actually force a sleep. +                    // We call sleep(MIN_DUR) above instead of yield() to ensure that we +                    // relinquish the current scheduler time slot. +                    // yield() is a hint to the scheduler to end the time +                    // slice early and schedule in another thread that is ready to run. +                    // However in most situations, there will be no other thread and +                    // this thread will continue to run which will rail a CPU core. +                    // We call sleep(MIN_DUR=1) instead which will sleep for a minimum +                    // time. Ideally we would like to use boost::chrono::.*seconds::min() +                    // but that is bound to 0, which causes the sleep_for call to be a +                    // no-op and thus useless to actually force a sleep.                      //**************************************************************** -                    //NOTE: This behavior makes this transport a poor choice for +                    // NOTE: This behavior makes this transport a poor choice for                      //      low latency communication.                      //****************************************************************                  }              } -            //Check if the master thread has requested a shutdown -            if (boost::this_thread::interruption_requested()) break; +            // Check if the master thread has requested a shutdown +            if (boost::this_thread::interruption_requested()) +                break;          }      } @@ -241,10 +254,11 @@ private:          if (buff) {              stream_impl::sptr stream;              try { -                const uint32_t stream_num = _classify(buff->cast<void*>(), _base_xport->get_recv_frame_size()); +                const uint32_t stream_num = +                    _classify(buff->cast<void*>(), _base_xport->get_recv_frame_size());                  { -                    //Hold the stream mutex long enough to pull a bounded buffer -                    //and lock it (increment its ref count). +                    // Hold the stream mutex long enough to pull a bounded buffer +                    // and lock it (increment its ref count).                      boost::lock_guard<boost::mutex> lock(_mutex);                      stream_map_t::iterator str_iter = _streams.find(stream_num);                      if (str_iter != _streams.end()) { @@ -252,41 +266,41 @@ private:                      }                  }              } catch (std::exception&) { -                //If _classify throws we simply drop the frame +                // If _classify throws we simply drop the frame              } -            //Once a bounded buffer is acquired, we can rely on its -            //thread safety to serialize with the consumer. +            // Once a bounded buffer is acquired, we can rely on its +            // thread safety to serialize with the consumer.              if (stream.get()) {                  stream->push_recv_buff(buff);              } else {                  boost::lock_guard<boost::mutex> lock(_mutex);                  _num_dropped_frames++;              } -            //We processed a packet, and there could be more coming -            //Don't yield in the next iteration. +            // We processed a packet, and there could be more coming +            // Don't yield in the next iteration.              return true;          } else { -            //The base transport is idle. Return false to let the -            //thread yield. +            // The base transport is idle. Return false to let the +            // thread yield.              return false;          }      }      typedef std::map<uint32_t, stream_impl::wptr> stream_map_t; -    zero_copy_if::sptr      _base_xport; -    stream_classifier_fn    _classify; -    stream_map_t            _streams; -    const size_t            _max_num_streams; -    size_t                  _num_dropped_frames; -    boost::thread           _recv_thread; -    boost::mutex            _mutex; +    zero_copy_if::sptr _base_xport; +    stream_classifier_fn _classify; +    stream_map_t _streams; +    const size_t _max_num_streams; +    size_t _num_dropped_frames; +    boost::thread _recv_thread; +    boost::mutex _mutex;  }; -muxed_zero_copy_if::sptr muxed_zero_copy_if::make( -    zero_copy_if::sptr base_xport, +muxed_zero_copy_if::sptr muxed_zero_copy_if::make(zero_copy_if::sptr base_xport,      muxed_zero_copy_if::stream_classifier_fn classify_fn, -    size_t max_streams -) { -    return boost::make_shared<muxed_zero_copy_if_impl>(base_xport, classify_fn, max_streams); +    size_t max_streams) +{ +    return boost::make_shared<muxed_zero_copy_if_impl>( +        base_xport, classify_fn, max_streams);  } diff --git a/host/lib/transport/nirio_zero_copy.cpp b/host/lib/transport/nirio_zero_copy.cpp index 993a2c593..e72064427 100644 --- a/host/lib/transport/nirio_zero_copy.cpp +++ b/host/lib/transport/nirio_zero_copy.cpp @@ -5,25 +5,25 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <uhd/transport/nirio_zero_copy.hpp>  #include <uhd/transport/nirio/nirio_fifo.h> +#include <uhd/transport/nirio_zero_copy.hpp>  #include <uhd/utils/log.hpp>  #include <uhdlib/utils/atomic.hpp> +#include <stdio.h> +#include <boost/date_time/posix_time/posix_time.hpp>  #include <boost/format.hpp> +#include <boost/interprocess/mapped_region.hpp> //get_page_size()  #include <boost/make_shared.hpp> -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/interprocess/mapped_region.hpp>	//get_page_size() -#include <vector> -#include <algorithm>    // std::max +#include <algorithm> // std::max  #include <chrono>  #include <thread> -#include <stdio.h> +#include <vector>  //@TODO: Move the register defs required by the class to a common location  #include "../usrp/x300/x300_regs.hpp"  #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -#include <windows.h> +#    include <windows.h>  static UHD_INLINE size_t get_page_size()  {      SYSTEM_INFO si; @@ -31,7 +31,7 @@ static UHD_INLINE size_t get_page_size()      return si.dwPageSize;  }  #else -#include <unistd.h> +#    include <unistd.h>  static UHD_INLINE size_t get_page_size()  {      return size_t(sysconf(_SC_PAGESIZE)); @@ -48,153 +48,172 @@ typedef uint64_t fifo_data_t;  class nirio_zero_copy_mrb : public managed_recv_buffer  {  public: -    nirio_zero_copy_mrb(nirio_fifo<fifo_data_t>& fifo, const size_t frame_size): -        _fifo(fifo), _frame_size(frame_size) { } +    nirio_zero_copy_mrb(nirio_fifo<fifo_data_t>& fifo, const size_t frame_size) +        : _fifo(fifo), _frame_size(frame_size) +    { +    }      void release(void)      {          _fifo.release(_frame_size / sizeof(fifo_data_t));      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index) +    UHD_INLINE sptr get_new(const double timeout, size_t& index)      { -        nirio_status status = 0; -        size_t elems_acquired = 0; +        nirio_status status    = 0; +        size_t elems_acquired  = 0;          size_t elems_remaining = 0; -        nirio_status_chain(_fifo.acquire( -            _typed_buffer, _frame_size / sizeof(fifo_data_t), -            static_cast<uint32_t>(timeout*1000), -            elems_acquired, elems_remaining), status); +        nirio_status_chain(_fifo.acquire(_typed_buffer, +                               _frame_size / sizeof(fifo_data_t), +                               static_cast<uint32_t>(timeout * 1000), +                               elems_acquired, +                               elems_remaining), +            status);          _length = elems_acquired * sizeof(fifo_data_t);          _buffer = static_cast<void*>(_typed_buffer);          if (nirio_status_not_fatal(status)) { -            index++;        //Advances the caller's buffer +            index++; // Advances the caller's buffer              return make(this, _buffer, _length);          } else if (status == NiRio_Status_CommunicationTimeout) {              nirio_status_to_exception(status, "NI-RIO PCIe data transfer failed.");              return sptr();          } else { -            return sptr();  //NULL for timeout or error. +            return sptr(); // NULL for timeout or error.          }      }  private: -    nirio_fifo<fifo_data_t>&    _fifo; -    fifo_data_t*                _typed_buffer; -    const size_t                _frame_size; +    nirio_fifo<fifo_data_t>& _fifo; +    fifo_data_t* _typed_buffer; +    const size_t _frame_size;  };  class nirio_zero_copy_msb : public managed_send_buffer  {  public: -    nirio_zero_copy_msb(nirio_fifo<fifo_data_t>& fifo, const size_t frame_size): -        _fifo(fifo), _frame_size(frame_size) { } +    nirio_zero_copy_msb(nirio_fifo<fifo_data_t>& fifo, const size_t frame_size) +        : _fifo(fifo), _frame_size(frame_size) +    { +    }      void release(void)      {          _fifo.release(_frame_size / sizeof(fifo_data_t));      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index) +    UHD_INLINE sptr get_new(const double timeout, size_t& index)      { -        nirio_status status = 0; -        size_t elems_acquired = 0; +        nirio_status status    = 0; +        size_t elems_acquired  = 0;          size_t elems_remaining = 0; -        nirio_status_chain(_fifo.acquire( -            _typed_buffer, _frame_size / sizeof(fifo_data_t), -            static_cast<uint32_t>(timeout*1000), -            elems_acquired, elems_remaining), status); +        nirio_status_chain(_fifo.acquire(_typed_buffer, +                               _frame_size / sizeof(fifo_data_t), +                               static_cast<uint32_t>(timeout * 1000), +                               elems_acquired, +                               elems_remaining), +            status);          _length = elems_acquired * sizeof(fifo_data_t);          _buffer = static_cast<void*>(_typed_buffer);          if (nirio_status_not_fatal(status)) { -            index++;        //Advances the caller's buffer +            index++; // Advances the caller's buffer              return make(this, _buffer, _length);          } else if (status == NiRio_Status_CommunicationTimeout) {              nirio_status_to_exception(status, "NI-RIO PCIe data transfer failed.");              return sptr();          } else { -            return sptr();  //NULL for timeout or error. +            return sptr(); // NULL for timeout or error.          }      }  private: -    nirio_fifo<fifo_data_t>&    _fifo; -    fifo_data_t*                _typed_buffer; -    const size_t                _frame_size; +    nirio_fifo<fifo_data_t>& _fifo; +    fifo_data_t* _typed_buffer; +    const size_t _frame_size;  }; -class nirio_zero_copy_impl : public nirio_zero_copy { +class nirio_zero_copy_impl : public nirio_zero_copy +{  public:      typedef boost::shared_ptr<nirio_zero_copy_impl> sptr; -    nirio_zero_copy_impl( -        uhd::niusrprio::niusrprio_session::sptr fpga_session, +    nirio_zero_copy_impl(uhd::niusrprio::niusrprio_session::sptr fpga_session,          uint32_t instance, -        const zero_copy_xport_params& xport_params -    ): -        _fpga_session(fpga_session), -        _fifo_instance(instance), -        _xport_params(xport_params), -        _next_recv_buff_index(0), _next_send_buff_index(0) +        const zero_copy_xport_params& xport_params) +        : _fpga_session(fpga_session) +        , _fifo_instance(instance) +        , _xport_params(xport_params) +        , _next_recv_buff_index(0) +        , _next_send_buff_index(0)      { -        UHD_LOGGER_TRACE("NIRIO") << boost::format("Creating PCIe transport for channel %d") % instance ; -        UHD_LOGGER_TRACE("NIRIO") << boost::format("nirio zero-copy RX transport configured with frame size = %u, #frames = %u, buffer size = %u\n") -                    % _xport_params.recv_frame_size % _xport_params.num_recv_frames % -                    (_xport_params.recv_frame_size * _xport_params.num_recv_frames); -        UHD_LOGGER_TRACE("NIRIO") << boost::format("nirio zero-copy TX transport configured with frame size = %u, #frames = %u, buffer size = %u\n") -                    % _xport_params.send_frame_size % _xport_params.num_send_frames % (_xport_params.send_frame_size * _xport_params.num_send_frames); +        UHD_LOGGER_TRACE("NIRIO") +            << boost::format("Creating PCIe transport for channel %d") % instance; +        UHD_LOGGER_TRACE("NIRIO") +            << boost::format("nirio zero-copy RX transport configured with frame size = " +                             "%u, #frames = %u, buffer size = %u\n") +                   % _xport_params.recv_frame_size % _xport_params.num_recv_frames +                   % (_xport_params.recv_frame_size * _xport_params.num_recv_frames); +        UHD_LOGGER_TRACE("NIRIO") +            << boost::format("nirio zero-copy TX transport configured with frame size = " +                             "%u, #frames = %u, buffer size = %u\n") +                   % _xport_params.send_frame_size % _xport_params.num_send_frames +                   % (_xport_params.send_frame_size * _xport_params.num_send_frames);          nirio_status status = 0;          size_t actual_depth = 0, actual_size = 0; -        //Disable DMA streams in case last shutdown was unclean (cleanup, so don't status chain) -        _proxy()->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED); -        _proxy()->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED); +        // Disable DMA streams in case last shutdown was unclean (cleanup, so don't status +        // chain) +        _proxy()->poke( +            PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED); +        _proxy()->poke( +            PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);          _wait_until_stream_ready(); -        //Configure frame width +        // Configure frame width          nirio_status_chain(              _proxy()->poke(PCIE_TX_DMA_REG(DMA_FRAME_SIZE_REG, _fifo_instance), -                          static_cast<uint32_t>(_xport_params.send_frame_size/sizeof(fifo_data_t))), +                static_cast<uint32_t>( +                    _xport_params.send_frame_size / sizeof(fifo_data_t))),              status);          nirio_status_chain(              _proxy()->poke(PCIE_RX_DMA_REG(DMA_FRAME_SIZE_REG, _fifo_instance), -                          static_cast<uint32_t>(_xport_params.recv_frame_size/sizeof(fifo_data_t))), +                static_cast<uint32_t>( +                    _xport_params.recv_frame_size / sizeof(fifo_data_t))),              status); -        //Config 32-bit word flipping and enable DMA streams +        // Config 32-bit word flipping and enable DMA streams          nirio_status_chain(              _proxy()->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), -                          DMA_CTRL_SW_BUF_U32 | DMA_CTRL_ENABLED), +                DMA_CTRL_SW_BUF_U32 | DMA_CTRL_ENABLED),              status);          nirio_status_chain(              _proxy()->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), -                          DMA_CTRL_SW_BUF_U32 | DMA_CTRL_ENABLED), +                DMA_CTRL_SW_BUF_U32 | DMA_CTRL_ENABLED),              status); -        //Create FIFOs +        // Create FIFOs          nirio_status_chain( -            _fpga_session->create_rx_fifo(_fifo_instance, _recv_fifo), -            status); +            _fpga_session->create_rx_fifo(_fifo_instance, _recv_fifo), status);          nirio_status_chain( -            _fpga_session->create_tx_fifo(_fifo_instance, _send_fifo), -            status); +            _fpga_session->create_tx_fifo(_fifo_instance, _send_fifo), status);          if ((_recv_fifo.get() != NULL) && (_send_fifo.get() != NULL)) { -            //Initialize FIFOs -            nirio_status_chain( -                _recv_fifo->initialize( -                    (_xport_params.recv_frame_size*_xport_params.num_recv_frames)/sizeof(fifo_data_t), -                    _xport_params.recv_frame_size / sizeof(fifo_data_t), -                    actual_depth, actual_size), +            // Initialize FIFOs +            nirio_status_chain(_recv_fifo->initialize((_xport_params.recv_frame_size +                                                          * _xport_params.num_recv_frames) +                                                          / sizeof(fifo_data_t), +                                   _xport_params.recv_frame_size / sizeof(fifo_data_t), +                                   actual_depth, +                                   actual_size),                  status); -            nirio_status_chain( -                _send_fifo->initialize( -                    (_xport_params.send_frame_size*_xport_params.num_send_frames)/sizeof(fifo_data_t), -                    _xport_params.send_frame_size / sizeof(fifo_data_t), -                    actual_depth, actual_size), +            nirio_status_chain(_send_fifo->initialize((_xport_params.send_frame_size +                                                          * _xport_params.num_send_frames) +                                                          / sizeof(fifo_data_t), +                                   _xport_params.send_frame_size / sizeof(fifo_data_t), +                                   actual_depth, +                                   actual_size),                  status);              _proxy()->get_rio_quirks().add_tx_fifo(_fifo_instance); @@ -203,16 +222,16 @@ public:              nirio_status_chain(_send_fifo->start(), status);              if (nirio_status_not_fatal(status)) { -                //allocate re-usable managed receive buffers -                for (size_t i = 0; i < get_num_recv_frames(); i++){ -                    _mrb_pool.push_back(boost::shared_ptr<nirio_zero_copy_mrb>(new nirio_zero_copy_mrb( -                        *_recv_fifo, get_recv_frame_size()))); +                // allocate re-usable managed receive buffers +                for (size_t i = 0; i < get_num_recv_frames(); i++) { +                    _mrb_pool.push_back(boost::shared_ptr<nirio_zero_copy_mrb>( +                        new nirio_zero_copy_mrb(*_recv_fifo, get_recv_frame_size())));                  } -                //allocate re-usable managed send buffers -                for (size_t i = 0; i < get_num_send_frames(); i++){ -                    _msb_pool.push_back(boost::shared_ptr<nirio_zero_copy_msb>(new nirio_zero_copy_msb( -                        *_send_fifo, get_send_frame_size()))); +                // allocate re-usable managed send buffers +                for (size_t i = 0; i < get_num_send_frames(); i++) { +                    _msb_pool.push_back(boost::shared_ptr<nirio_zero_copy_msb>( +                        new nirio_zero_copy_msb(*_send_fifo, get_send_frame_size())));                  }              }          } else { @@ -226,14 +245,16 @@ public:      {          _proxy()->get_rio_quirks().remove_tx_fifo(_fifo_instance); -        //Disable DMA streams (cleanup, so don't status chain) -        _proxy()->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED); -        _proxy()->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED); +        // Disable DMA streams (cleanup, so don't status chain) +        _proxy()->poke( +            PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED); +        _proxy()->poke( +            PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);          _flush_rx_buff(); -        //Stop DMA channels. Stop is called in the fifo dtor but -        //it doesn't hurt to do it here. +        // Stop DMA channels. Stop is called in the fifo dtor but +        // it doesn't hurt to do it here.          _send_fifo->stop();          _recv_fifo->stop();      } @@ -244,12 +265,19 @@ public:       ******************************************************************/      managed_recv_buffer::sptr get_recv_buff(double timeout)      { -        if (_next_recv_buff_index == _xport_params.num_recv_frames) _next_recv_buff_index = 0; +        if (_next_recv_buff_index == _xport_params.num_recv_frames) +            _next_recv_buff_index = 0;          return _mrb_pool[_next_recv_buff_index]->get_new(timeout, _next_recv_buff_index);      } -    size_t get_num_recv_frames(void) const {return _xport_params.num_recv_frames;} -    size_t get_recv_frame_size(void) const {return _xport_params.recv_frame_size;} +    size_t get_num_recv_frames(void) const +    { +        return _xport_params.num_recv_frames; +    } +    size_t get_recv_frame_size(void) const +    { +        return _xport_params.recv_frame_size; +    }      /*******************************************************************       * Send implementation: @@ -257,16 +285,25 @@ public:       ******************************************************************/      managed_send_buffer::sptr get_send_buff(double timeout)      { -        if (_next_send_buff_index == _xport_params.num_send_frames) _next_send_buff_index = 0; +        if (_next_send_buff_index == _xport_params.num_send_frames) +            _next_send_buff_index = 0;          return _msb_pool[_next_send_buff_index]->get_new(timeout, _next_send_buff_index);      } -    size_t get_num_send_frames(void) const {return _xport_params.num_send_frames;} -    size_t get_send_frame_size(void) const {return _xport_params.send_frame_size;} +    size_t get_num_send_frames(void) const +    { +        return _xport_params.num_send_frames; +    } +    size_t get_send_frame_size(void) const +    { +        return _xport_params.send_frame_size; +    }  private: - -    UHD_INLINE niriok_proxy::sptr _proxy() { return _fpga_session->get_kernel_proxy(); } +    UHD_INLINE niriok_proxy::sptr _proxy() +    { +        return _fpga_session->get_kernel_proxy(); +    }      UHD_INLINE void _flush_rx_buff()      { @@ -275,21 +312,19 @@ private:          // repeatedly with the number of remaining elements          // until the buffer is empty          for (size_t num_elems_requested = 0, -            num_elems_acquired = 0, -            num_elems_remaining = 1; -            num_elems_remaining; -            num_elems_requested = num_elems_remaining) -        { +                    num_elems_acquired  = 0, +                    num_elems_remaining = 1; +             num_elems_remaining; +             num_elems_requested = num_elems_remaining) {              fifo_data_t* elems_buffer = NULL; -            nirio_status status = _recv_fifo->acquire( -                elems_buffer, +            nirio_status status       = _recv_fifo->acquire(elems_buffer,                  num_elems_requested, -                0,                      // timeout +                0, // timeout                  num_elems_acquired,                  num_elems_remaining);              // throw excetption if status is fatal -            nirio_status_to_exception(status, -                "NI-RIO PCIe data transfer failed during flush."); +            nirio_status_to_exception( +                status, "NI-RIO PCIe data transfer failed during flush.");              _recv_fifo->release(num_elems_acquired);          }      } @@ -304,44 +339,52 @@ private:          boost::posix_time::time_duration elapsed;          nirio_status status = NiRio_Status_Success; -        nirio_status_chain(_proxy()->peek( -            PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); +        nirio_status_chain( +            _proxy()->peek( +                PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), +            status);          tx_busy = (reg_data & DMA_STATUS_BUSY) > 0; -        nirio_status_chain(_proxy()->peek( -            PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); +        nirio_status_chain( +            _proxy()->peek( +                PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), +            status);          rx_busy = (reg_data & DMA_STATUS_BUSY) > 0;          if (nirio_status_not_fatal(status) && (tx_busy || rx_busy)) {              start_time = boost::posix_time::microsec_clock::local_time();              do { -                std::this_thread::sleep_for(std::chrono::microseconds(50)); //Avoid flooding the bus +                std::this_thread::sleep_for( +                    std::chrono::microseconds(50)); // Avoid flooding the bus                  elapsed = boost::posix_time::microsec_clock::local_time() - start_time; -                nirio_status_chain(_proxy()->peek( -                    PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); +                nirio_status_chain( +                    _proxy()->peek( +                        PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), +                    status);                  tx_busy = (reg_data & DMA_STATUS_BUSY) > 0; -                nirio_status_chain(_proxy()->peek( -                    PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status); +                nirio_status_chain( +                    _proxy()->peek( +                        PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), +                    status);                  rx_busy = (reg_data & DMA_STATUS_BUSY) > 0; -            } while ( -                nirio_status_not_fatal(status) && -                (tx_busy || rx_busy) && -                elapsed.total_milliseconds() < TIMEOUT_IN_MS); +            } while (nirio_status_not_fatal(status) && (tx_busy || rx_busy) +                     && elapsed.total_milliseconds() < TIMEOUT_IN_MS);              if (tx_busy || rx_busy) {                  nirio_status_chain(NiRio_Status_FpgaBusy, status);              } -            nirio_status_to_exception(status, "Could not create nirio_zero_copy transport."); +            nirio_status_to_exception( +                status, "Could not create nirio_zero_copy transport.");          }      } -    //memory management -> buffers and fifos +    // memory management -> buffers and fifos      niusrprio::niusrprio_session::sptr _fpga_session;      uint32_t _fifo_instance;      nirio_fifo<fifo_data_t>::sptr _recv_fifo, _send_fifo;      const zero_copy_xport_params _xport_params; -    std::vector<boost::shared_ptr<nirio_zero_copy_msb> > _msb_pool; -    std::vector<boost::shared_ptr<nirio_zero_copy_mrb> > _mrb_pool; +    std::vector<boost::shared_ptr<nirio_zero_copy_msb>> _msb_pool; +    std::vector<boost::shared_ptr<nirio_zero_copy_mrb>> _mrb_pool;      size_t _next_recv_buff_index, _next_send_buff_index;  }; @@ -350,102 +393,121 @@ nirio_zero_copy::sptr nirio_zero_copy::make(      uhd::niusrprio::niusrprio_session::sptr fpga_session,      const uint32_t instance,      const zero_copy_xport_params& default_buff_args, -    const device_addr_t &hints -){ -    //Initialize xport_params +    const device_addr_t& hints) +{ +    // Initialize xport_params      zero_copy_xport_params xport_params = default_buff_args; -    //The kernel buffer for this transport must be (num_frames * frame_size) big. Unlike ethernet, -    //where the kernel buffer size is independent of the circular buffer size for the transport, -    //it is possible for users to over constrain the system when they set the num_frames and the buff_size -    //So we give buff_size priority over num_frames and throw an error if they conflict. +    // The kernel buffer for this transport must be (num_frames * frame_size) big. Unlike +    // ethernet, where the kernel buffer size is independent of the circular buffer size +    // for the transport, it is possible for users to over constrain the system when they +    // set the num_frames and the buff_size So we give buff_size priority over num_frames +    // and throw an error if they conflict. -    //RX -    xport_params.recv_frame_size = size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size)); +    // RX +    xport_params.recv_frame_size = +        size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size));      size_t usr_num_recv_frames = static_cast<size_t>(          hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames));      size_t usr_recv_buff_size = static_cast<size_t>(          hints.cast<double>("recv_buff_size", default_buff_args.num_recv_frames)); -    if (hints.has_key("recv_buff_size")) -    { -        if (usr_recv_buff_size % page_size != 0) -        { -            throw uhd::value_error((boost::format("recv_buff_size must be multiple of %d") % page_size).str()); +    if (hints.has_key("recv_buff_size")) { +        if (usr_recv_buff_size % page_size != 0) { +            throw uhd::value_error( +                (boost::format("recv_buff_size must be multiple of %d") % page_size) +                    .str());          }      } -    if (hints.has_key("recv_frame_size") and hints.has_key("num_recv_frames")) -    { -        if (usr_num_recv_frames * xport_params.recv_frame_size % page_size != 0) -        { -            throw uhd::value_error((boost::format("num_recv_frames * recv_frame_size must be an even multiple of %d") % page_size).str()); +    if (hints.has_key("recv_frame_size") and hints.has_key("num_recv_frames")) { +        if (usr_num_recv_frames * xport_params.recv_frame_size % page_size != 0) { +            throw uhd::value_error( +                (boost::format( +                     "num_recv_frames * recv_frame_size must be an even multiple of %d") +                    % page_size) +                    .str());          }      }      if (hints.has_key("num_recv_frames") and hints.has_key("recv_buff_size")) {          if (usr_recv_buff_size < xport_params.recv_frame_size) -            throw uhd::value_error("recv_buff_size must be equal to or greater than (num_recv_frames * recv_frame_size)"); +            throw uhd::value_error("recv_buff_size must be equal to or greater than " +                                   "(num_recv_frames * recv_frame_size)"); -        if ((usr_recv_buff_size/xport_params.recv_frame_size) != usr_num_recv_frames) -            throw uhd::value_error("Conflicting values for recv_buff_size and num_recv_frames"); +        if ((usr_recv_buff_size / xport_params.recv_frame_size) != usr_num_recv_frames) +            throw uhd::value_error( +                "Conflicting values for recv_buff_size and num_recv_frames");      }      if (hints.has_key("recv_buff_size")) { -        xport_params.num_recv_frames = std::max<size_t>(1, usr_recv_buff_size/xport_params.recv_frame_size);    //Round down +        xport_params.num_recv_frames = std::max<size_t>( +            1, usr_recv_buff_size / xport_params.recv_frame_size); // Round down      } else if (hints.has_key("num_recv_frames")) {          xport_params.num_recv_frames = usr_num_recv_frames;      } -    if (xport_params.num_recv_frames * xport_params.recv_frame_size % page_size != 0) -    { -        throw uhd::value_error((boost::format("num_recv_frames * recv_frame_size must be an even multiple of %d") % page_size).str()); +    if (xport_params.num_recv_frames * xport_params.recv_frame_size % page_size != 0) { +        throw uhd::value_error( +            (boost::format( +                 "num_recv_frames * recv_frame_size must be an even multiple of %d") +                % page_size) +                .str());      } -    //TX -    xport_params.send_frame_size = size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size)); +    // TX +    xport_params.send_frame_size = +        size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size));      size_t usr_num_send_frames = static_cast<size_t>(          hints.cast<double>("num_send_frames", default_buff_args.num_send_frames));      size_t usr_send_buff_size = static_cast<size_t>(          hints.cast<double>("send_buff_size", default_buff_args.num_send_frames)); -    if (hints.has_key("send_buff_size"))  -    { -        if (usr_send_buff_size % page_size != 0) -        { -            throw uhd::value_error((boost::format("send_buff_size must be multiple of %d") % page_size).str()); +    if (hints.has_key("send_buff_size")) { +        if (usr_send_buff_size % page_size != 0) { +            throw uhd::value_error( +                (boost::format("send_buff_size must be multiple of %d") % page_size) +                    .str());          }      } -    if (hints.has_key("send_frame_size") and hints.has_key("num_send_frames")) -    { -        if (usr_num_send_frames * xport_params.send_frame_size % page_size != 0) -        { -            throw uhd::value_error((boost::format("num_send_frames * send_frame_size must be an even multiple of %d") % page_size).str()); +    if (hints.has_key("send_frame_size") and hints.has_key("num_send_frames")) { +        if (usr_num_send_frames * xport_params.send_frame_size % page_size != 0) { +            throw uhd::value_error( +                (boost::format( +                     "num_send_frames * send_frame_size must be an even multiple of %d") +                    % page_size) +                    .str());          }      }      if (hints.has_key("num_send_frames") and hints.has_key("send_buff_size")) {          if (usr_send_buff_size < xport_params.send_frame_size) -            throw uhd::value_error("send_buff_size must be equal to or greater than (num_send_frames * send_frame_size)"); +            throw uhd::value_error("send_buff_size must be equal to or greater than " +                                   "(num_send_frames * send_frame_size)"); -        if ((usr_send_buff_size/xport_params.send_frame_size) != usr_num_send_frames) -            throw uhd::value_error("Conflicting values for send_buff_size and num_send_frames"); +        if ((usr_send_buff_size / xport_params.send_frame_size) != usr_num_send_frames) +            throw uhd::value_error( +                "Conflicting values for send_buff_size and num_send_frames");      }      if (hints.has_key("send_buff_size")) { -        xport_params.num_send_frames = std::max<size_t>(1, usr_send_buff_size/xport_params.send_frame_size);    //Round down +        xport_params.num_send_frames = std::max<size_t>( +            1, usr_send_buff_size / xport_params.send_frame_size); // Round down      } else if (hints.has_key("num_send_frames")) {          xport_params.num_send_frames = usr_num_send_frames;      } -    if (xport_params.num_send_frames * xport_params.send_frame_size % page_size != 0) -    { -        throw uhd::value_error((boost::format("num_send_frames * send_frame_size must be an even multiple of %d") % page_size).str()); +    if (xport_params.num_send_frames * xport_params.send_frame_size % page_size != 0) { +        throw uhd::value_error( +            (boost::format( +                 "num_send_frames * send_frame_size must be an even multiple of %d") +                % page_size) +                .str());      } -    return nirio_zero_copy::sptr(new nirio_zero_copy_impl(fpga_session, instance, xport_params)); +    return nirio_zero_copy::sptr( +        new nirio_zero_copy_impl(fpga_session, instance, xport_params));  } - diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp index 894287d6b..342d273a6 100644 --- a/host/lib/transport/super_recv_packet_handler.hpp +++ b/host/lib/transport/super_recv_packet_handler.hpp @@ -9,43 +9,43 @@  #define INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP  #include <uhd/config.hpp> -#include <uhd/exception.hpp>  #include <uhd/convert.hpp> +#include <uhd/exception.hpp>  #include <uhd/stream.hpp> -#include <uhd/utils/tasks.hpp> -#include <uhd/utils/byteswap.hpp> -#include <uhd/utils/log.hpp> -#include <uhd/types/metadata.hpp>  #include <uhd/transport/vrt_if_packet.hpp>  #include <uhd/transport/zero_copy.hpp> +#include <uhd/types/metadata.hpp> +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/tasks.hpp>  #include <uhdlib/rfnoc/rx_stream_terminator.hpp>  #include <boost/dynamic_bitset.hpp> -#include <boost/function.hpp>  #include <boost/format.hpp> +#include <boost/function.hpp>  #include <boost/make_shared.hpp>  #include <iostream>  #include <vector>  // Included for debugging  #ifdef UHD_TXRX_DEBUG_PRINTS -#include <boost/format.hpp> -#include <boost/thread/thread.hpp> -#include "boost/date_time/posix_time/posix_time.hpp" +#    include "boost/date_time/posix_time/posix_time.hpp" +#    include <boost/format.hpp> +#    include <boost/thread/thread.hpp>  #endif -namespace uhd{ namespace transport{ namespace sph{ +namespace uhd { namespace transport { namespace sph {  UHD_INLINE uint32_t get_context_code( -    const uint32_t *vrt_hdr, const vrt::if_packet_info_t &if_packet_info -){ -    //extract the context word (we dont know the endianness so mirror the bytes) -    uint32_t word0 = vrt_hdr[if_packet_info.num_header_words32] | -              uhd::byteswap(vrt_hdr[if_packet_info.num_header_words32]); +    const uint32_t* vrt_hdr, const vrt::if_packet_info_t& if_packet_info) +{ +    // extract the context word (we dont know the endianness so mirror the bytes) +    uint32_t word0 = vrt_hdr[if_packet_info.num_header_words32] +                     | uhd::byteswap(vrt_hdr[if_packet_info.num_header_words32]);      return word0 & 0xff;  }  typedef boost::function<void(void)> handle_overflow_type; -static inline void handle_overflow_nop(void){} +static inline void handle_overflow_nop(void) {}  /***********************************************************************   * Super receive packet handler @@ -54,51 +54,58 @@ static inline void handle_overflow_nop(void){}   * The channel group shares a common sample rate.   * All channels are received in unison in recv().   **********************************************************************/ -class recv_packet_handler{ +class recv_packet_handler +{  public:      typedef boost::function<managed_recv_buffer::sptr(double)> get_buff_type;      typedef boost::function<void(const size_t)> handle_flowctrl_type; -    typedef std::function<void(const uint32_t *)> handle_flowctrl_ack_type; +    typedef std::function<void(const uint32_t*)> handle_flowctrl_ack_type;      typedef boost::function<void(const stream_cmd_t&)> issue_stream_cmd_type; -    typedef void(*vrt_unpacker_type)(const uint32_t *, vrt::if_packet_info_t &); -    //typedef boost::function<void(const uint32_t *, vrt::if_packet_info_t &)> vrt_unpacker_type; +    typedef void (*vrt_unpacker_type)(const uint32_t*, vrt::if_packet_info_t&); +    // typedef boost::function<void(const uint32_t *, vrt::if_packet_info_t &)> +    // vrt_unpacker_type;      /*!       * Make a new packet handler for receive       * \param size the number of transport channels       */ -    recv_packet_handler(const size_t size = 1): -        _queue_error_for_next_call(false), -        _buffers_infos_index(0) +    recv_packet_handler(const size_t size = 1) +        : _queue_error_for_next_call(false), _buffers_infos_index(0)      { -        #ifdef  ERROR_INJECT_DROPPED_PACKETS +#ifdef ERROR_INJECT_DROPPED_PACKETS          recvd_packets = 0; -        #endif +#endif          this->resize(size);          set_alignment_failure_threshold(1000);      } -    ~recv_packet_handler(void){ +    ~recv_packet_handler(void) +    {          /* NOP */      }      //! Resize the number of transport channels -    void resize(const size_t size){ -        if (this->size() == size) return; +    void resize(const size_t size) +    { +        if (this->size() == size) +            return;          _props.resize(size); -        //re-initialize all buffers infos by re-creating the vector +        // re-initialize all buffers infos by re-creating the vector          _buffers_infos = std::vector<buffers_info_type>(4, buffers_info_type(size));      }      //! Get the channel width of this handler -    size_t size(void) const{ +    size_t size(void) const +    {          return _props.size();      }      //! Setup the vrt unpacker function and offset -    void set_vrt_unpacker(const vrt_unpacker_type &vrt_unpacker, const size_t header_offset_words32 = 0){ -        _vrt_unpacker = vrt_unpacker; +    void set_vrt_unpacker( +        const vrt_unpacker_type& vrt_unpacker, const size_t header_offset_words32 = 0) +    { +        _vrt_unpacker          = vrt_unpacker;          _header_offset_words32 = header_offset_words32;      } @@ -107,17 +114,20 @@ public:       * How many packets throw out before giving up?       * \param threshold number of packets per channel       */ -    void set_alignment_failure_threshold(const size_t threshold){ -        _alignment_failure_threshold = threshold*this->size(); +    void set_alignment_failure_threshold(const size_t threshold) +    { +        _alignment_failure_threshold = threshold * this->size();      }      //! Set the rate of ticks per second -    void set_tick_rate(const double rate){ +    void set_tick_rate(const double rate) +    {          _tick_rate = rate;      }      //! Set the rate of samples per second -    void set_samp_rate(const double rate){ +    void set_samp_rate(const double rate) +    {          _samp_rate = rate;      } @@ -126,9 +136,12 @@ public:       * \param xport_chan which transport channel       * \param get_buff the getter function       */ -    void set_xport_chan_get_buff(const size_t xport_chan, const get_buff_type &get_buff, const bool flush = false){ -        if (flush){ -            while (get_buff(0.0)) {}; +    void set_xport_chan_get_buff( +        const size_t xport_chan, const get_buff_type& get_buff, const bool flush = false) +    { +        if (flush) { +            while (get_buff(0.0)) { +            };          }          _props.at(xport_chan).get_buff = get_buff;      } @@ -148,58 +161,67 @@ public:       * \param xport_chan which transport channel       * \param handle_flowctrl the callback function       */ -    void set_xport_handle_flowctrl(const size_t xport_chan, const handle_flowctrl_type &handle_flowctrl, const size_t update_window, const bool do_init = false) +    void set_xport_handle_flowctrl(const size_t xport_chan, +        const handle_flowctrl_type& handle_flowctrl, +        const size_t update_window, +        const bool do_init = false)      {          _props.at(xport_chan).handle_flowctrl = handle_flowctrl; -        //we need the window size to be within the 0xfff (max 12 bit seq) +        // we need the window size to be within the 0xfff (max 12 bit seq)          _props.at(xport_chan).fc_update_window = std::min<size_t>(update_window, 0xfff); -        if (do_init) handle_flowctrl(0); +        if (do_init) +            handle_flowctrl(0);      }      void set_xport_handle_flowctrl_ack( -            const size_t xport_chan, -            const handle_flowctrl_ack_type &handle_flowctrl_ack -    ) { +        const size_t xport_chan, const handle_flowctrl_ack_type& handle_flowctrl_ack) +    {          _props.at(xport_chan).handle_flowctrl_ack = handle_flowctrl_ack;      }      //! Set the conversion routine for all channels -    void set_converter(const uhd::convert::id_type &id){ +    void set_converter(const uhd::convert::id_type& id) +    {          _num_outputs = id.num_outputs; -        _converter = uhd::convert::get_converter(id)(); -        this->set_scale_factor(1/32767.); //update after setting converter +        _converter   = uhd::convert::get_converter(id)(); +        this->set_scale_factor(1 / 32767.); // update after setting converter          _bytes_per_otw_item = uhd::convert::get_bytes_per_item(id.input_format);          _bytes_per_cpu_item = uhd::convert::get_bytes_per_item(id.output_format);      }      //! Set the transport channel's overflow handler -    void set_overflow_handler(const size_t xport_chan, const handle_overflow_type &handle_overflow){ +    void set_overflow_handler( +        const size_t xport_chan, const handle_overflow_type& handle_overflow) +    {          _props.at(xport_chan).handle_overflow = handle_overflow;      }      //! Set the scale factor used in float conversion -    void set_scale_factor(const double scale_factor){ +    void set_scale_factor(const double scale_factor) +    {          _converter->set_scalar(scale_factor);      }      //! Set the callback to issue stream commands -    void set_issue_stream_cmd(const size_t xport_chan, const issue_stream_cmd_type &issue_stream_cmd) +    void set_issue_stream_cmd( +        const size_t xport_chan, const issue_stream_cmd_type& issue_stream_cmd)      {          _props.at(xport_chan).issue_stream_cmd = issue_stream_cmd;      }      //! Overload call to issue stream commands -    void issue_stream_cmd(const stream_cmd_t &stream_cmd) +    void issue_stream_cmd(const stream_cmd_t& stream_cmd)      { -        if (size() > 1 and stream_cmd.stream_now and -            stream_cmd.stream_mode != stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) -        { -            throw uhd::runtime_error("Invalid recv stream command - stream now on multiple channels in a single streamer will fail to time align."); +        if (size() > 1 and stream_cmd.stream_now +            and stream_cmd.stream_mode != stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS) { +            throw uhd::runtime_error( +                "Invalid recv stream command - stream now on multiple channels in a " +                "single streamer will fail to time align.");          } -        for (size_t i = 0; i < _props.size(); i++) -        { -            if (_props[i].issue_stream_cmd) _props[i].issue_stream_cmd(stream_cmd); +        for (size_t i = 0; i < _props.size(); i++) { +            if (_props[i].issue_stream_cmd) +                _props[i].issue_stream_cmd(stream_cmd);          }      } @@ -208,56 +230,57 @@ public:       * The entry point for the fast-path receive calls.       * Dispatch into combinations of single packet receive calls.       ******************************************************************/ -    UHD_INLINE size_t recv( -        const uhd::rx_streamer::buffs_type &buffs, +    UHD_INLINE size_t recv(const uhd::rx_streamer::buffs_type& buffs,          const size_t nsamps_per_buff, -        uhd::rx_metadata_t &metadata, +        uhd::rx_metadata_t& metadata,          const double timeout, -        const bool one_packet -    ){ -        //handle metadata queued from a previous receive -        if (_queue_error_for_next_call){ +        const bool one_packet) +    { +        // handle metadata queued from a previous receive +        if (_queue_error_for_next_call) {              _queue_error_for_next_call = false; -            metadata = _queue_metadata; -            //We want to allow a full buffer recv to be cut short by a timeout, -            //but do not want to generate an inline timeout message packet. -            if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_TIMEOUT) return 0; +            metadata                   = _queue_metadata; +            // We want to allow a full buffer recv to be cut short by a timeout, +            // but do not want to generate an inline timeout message packet. +            if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_TIMEOUT) +                return 0;          } -        size_t accum_num_samps = recv_one_packet( -            buffs, nsamps_per_buff, metadata, timeout -        ); +        size_t accum_num_samps = +            recv_one_packet(buffs, nsamps_per_buff, metadata, timeout); -        if (one_packet or metadata.end_of_burst){ +        if (one_packet or metadata.end_of_burst) {  #ifdef UHD_TXRX_DEBUG_PRINTS -            dbg_gather_data(nsamps_per_buff, accum_num_samps, metadata, timeout, one_packet); +            dbg_gather_data( +                nsamps_per_buff, accum_num_samps, metadata, timeout, one_packet);  #endif              return accum_num_samps;          } -        //first recv had an error code set, return immediately +        // first recv had an error code set, return immediately          if (metadata.error_code != rx_metadata_t::ERROR_CODE_NONE) {              return accum_num_samps;          } -        //loop until buffer is filled or error code -        while(accum_num_samps < nsamps_per_buff){ -            size_t num_samps = recv_one_packet( -                buffs, nsamps_per_buff - accum_num_samps, _queue_metadata, -                timeout, accum_num_samps*_bytes_per_cpu_item -            ); +        // loop until buffer is filled or error code +        while (accum_num_samps < nsamps_per_buff) { +            size_t num_samps = recv_one_packet(buffs, +                nsamps_per_buff - accum_num_samps, +                _queue_metadata, +                timeout, +                accum_num_samps * _bytes_per_cpu_item);              metadata.end_of_burst = _queue_metadata.end_of_burst; -            //metadata had an error code set, store for next call and return -            if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_NONE){ +            // metadata had an error code set, store for next call and return +            if (_queue_metadata.error_code != rx_metadata_t::ERROR_CODE_NONE) {                  _queue_error_for_next_call = true;                  break;              }              accum_num_samps += num_samps; -            //return immediately if end of burst +            // return immediately if end of burst              if (_queue_metadata.end_of_burst) {                  break;              } @@ -275,12 +298,12 @@ private:      bool _queue_error_for_next_call;      size_t _alignment_failure_threshold;      rx_metadata_t _queue_metadata; -    struct xport_chan_props_type{ -        xport_chan_props_type(void): -            packet_count(0), -            handle_overflow(&handle_overflow_nop), -            fc_update_window(0) -        {} +    struct xport_chan_props_type +    { +        xport_chan_props_type(void) +            : packet_count(0), handle_overflow(&handle_overflow_nop), fc_update_window(0) +        { +        }          get_buff_type get_buff;          issue_stream_cmd_type issue_stream_cmd;          size_t packet_count; @@ -291,65 +314,80 @@ private:      };      std::vector<xport_chan_props_type> _props;      size_t _num_outputs; -    size_t _bytes_per_otw_item; //used in conversion -    size_t _bytes_per_cpu_item; //used in conversion -    uhd::convert::converter::sptr _converter; //used in conversion +    size_t _bytes_per_otw_item; // used in conversion +    size_t _bytes_per_cpu_item; // used in conversion +    uhd::convert::converter::sptr _converter; // used in conversion      //! information stored for a received buffer -    struct per_buffer_info_type{ +    struct per_buffer_info_type +    {          void reset()          {              buff.reset(); -            vrt_hdr = nullptr; -            time = 0; +            vrt_hdr   = nullptr; +            time      = 0;              copy_buff = nullptr;          }          managed_recv_buffer::sptr buff; -        const uint32_t *vrt_hdr; +        const uint32_t* vrt_hdr;          vrt::if_packet_info_t ifpi;          uint64_t time; -        const char *copy_buff; +        const char* copy_buff;      }; -    //!information stored for a set of aligned buffers -    struct buffers_info_type : std::vector<per_buffer_info_type> { -        buffers_info_type(const size_t size): -            std::vector<per_buffer_info_type>(size), -            indexes_todo(size, true), -            alignment_time(0), -            alignment_time_valid(false), -            data_bytes_to_copy(0), -            fragment_offset_in_samps(0) -        {/* NOP */} +    //! information stored for a set of aligned buffers +    struct buffers_info_type : std::vector<per_buffer_info_type> +    { +        buffers_info_type(const size_t size) +            : std::vector<per_buffer_info_type>(size) +            , indexes_todo(size, true) +            , alignment_time(0) +            , alignment_time_valid(false) +            , data_bytes_to_copy(0) +            , fragment_offset_in_samps(0) +        { /* NOP */ +        }          void reset()          {              indexes_todo.set(); -            alignment_time = 0; -            alignment_time_valid = false; -            data_bytes_to_copy = 0; +            alignment_time           = 0; +            alignment_time_valid     = false; +            data_bytes_to_copy       = 0;              fragment_offset_in_samps = 0;              metadata.reset();              for (size_t i = 0; i < size(); i++)                  at(i).reset();          } -        boost::dynamic_bitset<> indexes_todo; //used in alignment logic -        uint64_t alignment_time; //used in alignment logic -        bool alignment_time_valid; //used in alignment logic -        size_t data_bytes_to_copy; //keeps track of state -        size_t fragment_offset_in_samps; //keeps track of state -        rx_metadata_t metadata; //packet description +        boost::dynamic_bitset<> indexes_todo; // used in alignment logic +        uint64_t alignment_time; // used in alignment logic +        bool alignment_time_valid; // used in alignment logic +        size_t data_bytes_to_copy; // keeps track of state +        size_t fragment_offset_in_samps; // keeps track of state +        rx_metadata_t metadata; // packet description      };      //! a circular queue of buffer infos      std::vector<buffers_info_type> _buffers_infos;      size_t _buffers_infos_index; -    buffers_info_type &get_curr_buffer_info(void){return _buffers_infos[_buffers_infos_index];} -    buffers_info_type &get_prev_buffer_info(void){return _buffers_infos[(_buffers_infos_index + 3)%4];} -    buffers_info_type &get_next_buffer_info(void){return _buffers_infos[(_buffers_infos_index + 1)%4];} -    void increment_buffer_info(void){_buffers_infos_index = (_buffers_infos_index + 1)%4;} +    buffers_info_type& get_curr_buffer_info(void) +    { +        return _buffers_infos[_buffers_infos_index]; +    } +    buffers_info_type& get_prev_buffer_info(void) +    { +        return _buffers_infos[(_buffers_infos_index + 3) % 4]; +    } +    buffers_info_type& get_next_buffer_info(void) +    { +        return _buffers_infos[(_buffers_infos_index + 1) % 4]; +    } +    void increment_buffer_info(void) +    { +        _buffers_infos_index = (_buffers_infos_index + 1) % 4; +    }      //! possible return options for the packet receiver -    enum packet_type{ +    enum packet_type {          PACKET_IF_DATA,          PACKET_TIMESTAMP_ERROR,          PACKET_INLINE_MESSAGE, @@ -357,9 +395,9 @@ private:          PACKET_SEQUENCE_ERROR      }; -    #ifdef  ERROR_INJECT_DROPPED_PACKETS +#ifdef ERROR_INJECT_DROPPED_PACKETS      int recvd_packets; -    #endif +#endif      /*******************************************************************       * Get and process a single packet from the transport: @@ -367,57 +405,56 @@ private:       * Extract all the relevant info and store.       * Check the info to determine the return code.       ******************************************************************/ -    UHD_INLINE packet_type get_and_process_single_packet( -        const size_t index, -        per_buffer_info_type &prev_buffer_info, -        per_buffer_info_type &curr_buffer_info, -        double timeout -    ){ -        managed_recv_buffer::sptr &buff = curr_buffer_info.buff; -        per_buffer_info_type &info = curr_buffer_info; -        while (1) -        { -            //get a single packet from the transport layer +    UHD_INLINE packet_type get_and_process_single_packet(const size_t index, +        per_buffer_info_type& prev_buffer_info, +        per_buffer_info_type& curr_buffer_info, +        double timeout) +    { +        managed_recv_buffer::sptr& buff = curr_buffer_info.buff; +        per_buffer_info_type& info      = curr_buffer_info; +        while (1) { +            // get a single packet from the transport layer              buff = _props[index].get_buff(timeout); -            if (buff.get() == nullptr) return PACKET_TIMEOUT_ERROR; +            if (buff.get() == nullptr) +                return PACKET_TIMEOUT_ERROR; -            #ifdef  ERROR_INJECT_DROPPED_PACKETS -            if (++recvd_packets > 1000) -            { +#ifdef ERROR_INJECT_DROPPED_PACKETS +            if (++recvd_packets > 1000) {                  recvd_packets = 0;                  buff.reset();                  buff = _props[index].get_buff(timeout); -                if (buff.get() == nullptr) return PACKET_TIMEOUT_ERROR; +                if (buff.get() == nullptr) +                    return PACKET_TIMEOUT_ERROR;              } -            #endif +#endif -            //bounds check before extract -            const size_t num_packet_words32 = buff->size()/sizeof(uint32_t); -            if (num_packet_words32 <= _header_offset_words32){ +            // bounds check before extract +            const size_t num_packet_words32 = buff->size() / sizeof(uint32_t); +            if (num_packet_words32 <= _header_offset_words32) {                  throw std::runtime_error("recv buffer smaller than vrt packet offset");              } -            //extract packet info -            memset(&info.ifpi, 0, sizeof (vrt::if_packet_info_t)); +            // extract packet info +            memset(&info.ifpi, 0, sizeof(vrt::if_packet_info_t));              info.ifpi.num_packet_words32 = num_packet_words32 - _header_offset_words32; -            info.vrt_hdr = buff->cast<const uint32_t *>() + _header_offset_words32; +            info.vrt_hdr = buff->cast<const uint32_t*>() + _header_offset_words32;              _vrt_unpacker(info.vrt_hdr, info.ifpi); -            info.time = info.ifpi.tsf; //assumes has_tsf is true -            info.copy_buff = reinterpret_cast<const char *>(info.vrt_hdr + info.ifpi.num_header_words32); - -            //handle flow control -            if (_props[index].handle_flowctrl) -            { -                if ((info.ifpi.packet_count % _props[index].fc_update_window) == 0) -                { +            info.time      = info.ifpi.tsf; // assumes has_tsf is true +            info.copy_buff = reinterpret_cast<const char*>( +                info.vrt_hdr + info.ifpi.num_header_words32); + +            // handle flow control +            if (_props[index].handle_flowctrl) { +                if ((info.ifpi.packet_count % _props[index].fc_update_window) == 0) {                      _props[index].handle_flowctrl(info.ifpi.packet_count);                  }              } -            //handle flow control ack -            if (info.ifpi.fc_ack){ +            // handle flow control ack +            if (info.ifpi.fc_ack) {                  if (_props[index].handle_flowctrl_ack) { -                    _props[index].handle_flowctrl_ack(reinterpret_cast<const uint32_t *>(info.copy_buff)); +                    _props[index].handle_flowctrl_ack( +                        reinterpret_cast<const uint32_t*>(info.copy_buff));                  }                  // Process the next packet                  buff.reset(); @@ -433,18 +470,20 @@ private:          //-- The order of these checks is HOLY.          //-------------------------------------------------------------- -        //1) check for inline IF message packets -        if (info.ifpi.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ +        // 1) check for inline IF message packets +        if (info.ifpi.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA) {              return PACKET_INLINE_MESSAGE;          } -        //2) check for sequence errors -        #ifndef SRPH_DONT_CHECK_SEQUENCE -        const size_t seq_mask = (info.ifpi.link_type == vrt::if_packet_info_t::LINK_TYPE_NONE)? 0xf : 0xfff; +// 2) check for sequence errors +#ifndef SRPH_DONT_CHECK_SEQUENCE +        const size_t seq_mask = +            (info.ifpi.link_type == vrt::if_packet_info_t::LINK_TYPE_NONE) ? 0xf : 0xfff;          const size_t expected_packet_count = _props[index].packet_count; -        _props[index].packet_count = (info.ifpi.packet_count + 1) & seq_mask; -        if (expected_packet_count != info.ifpi.packet_count){ -            //UHD_LOGGER_INFO("STREAMER") << "expected: " << expected_packet_count << " got: " << info.ifpi.packet_count; +        _props[index].packet_count         = (info.ifpi.packet_count + 1) & seq_mask; +        if (expected_packet_count != info.ifpi.packet_count) { +            // UHD_LOGGER_INFO("STREAMER") << "expected: " << expected_packet_count << " +            // got: " << info.ifpi.packet_count;              if (_props[index].handle_flowctrl) {                  // Always update flow control in this case, because we don't                  // know which packet was dropped and what state the upstream @@ -453,14 +492,14 @@ private:              }              return PACKET_SEQUENCE_ERROR;          } -        #endif +#endif -        //3) check for out of order timestamps -        if (info.ifpi.has_tsf and prev_buffer_info.time > info.time){ +        // 3) check for out of order timestamps +        if (info.ifpi.has_tsf and prev_buffer_info.time > info.time) {              return PACKET_TIMESTAMP_ERROR;          } -        //4) otherwise the packet is normal! +        // 4) otherwise the packet is normal!          return PACKET_IF_DATA;      } @@ -470,25 +509,22 @@ private:          get_curr_buffer_info().reset();          get_next_buffer_info().reset(); -        for (size_t i = 0; i < _props.size(); i++) -        { +        for (size_t i = 0; i < _props.size(); i++) {              per_buffer_info_type prev_buffer_info, curr_buffer_info;              prev_buffer_info.reset();              curr_buffer_info.reset(); -            while (true) -            { -                //receive a single packet from the transport -                try -                { +            while (true) { +                // receive a single packet from the transport +                try {                      // call into get_and_process_single_packet()                      // to make sure flow control is handled                      if (get_and_process_single_packet( -                            i, -                            prev_buffer_info, -                            curr_buffer_info, -                            timeout) == PACKET_TIMEOUT_ERROR) break; -                } catch(...){} -                curr_buffer_info.buff.reset();  // Let my buffer go! +                            i, prev_buffer_info, curr_buffer_info, timeout) +                        == PACKET_TIMEOUT_ERROR) +                        break; +                } catch (...) { +                } +                curr_buffer_info.buff.reset(); // Let my buffer go!                  prev_buffer_info = curr_buffer_info;                  curr_buffer_info.reset();              } @@ -499,34 +535,31 @@ private:       * Alignment check:       * Check the received packet for alignment and mark accordingly.       ******************************************************************/ -    UHD_INLINE void alignment_check( -        const size_t index, buffers_info_type &info -    ){ -        //if alignment time was not valid or if the sequence id is newer: +    UHD_INLINE void alignment_check(const size_t index, buffers_info_type& info) +    { +        // if alignment time was not valid or if the sequence id is newer:          //  use this index's time as the alignment time          //  reset the indexes list and remove this index -        if (not info.alignment_time_valid or info[index].time > info.alignment_time){ +        if (not info.alignment_time_valid or info[index].time > info.alignment_time) {              info.alignment_time_valid = true; -            info.alignment_time = info[index].time; +            info.alignment_time       = info[index].time;              info.indexes_todo.set();              info.indexes_todo.reset(index);              // release the other buffers -            for (size_t i = 0; i < info.size(); i++) -            { -                if (i != index) -                { +            for (size_t i = 0; i < info.size(); i++) { +                if (i != index) {                      info[i].reset();                  }              }              info.data_bytes_to_copy = info[index].ifpi.num_payload_bytes;              // reset start_of_burst and end_of_burst states              info.metadata.start_of_burst = info[index].ifpi.sob; -            info.metadata.end_of_burst = info[index].ifpi.eob; +            info.metadata.end_of_burst   = info[index].ifpi.eob;          } -        //if the sequence id matches: +        // if the sequence id matches:          //  remove this index from the list and continue -        else if (info[index].time == info.alignment_time){ +        else if (info[index].time == info.alignment_time) {              info.indexes_todo.reset(index);              // All channels should have sob set at the same time, so only              // set start_of burst if all channels have sob set. @@ -539,9 +572,9 @@ private:              info[index].reset();          } -        //if the sequence id is older: +        // if the sequence id is older:          //  continue with the same index to try again -        //else if (info[index].time < info.alignment_time)... +        // else if (info[index].time < info.alignment_time)...      }      /******************************************************************* @@ -550,127 +583,139 @@ private:       * Handle all of the edge cases like inline messages and errors.       * The logic will throw out older packets until it finds a match.       ******************************************************************/ -    UHD_INLINE void get_aligned_buffs(double timeout){ - -        get_prev_buffer_info().reset(); // no longer need the previous info - reset it for future use +    UHD_INLINE void get_aligned_buffs(double timeout) +    { +        get_prev_buffer_info() +            .reset(); // no longer need the previous info - reset it for future use -        increment_buffer_info(); //increment to next buffer +        increment_buffer_info(); // increment to next buffer -        buffers_info_type &prev_info = get_prev_buffer_info(); -        buffers_info_type &curr_info = get_curr_buffer_info(); -        buffers_info_type &next_info = get_next_buffer_info(); +        buffers_info_type& prev_info = get_prev_buffer_info(); +        buffers_info_type& curr_info = get_curr_buffer_info(); +        buffers_info_type& next_info = get_next_buffer_info();          curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_NONE; -        //Loop until we get a message of an aligned set of buffers: +        // Loop until we get a message of an aligned set of buffers:          // - Receive a single packet and extract its info.          // - Handle the packet type yielded by the receive.          // - Check the timestamps for alignment conditions.          size_t iterations = 0; -        while (curr_info.indexes_todo.any()){ - -            //get the index to process for this iteration +        while (curr_info.indexes_todo.any()) { +            // get the index to process for this iteration              const size_t index = curr_info.indexes_todo.find_first();              packet_type packet; -            //receive a single packet from the transport -            try{ +            // receive a single packet from the transport +            try {                  packet = get_and_process_single_packet( -                    index, prev_info[index], curr_info[index], timeout -                ); +                    index, prev_info[index], curr_info[index], timeout);              } -            //handle the case where a bad header exists -            catch(const uhd::value_error &e){ -                UHD_LOGGER_ERROR("STREAMER") << boost::format( -                    "The receive packet handler caught a value exception.\n%s" -                    ) % e.what(); -                std::swap(curr_info, next_info); //save progress from curr -> next +            // handle the case where a bad header exists +            catch (const uhd::value_error& e) { +                UHD_LOGGER_ERROR("STREAMER") +                    << boost::format( +                           "The receive packet handler caught a value exception.\n%s") +                           % e.what(); +                std::swap(curr_info, next_info); // save progress from curr -> next                  curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_BAD_PACKET;                  return;              } -            switch(packet){ -            case PACKET_IF_DATA: -                alignment_check(index, curr_info); -                break; - -            case PACKET_TIMESTAMP_ERROR: -                //If the user changes the device time while streaming or without flushing, -                //we can receive a packet that comes before the previous packet in time. -                //This could cause the alignment logic to discard future received packets. -                //Therefore, when this occurs, we reset the info to restart from scratch. -                if (curr_info.alignment_time_valid and curr_info.alignment_time != curr_info[index].time){ -                    curr_info.alignment_time_valid = false; -                } -                alignment_check(index, curr_info); -                break; +            switch (packet) { +                case PACKET_IF_DATA: +                    alignment_check(index, curr_info); +                    break; + +                case PACKET_TIMESTAMP_ERROR: +                    // If the user changes the device time while streaming or without +                    // flushing, we can receive a packet that comes before the previous +                    // packet in time. This could cause the alignment logic to discard +                    // future received packets. Therefore, when this occurs, we reset the +                    // info to restart from scratch. +                    if (curr_info.alignment_time_valid +                        and curr_info.alignment_time != curr_info[index].time) { +                        curr_info.alignment_time_valid = false; +                    } +                    alignment_check(index, curr_info); +                    break; + +                case PACKET_INLINE_MESSAGE: +                    curr_info[index].buff.reset(); // No data, so release the buffer +                    curr_info[index].copy_buff = nullptr; +                    std::swap(curr_info, next_info); // save progress from curr -> next +                    curr_info.metadata.has_time_spec = next_info[index].ifpi.has_tsf; +                    curr_info.metadata.time_spec = +                        time_spec_t::from_ticks(next_info[index].time, _tick_rate); +                    curr_info.metadata.error_code = +                        rx_metadata_t::error_code_t(get_context_code( +                            next_info[index].vrt_hdr, next_info[index].ifpi)); +                    if (curr_info.metadata.error_code +                        == rx_metadata_t::ERROR_CODE_OVERFLOW) { +                        // Not sending flow control would cause timeouts due to source +                        // flow control locking up. Send first as the overrun handler may +                        // flush the receive buffers which could contain packets with +                        // sequence numbers after this packet's sequence number! +                        if (_props[index].handle_flowctrl) { +                            _props[index].handle_flowctrl( +                                next_info[index].ifpi.packet_count); +                        } + +                        rx_metadata_t metadata = curr_info.metadata; +                        _props[index].handle_overflow(); +                        curr_info.metadata = metadata; +                        UHD_LOG_FASTPATH("O"); +                    } +                    return; -            case PACKET_INLINE_MESSAGE: -                curr_info[index].buff.reset();  // No data, so release the buffer -                curr_info[index].copy_buff = nullptr; -                std::swap(curr_info, next_info); //save progress from curr -> next -                curr_info.metadata.has_time_spec = next_info[index].ifpi.has_tsf; -                curr_info.metadata.time_spec = time_spec_t::from_ticks(next_info[index].time, _tick_rate); -                curr_info.metadata.error_code = rx_metadata_t::error_code_t(get_context_code(next_info[index].vrt_hdr, next_info[index].ifpi)); -                if (curr_info.metadata.error_code == rx_metadata_t::ERROR_CODE_OVERFLOW){ -                    // Not sending flow control would cause timeouts due to source flow control locking up. -                    // Send first as the overrun handler may flush the receive buffers which could contain -                    // packets with sequence numbers after this packet's sequence number! -                    if(_props[index].handle_flowctrl) { +                case PACKET_TIMEOUT_ERROR: +                    std::swap(curr_info, next_info); // save progress from curr -> next +                    if (_props[index].handle_flowctrl) {                          _props[index].handle_flowctrl(next_info[index].ifpi.packet_count);                      } - -                    rx_metadata_t metadata = curr_info.metadata; -                    _props[index].handle_overflow(); -                    curr_info.metadata = metadata; -                    UHD_LOG_FASTPATH("O"); -                } -                return; - -            case PACKET_TIMEOUT_ERROR: -                std::swap(curr_info, next_info); //save progress from curr -> next -                if(_props[index].handle_flowctrl) { -                    _props[index].handle_flowctrl(next_info[index].ifpi.packet_count); -                } -                curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_TIMEOUT; -                return; - -            case PACKET_SEQUENCE_ERROR: -                alignment_check(index, curr_info); -                std::swap(curr_info, next_info); //save progress from curr -> next -                curr_info.metadata.has_time_spec = prev_info.metadata.has_time_spec; -                curr_info.metadata.time_spec = prev_info.metadata.time_spec + time_spec_t::from_ticks( -                    prev_info[index].ifpi.num_payload_words32*sizeof(uint32_t)/_bytes_per_otw_item, _samp_rate); -                curr_info.metadata.out_of_sequence = true; -                curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_OVERFLOW; -                UHD_LOG_FASTPATH("D"); -                return; - +                    curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_TIMEOUT; +                    return; + +                case PACKET_SEQUENCE_ERROR: +                    alignment_check(index, curr_info); +                    std::swap(curr_info, next_info); // save progress from curr -> next +                    curr_info.metadata.has_time_spec = prev_info.metadata.has_time_spec; +                    curr_info.metadata.time_spec = +                        prev_info.metadata.time_spec +                        + time_spec_t::from_ticks( +                              prev_info[index].ifpi.num_payload_words32 * sizeof(uint32_t) +                                  / _bytes_per_otw_item, +                              _samp_rate); +                    curr_info.metadata.out_of_sequence = true; +                    curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_OVERFLOW; +                    UHD_LOG_FASTPATH("D"); +                    return;              } -            //too many iterations: detect alignment failure -            if (iterations++ > _alignment_failure_threshold){ -                UHD_LOGGER_ERROR("STREAMER") << boost::format( -                    "The receive packet handler failed to time-align packets.\n" -                    "%u received packets were processed by the handler.\n" -                    "However, a timestamp match could not be determined.\n" -                ) % iterations << std::endl; -                std::swap(curr_info, next_info); //save progress from curr -> next +            // too many iterations: detect alignment failure +            if (iterations++ > _alignment_failure_threshold) { +                UHD_LOGGER_ERROR("STREAMER") +                    << boost::format( +                           "The receive packet handler failed to time-align packets.\n" +                           "%u received packets were processed by the handler.\n" +                           "However, a timestamp match could not be determined.\n") +                           % iterations +                    << std::endl; +                std::swap(curr_info, next_info); // save progress from curr -> next                  curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_ALIGNMENT;                  _props[index].handle_overflow();                  return;              } -          } -        //set the metadata from the buffer information at index zero +        // set the metadata from the buffer information at index zero          curr_info.metadata.has_time_spec = curr_info[0].ifpi.has_tsf; -        curr_info.metadata.time_spec = time_spec_t::from_ticks(curr_info[0].time, _tick_rate); -        curr_info.metadata.more_fragments = false; +        curr_info.metadata.time_spec = +            time_spec_t::from_ticks(curr_info[0].time, _tick_rate); +        curr_info.metadata.more_fragments  = false;          curr_info.metadata.fragment_offset = 0; -        curr_info.metadata.error_code = rx_metadata_t::ERROR_CODE_NONE; - +        curr_info.metadata.error_code      = rx_metadata_t::ERROR_CODE_NONE;      }      /******************************************************************* @@ -679,50 +724,50 @@ private:       * When no fragments are available, call the get aligned buffers.       * Then copy-convert available data into the user's IO buffers.       ******************************************************************/ -    UHD_INLINE size_t recv_one_packet( -        const uhd::rx_streamer::buffs_type &buffs, +    UHD_INLINE size_t recv_one_packet(const uhd::rx_streamer::buffs_type& buffs,          const size_t nsamps_per_buff, -        uhd::rx_metadata_t &metadata, +        uhd::rx_metadata_t& metadata,          const double timeout, -        const size_t buffer_offset_bytes = 0 -    ){ -        //get the next buffer if the current one has expired -        if (get_curr_buffer_info().data_bytes_to_copy == 0) -        { -            //perform receive with alignment logic +        const size_t buffer_offset_bytes = 0) +    { +        // get the next buffer if the current one has expired +        if (get_curr_buffer_info().data_bytes_to_copy == 0) { +            // perform receive with alignment logic              get_aligned_buffs(timeout);          } -        buffers_info_type &info = get_curr_buffer_info(); -        metadata = info.metadata; +        buffers_info_type& info = get_curr_buffer_info(); +        metadata                = info.metadata; -        //interpolate the time spec (useful when this is a fragment) -        metadata.time_spec += time_spec_t::from_ticks(info.fragment_offset_in_samps, _samp_rate); +        // interpolate the time spec (useful when this is a fragment) +        metadata.time_spec += +            time_spec_t::from_ticks(info.fragment_offset_in_samps, _samp_rate); -        //extract the number of samples available to copy -        const size_t nsamps_available = info.data_bytes_to_copy/_bytes_per_otw_item; -        const size_t nsamps_to_copy = std::min(nsamps_per_buff*_num_outputs, nsamps_available); -        const size_t bytes_to_copy = nsamps_to_copy*_bytes_per_otw_item; -        const size_t nsamps_to_copy_per_io_buff = nsamps_to_copy/_num_outputs; +        // extract the number of samples available to copy +        const size_t nsamps_available = info.data_bytes_to_copy / _bytes_per_otw_item; +        const size_t nsamps_to_copy = +            std::min(nsamps_per_buff * _num_outputs, nsamps_available); +        const size_t bytes_to_copy              = nsamps_to_copy * _bytes_per_otw_item; +        const size_t nsamps_to_copy_per_io_buff = nsamps_to_copy / _num_outputs; -        //setup the data to share with converter threads -        _convert_nsamps = nsamps_to_copy_per_io_buff; -        _convert_buffs = &buffs; +        // setup the data to share with converter threads +        _convert_nsamps              = nsamps_to_copy_per_io_buff; +        _convert_buffs               = &buffs;          _convert_buffer_offset_bytes = buffer_offset_bytes; -        _convert_bytes_to_copy = bytes_to_copy; +        _convert_bytes_to_copy       = bytes_to_copy; -        //perform N channels of conversion +        // perform N channels of conversion          for (size_t i = 0; i < this->size(); i++) {              convert_to_out_buff(i);          } -        //update the copy buffer's availability +        // update the copy buffer's availability          info.data_bytes_to_copy -= bytes_to_copy; -        //setup the fragment flags and offset -        metadata.more_fragments = info.data_bytes_to_copy != 0; +        // setup the fragment flags and offset +        metadata.more_fragments  = info.data_bytes_to_copy != 0;          metadata.fragment_offset = info.fragment_offset_in_samps; -        info.fragment_offset_in_samps += nsamps_to_copy; //set for next call +        info.fragment_offset_in_samps += nsamps_to_copy; // set for next call          return nsamps_to_copy_per_io_buff;      } @@ -736,34 +781,34 @@ private:       */      inline void convert_to_out_buff(const size_t index)      { -        //shortcut references to local data structures -        buffers_info_type &buff_info = get_curr_buffer_info(); -        per_buffer_info_type &info = buff_info[index]; -        const rx_streamer::buffs_type &buffs = *_convert_buffs; - -        //fill IO buffs with pointers into the output buffer -        void *io_buffs[4/*max interleave*/]; -        for (size_t i = 0; i < _num_outputs; i++){ -            char *b = reinterpret_cast<char *>(buffs[index*_num_outputs + i]); +        // shortcut references to local data structures +        buffers_info_type& buff_info         = get_curr_buffer_info(); +        per_buffer_info_type& info           = buff_info[index]; +        const rx_streamer::buffs_type& buffs = *_convert_buffs; + +        // fill IO buffs with pointers into the output buffer +        void* io_buffs[4 /*max interleave*/]; +        for (size_t i = 0; i < _num_outputs; i++) { +            char* b     = reinterpret_cast<char*>(buffs[index * _num_outputs + i]);              io_buffs[i] = b + _convert_buffer_offset_bytes;          } -        const ref_vector<void *> out_buffs(io_buffs, _num_outputs); +        const ref_vector<void*> out_buffs(io_buffs, _num_outputs); -        //perform the conversion operation +        // perform the conversion operation          _converter->conv(info.copy_buff, out_buffs, _convert_nsamps); -        //advance the pointer for the source buffer +        // advance the pointer for the source buffer          info.copy_buff += _convert_bytes_to_copy; -        //release the buffer if fully consumed -        if (buff_info.data_bytes_to_copy == _convert_bytes_to_copy){ -            info.buff.reset(); //effectively a release +        // release the buffer if fully consumed +        if (buff_info.data_bytes_to_copy == _convert_bytes_to_copy) { +            info.buff.reset(); // effectively a release          }      }      //! Shared variables for the worker threads      size_t _convert_nsamps; -    const rx_streamer::buffs_type *_convert_buffs; +    const rx_streamer::buffs_type* _convert_buffs;      size_t _convert_buffer_offset_bytes;      size_t _convert_bytes_to_copy; @@ -773,10 +818,24 @@ private:       * Gathered data can be used to post process it with external tools.       */  #ifdef UHD_TXRX_DEBUG_PRINTS -    struct dbg_recv_stat_t { -        dbg_recv_stat_t(long wc, size_t nspb, size_t nsr, uhd::rx_metadata_t md, double to, bool op, double rate): -        wallclock(wc), nsamps_per_buff(nspb), nsamps_recv(nsr), metadata(md), timeout(to), one_packet(op), samp_rate(rate) -        {} +    struct dbg_recv_stat_t +    { +        dbg_recv_stat_t(long wc, +            size_t nspb, +            size_t nsr, +            uhd::rx_metadata_t md, +            double to, +            bool op, +            double rate) +            : wallclock(wc) +            , nsamps_per_buff(nspb) +            , nsamps_recv(nsr) +            , metadata(md) +            , timeout(to) +            , one_packet(op) +            , samp_rate(rate) +        { +        }          long wallclock;          size_t nsamps_per_buff;          size_t nsamps_recv; @@ -785,42 +844,47 @@ private:          bool one_packet;          double samp_rate;          // Create a formatted print line for all the info gathered in this struct. -        std::string print_line() { +        std::string print_line() +        {              boost::format fmt("recv,%ld,%f,%i,%i,%s,%i,%s,%s,%s,%i,%s,%ld");              fmt % wallclock; -            fmt % timeout % (int)nsamps_per_buff % (int) nsamps_recv; -            fmt % (one_packet ? "true":"false"); +            fmt % timeout % (int)nsamps_per_buff % (int)nsamps_recv; +            fmt % (one_packet ? "true" : "false");              fmt % metadata.error_code; -            fmt % (metadata.start_of_burst ? "true":"false") % (metadata.end_of_burst ? "true":"false"); -            fmt % (metadata.more_fragments ? "true":"false") % (int)metadata.fragment_offset; -            fmt % (metadata.has_time_spec ? "true":"false") % metadata.time_spec.to_ticks(samp_rate); +            fmt % (metadata.start_of_burst ? "true" : "false") +                % (metadata.end_of_burst ? "true" : "false"); +            fmt % (metadata.more_fragments ? "true" : "false") +                % (int)metadata.fragment_offset; +            fmt % (metadata.has_time_spec ? "true" : "false") +                % metadata.time_spec.to_ticks(samp_rate);              return fmt.str();          }      }; -    void dbg_gather_data(const size_t nsamps_per_buff, const size_t nsamps_recv, -            uhd::rx_metadata_t &metadata, const double timeout, -            const bool one_packet, -            bool dbg_print_directly = true -        ) +    void dbg_gather_data(const size_t nsamps_per_buff, +        const size_t nsamps_recv, +        uhd::rx_metadata_t& metadata, +        const double timeout, +        const bool one_packet, +        bool dbg_print_directly = true)      { -        // Initialize a struct with all available data. It can return a formatted string with all infos if wanted. +        // Initialize a struct with all available data. It can return a formatted string +        // with all infos if wanted.          dbg_recv_stat_t data(boost::get_system_time().time_of_day().total_microseconds(), -                nsamps_per_buff, -                nsamps_recv, -                metadata, -                timeout, -                one_packet, -                _samp_rate -            ); -        if(dbg_print_directly) { +            nsamps_per_buff, +            nsamps_recv, +            metadata, +            timeout, +            one_packet, +            _samp_rate); +        if (dbg_print_directly) {              dbg_print_err(data.print_line());          }      } - -    void dbg_print_err(std::string msg) { +    void dbg_print_err(std::string msg) +    {          std::string dbg_prefix("super_recv_packet_handler,");          msg = dbg_prefix + msg;          fprintf(stderr, "%s\n", msg.c_str()); @@ -828,31 +892,35 @@ private:  #endif  }; -class recv_packet_streamer : public recv_packet_handler, public rx_streamer{ +class recv_packet_streamer : public recv_packet_handler, public rx_streamer +{  public: -    recv_packet_streamer(const size_t max_num_samps){ +    recv_packet_streamer(const size_t max_num_samps) +    {          _max_num_samps = max_num_samps;      } -    size_t get_num_channels(void) const{ +    size_t get_num_channels(void) const +    {          return this->size();      } -    size_t get_max_num_samps(void) const{ +    size_t get_max_num_samps(void) const +    {          return _max_num_samps;      } -    size_t recv( -        const rx_streamer::buffs_type &buffs, +    size_t recv(const rx_streamer::buffs_type& buffs,          const size_t nsamps_per_buff, -        uhd::rx_metadata_t &metadata, +        uhd::rx_metadata_t& metadata,          const double timeout, -        const bool one_packet -    ){ -        return recv_packet_handler::recv(buffs, nsamps_per_buff, metadata, timeout, one_packet); +        const bool one_packet) +    { +        return recv_packet_handler::recv( +            buffs, nsamps_per_buff, metadata, timeout, one_packet);      } -    void issue_stream_cmd(const stream_cmd_t &stream_cmd) +    void issue_stream_cmd(const stream_cmd_t& stream_cmd)      {          return recv_packet_handler::issue_stream_cmd(stream_cmd);      } @@ -861,6 +929,6 @@ private:      size_t _max_num_samps;  }; -}}} //namespace +}}} // namespace uhd::transport::sph  #endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_RECV_PACKET_HANDLER_HPP */ diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index b90ea8afd..af6ecaa5e 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -9,34 +9,32 @@  #define INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP  #include <uhd/config.hpp> -#include <uhd/exception.hpp>  #include <uhd/convert.hpp> +#include <uhd/exception.hpp>  #include <uhd/stream.hpp> -#include <uhd/utils/tasks.hpp> -#include <uhd/utils/byteswap.hpp> -#include <uhd/utils/thread.hpp> -#include <uhd/types/metadata.hpp>  #include <uhd/transport/vrt_if_packet.hpp>  #include <uhd/transport/zero_copy.hpp> +#include <uhd/types/metadata.hpp> +#include <uhd/utils/byteswap.hpp> +#include <uhd/utils/tasks.hpp> +#include <uhd/utils/thread.hpp>  #include <uhdlib/rfnoc/tx_stream_terminator.hpp>  #include <boost/function.hpp> -#include <iostream> -#include <vector>  #include <chrono> +#include <iostream>  #include <thread> +#include <vector>  #ifdef UHD_TXRX_DEBUG_PRINTS  // Included for debugging -#include <boost/format.hpp> -#include <boost/thread/thread.hpp> -#include "boost/date_time/posix_time/posix_time.hpp" -#include <map> -#include <fstream> +#    include "boost/date_time/posix_time/posix_time.hpp" +#    include <boost/format.hpp> +#    include <boost/thread/thread.hpp> +#    include <fstream> +#    include <map>  #endif -namespace uhd { -namespace transport { -namespace sph { +namespace uhd { namespace transport { namespace sph {  /***********************************************************************   * Super send packet handler @@ -45,52 +43,61 @@ namespace sph {   * The channel group shares a common sample rate.   * All channels are sent in unison in send().   **********************************************************************/ -class send_packet_handler{ +class send_packet_handler +{  public:      typedef std::function<managed_send_buffer::sptr(double)> get_buff_type;      typedef std::function<void(void)> post_send_cb_type; -    typedef std::function<bool(uhd::async_metadata_t &, const double)> async_receiver_type; -    typedef void(*vrt_packer_type)(uint32_t *, vrt::if_packet_info_t &); -    //typedef std::function<void(uint32_t *, vrt::if_packet_info_t &)> vrt_packer_type; +    typedef std::function<bool(uhd::async_metadata_t&, const double)> async_receiver_type; +    typedef void (*vrt_packer_type)(uint32_t*, vrt::if_packet_info_t&); +    // typedef std::function<void(uint32_t *, vrt::if_packet_info_t &)> vrt_packer_type;      /*!       * Make a new packet handler for send       * \param size the number of transport channels       */ -    send_packet_handler(const size_t size = 1): -        _next_packet_seq(0), _cached_metadata(false) +    send_packet_handler(const size_t size = 1) +        : _next_packet_seq(0), _cached_metadata(false)      {          this->set_enable_trailer(true);          this->resize(size);      } -    ~send_packet_handler(void){ +    ~send_packet_handler(void) +    {          /* NOP */      }      //! Resize the number of transport channels -    void resize(const size_t size){ -        if (this->size() == size) return; +    void resize(const size_t size) +    { +        if (this->size() == size) +            return;          _props.resize(size);          static const uint64_t zero = 0;          _zero_buffs.resize(size, &zero);      }      //! Get the channel width of this handler -    size_t size(void) const{ +    size_t size(void) const +    {          return _props.size();      }      //! Setup the vrt packer function and offset -    void set_vrt_packer(const vrt_packer_type &vrt_packer, const size_t header_offset_words32 = 0){ -        _vrt_packer = vrt_packer; +    void set_vrt_packer( +        const vrt_packer_type& vrt_packer, const size_t header_offset_words32 = 0) +    { +        _vrt_packer            = vrt_packer;          _header_offset_words32 = header_offset_words32;      }      //! Set the stream ID for a specific channel (or no SID) -    void set_xport_chan_sid(const size_t xport_chan, const bool has_sid, const uint32_t sid = 0){ +    void set_xport_chan_sid( +        const size_t xport_chan, const bool has_sid, const uint32_t sid = 0) +    {          _props.at(xport_chan).has_sid = has_sid; -        _props.at(xport_chan).sid = sid; +        _props.at(xport_chan).sid     = sid;      }      void set_enable_trailer(const bool enable) @@ -99,12 +106,14 @@ public:      }      //! Set the rate of ticks per second -    void set_tick_rate(const double rate){ +    void set_tick_rate(const double rate) +    {          _tick_rate = rate;      }      //! Set the rate of samples per second -    void set_samp_rate(const double rate){ +    void set_samp_rate(const double rate) +    {          _samp_rate = rate;      } @@ -113,7 +122,8 @@ public:       * \param xport_chan which transport channel       * \param get_buff the getter function       */ -    void set_xport_chan_get_buff(const size_t xport_chan, const get_buff_type &get_buff){ +    void set_xport_chan_get_buff(const size_t xport_chan, const get_buff_type& get_buff) +    {          _props.at(xport_chan).get_buff = get_buff;      } @@ -122,15 +132,17 @@ public:       * \param xport_chan which transport channel       * \param cb post-send callback       */ -    void set_xport_chan_post_send_cb(const size_t xport_chan, const post_send_cb_type &cb){ +    void set_xport_chan_post_send_cb(const size_t xport_chan, const post_send_cb_type& cb) +    {          _props.at(xport_chan).go_postal = cb;      }      //! Set the conversion routine for all channels -    void set_converter(const uhd::convert::id_type &id){ +    void set_converter(const uhd::convert::id_type& id) +    {          _num_inputs = id.num_inputs; -        _converter = uhd::convert::get_converter(id)(); -        this->set_scale_factor(32767.); //update after setting converter +        _converter  = uhd::convert::get_converter(id)(); +        this->set_scale_factor(32767.); // update after setting converter          _bytes_per_otw_item = uhd::convert::get_bytes_per_item(id.output_format);          _bytes_per_cpu_item = uhd::convert::get_bytes_per_item(id.input_format);      } @@ -140,27 +152,29 @@ public:       * Ex: A USRP1 in dual channel mode would be half.       * \param num_samps the maximum samples in a packet       */ -    void set_max_samples_per_packet(const size_t num_samps){ +    void set_max_samples_per_packet(const size_t num_samps) +    {          _max_samples_per_packet = num_samps;      }      //! Set the scale factor used in float conversion -    void set_scale_factor(const double scale_factor){ +    void set_scale_factor(const double scale_factor) +    {          _converter->set_scalar(scale_factor);      }      //! Set the callback to get async messages -    void set_async_receiver(const async_receiver_type &async_receiver) +    void set_async_receiver(const async_receiver_type& async_receiver)      {          _async_receiver = async_receiver;      }      //! Overload call to get async metadata -    bool recv_async_msg( -        uhd::async_metadata_t &async_metadata, double timeout = 0.1 -    ){ -        if (_async_receiver) return _async_receiver(async_metadata, timeout); -        std::this_thread::sleep_for(std::chrono::microseconds(long(timeout*1e6))); +    bool recv_async_msg(uhd::async_metadata_t& async_metadata, double timeout = 0.1) +    { +        if (_async_receiver) +            return _async_receiver(async_metadata, timeout); +        std::this_thread::sleep_for(std::chrono::microseconds(long(timeout * 1e6)));          return false;      } @@ -169,16 +183,15 @@ public:       * The entry point for the fast-path send calls.       * Dispatch into combinations of single packet send calls.       ******************************************************************/ -    UHD_INLINE size_t send( -        const uhd::tx_streamer::buffs_type &buffs, +    UHD_INLINE size_t send(const uhd::tx_streamer::buffs_type& buffs,          const size_t nsamps_per_buff, -        const uhd::tx_metadata_t &metadata, -        const double timeout -    ){ -        //translate the metadata to vrt if packet info +        const uhd::tx_metadata_t& metadata, +        const double timeout) +    { +        // translate the metadata to vrt if packet info          vrt::if_packet_info_t if_packet_info;          if_packet_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; -        //if_packet_info.has_sid = false; //set per channel +        // if_packet_info.has_sid = false; //set per channel          if_packet_info.has_cid = false;          if_packet_info.has_tlr = _has_tlr;          if_packet_info.has_tsi = false; @@ -186,99 +199,102 @@ public:          if_packet_info.tsf     = metadata.time_spec.to_ticks(_tick_rate);          if_packet_info.sob     = metadata.start_of_burst;          if_packet_info.eob     = metadata.end_of_burst; -        if_packet_info.fc_ack  = false; //This is a data packet +        if_packet_info.fc_ack  = false; // This is a data packet          /* -         * Metadata is cached when we get a send requesting a start of burst with no samples. -         * It is applied here on the next call to send() that actually has samples to send. +         * Metadata is cached when we get a send requesting a start of burst with no +         * samples. It is applied here on the next call to send() that actually has +         * samples to send.           */ -        if (_cached_metadata && nsamps_per_buff != 0) -        { +        if (_cached_metadata && nsamps_per_buff != 0) {              // If the new metada has a time_spec, do not use the cached time_spec. -            if (!metadata.has_time_spec) -            { +            if (!metadata.has_time_spec) {                  if_packet_info.has_tsf = _metadata_cache.has_time_spec;                  if_packet_info.tsf     = _metadata_cache.time_spec.to_ticks(_tick_rate);              } -            if_packet_info.sob     = _metadata_cache.start_of_burst; -            if_packet_info.eob     = _metadata_cache.end_of_burst; -            _cached_metadata = false; +            if_packet_info.sob = _metadata_cache.start_of_burst; +            if_packet_info.eob = _metadata_cache.end_of_burst; +            _cached_metadata   = false;          } -        if (nsamps_per_buff <= _max_samples_per_packet){ - -            //TODO remove this code when sample counts of zero are supported by hardware -            #ifndef SSPH_DONT_PAD_TO_ONE -                static const uint64_t zero = 0; -                _zero_buffs.resize(buffs.size(), &zero); - -                if (nsamps_per_buff == 0) -                { -                    // if this is a start of a burst and there are no samples -                    if (metadata.start_of_burst) -                    { -                        // cache metadata and apply on the next send() -                        _metadata_cache = metadata; -                        _cached_metadata = true; -                        return 0; -                    } else { -                        // send requests with no samples are handled here (such as end of burst) -                        return send_one_packet(_zero_buffs, 1, if_packet_info, timeout) & 0x0; -                    } +        if (nsamps_per_buff <= _max_samples_per_packet) { +// TODO remove this code when sample counts of zero are supported by hardware +#ifndef SSPH_DONT_PAD_TO_ONE +            static const uint64_t zero = 0; +            _zero_buffs.resize(buffs.size(), &zero); + +            if (nsamps_per_buff == 0) { +                // if this is a start of a burst and there are no samples +                if (metadata.start_of_burst) { +                    // cache metadata and apply on the next send() +                    _metadata_cache  = metadata; +                    _cached_metadata = true; +                    return 0; +                } else { +                    // send requests with no samples are handled here (such as end of +                    // burst) +                    return send_one_packet(_zero_buffs, 1, if_packet_info, timeout) & 0x0;                  } -            #endif +            } +#endif -			size_t nsamps_sent = send_one_packet(buffs, nsamps_per_buff, if_packet_info, timeout); +            size_t nsamps_sent = +                send_one_packet(buffs, nsamps_per_buff, if_packet_info, timeout);  #ifdef UHD_TXRX_DEBUG_PRINTS -			dbg_print_send(nsamps_per_buff, nsamps_sent, metadata, timeout); +            dbg_print_send(nsamps_per_buff, nsamps_sent, metadata, timeout);  #endif -			return nsamps_sent;        } +            return nsamps_sent; +        }          size_t total_num_samps_sent = 0; -        //false until final fragment +        // false until final fragment          if_packet_info.eob = false; -        const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet; -        const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1; - -        //loop through the following fragment indexes -        for (size_t i = 0; i < num_fragments; i++){ - -            //send a fragment with the helper function -            const size_t num_samps_sent = send_one_packet( -                buffs, _max_samples_per_packet, -                if_packet_info, timeout, -                total_num_samps_sent*_bytes_per_cpu_item -            ); +        const size_t num_fragments = (nsamps_per_buff - 1) / _max_samples_per_packet; +        const size_t final_length = ((nsamps_per_buff - 1) % _max_samples_per_packet) + 1; + +        // loop through the following fragment indexes +        for (size_t i = 0; i < num_fragments; i++) { +            // send a fragment with the helper function +            const size_t num_samps_sent = send_one_packet(buffs, +                _max_samples_per_packet, +                if_packet_info, +                timeout, +                total_num_samps_sent * _bytes_per_cpu_item);              total_num_samps_sent += num_samps_sent; -            if (num_samps_sent == 0) return total_num_samps_sent; +            if (num_samps_sent == 0) +                return total_num_samps_sent; -            //setup metadata for the next fragment -            const time_spec_t time_spec = metadata.time_spec + time_spec_t::from_ticks(total_num_samps_sent, _samp_rate); +            // setup metadata for the next fragment +            const time_spec_t time_spec = +                metadata.time_spec +                + time_spec_t::from_ticks(total_num_samps_sent, _samp_rate);              if_packet_info.tsf = time_spec.to_ticks(_tick_rate);              if_packet_info.sob = false; -          } -        //send the final fragment with the helper function +        // send the final fragment with the helper function          if_packet_info.eob = metadata.end_of_burst; -		size_t nsamps_sent = total_num_samps_sent -				+ send_one_packet(buffs, final_length, if_packet_info, timeout, -					total_num_samps_sent * _bytes_per_cpu_item); +        size_t nsamps_sent = total_num_samps_sent +                             + send_one_packet(buffs, +                                   final_length, +                                   if_packet_info, +                                   timeout, +                                   total_num_samps_sent * _bytes_per_cpu_item);  #ifdef UHD_TXRX_DEBUG_PRINTS -		dbg_print_send(nsamps_per_buff, nsamps_sent, metadata, timeout); +        dbg_print_send(nsamps_per_buff, nsamps_sent, metadata, timeout);  #endif -		return nsamps_sent; +        return nsamps_sent;      }  private: -      vrt_packer_type _vrt_packer;      size_t _header_offset_words32;      double _tick_rate, _samp_rate; -    struct xport_chan_props_type{ -        xport_chan_props_type(void):has_sid(false),sid(0){} +    struct xport_chan_props_type +    { +        xport_chan_props_type(void) : has_sid(false), sid(0) {}          get_buff_type get_buff;          post_send_cb_type go_postal;          bool has_sid; @@ -287,11 +303,11 @@ private:      };      std::vector<xport_chan_props_type> _props;      size_t _num_inputs; -    size_t _bytes_per_otw_item; //used in conversion -    size_t _bytes_per_cpu_item; //used in conversion -    uhd::convert::converter::sptr _converter; //used in conversion +    size_t _bytes_per_otw_item; // used in conversion +    size_t _bytes_per_cpu_item; // used in conversion +    uhd::convert::converter::sptr _converter; // used in conversion      size_t _max_samples_per_packet; -    std::vector<const void *> _zero_buffs; +    std::vector<const void*> _zero_buffs;      size_t _next_packet_seq;      bool _has_tlr;      async_receiver_type _async_receiver; @@ -299,10 +315,22 @@ private:      uhd::tx_metadata_t _metadata_cache;  #ifdef UHD_TXRX_DEBUG_PRINTS -    struct dbg_send_stat_t { -        dbg_send_stat_t(long wc, size_t nspb, size_t nss, uhd::tx_metadata_t md, double to, double rate): -            wallclock(wc), nsamps_per_buff(nspb), nsamps_sent(nss), metadata(md), timeout(to), samp_rate(rate) -        {} +    struct dbg_send_stat_t +    { +        dbg_send_stat_t(long wc, +            size_t nspb, +            size_t nss, +            uhd::tx_metadata_t md, +            double to, +            double rate) +            : wallclock(wc) +            , nsamps_per_buff(nspb) +            , nsamps_sent(nss) +            , metadata(md) +            , timeout(to) +            , samp_rate(rate) +        { +        }          long wallclock;          size_t nsamps_per_buff;          size_t nsamps_sent; @@ -310,32 +338,37 @@ private:          double timeout;          double samp_rate;          // Create a formatted print line for all the info gathered in this struct. -        std::string print_line() { +        std::string print_line() +        {              boost::format fmt("send,%ld,%f,%i,%i,%s,%s,%s,%ld");              fmt % wallclock; -            fmt % timeout % (int)nsamps_per_buff % (int) nsamps_sent; -            fmt % (metadata.start_of_burst ? "true":"false") % (metadata.end_of_burst ? "true":"false"); -            fmt % (metadata.has_time_spec ? "true":"false") % metadata.time_spec.to_ticks(samp_rate); +            fmt % timeout % (int)nsamps_per_buff % (int)nsamps_sent; +            fmt % (metadata.start_of_burst ? "true" : "false") +                % (metadata.end_of_burst ? "true" : "false"); +            fmt % (metadata.has_time_spec ? "true" : "false") +                % metadata.time_spec.to_ticks(samp_rate);              return fmt.str();          }      }; -    void dbg_print_send(size_t nsamps_per_buff, size_t nsamps_sent, -            const uhd::tx_metadata_t &metadata, const double timeout, -            bool dbg_print_directly = true) +    void dbg_print_send(size_t nsamps_per_buff, +        size_t nsamps_sent, +        const uhd::tx_metadata_t& metadata, +        const double timeout, +        bool dbg_print_directly = true)      {          dbg_send_stat_t data(boost::get_system_time().time_of_day().total_microseconds(),              nsamps_per_buff,              nsamps_sent,              metadata,              timeout, -            _samp_rate -        ); -        if(dbg_print_directly){ +            _samp_rate); +        if (dbg_print_directly) {              dbg_print_err(data.print_line());          }      } -    void dbg_print_err(std::string msg) { +    void dbg_print_err(std::string msg) +    {          msg = "super_send_packet_handler," + msg;          fprintf(stderr, "%s\n", msg.c_str());      } @@ -346,37 +379,39 @@ private:      /*******************************************************************       * Send a single packet:       ******************************************************************/ -    UHD_INLINE size_t send_one_packet( -        const uhd::tx_streamer::buffs_type &buffs, +    UHD_INLINE size_t send_one_packet(const uhd::tx_streamer::buffs_type& buffs,          const size_t nsamps_per_buff, -        vrt::if_packet_info_t &if_packet_info, +        vrt::if_packet_info_t& if_packet_info,          const double timeout, -        const size_t buffer_offset_bytes = 0 -    ){ - -        //load the rest of the if_packet_info in here -        if_packet_info.num_payload_bytes = nsamps_per_buff*_num_inputs*_bytes_per_otw_item; -        if_packet_info.num_payload_words32 = (if_packet_info.num_payload_bytes + 3/*round up*/)/sizeof(uint32_t); +        const size_t buffer_offset_bytes = 0) +    { +        // load the rest of the if_packet_info in here +        if_packet_info.num_payload_bytes = +            nsamps_per_buff * _num_inputs * _bytes_per_otw_item; +        if_packet_info.num_payload_words32 = +            (if_packet_info.num_payload_bytes + 3 /*round up*/) / sizeof(uint32_t);          if_packet_info.packet_count = _next_packet_seq; -        //get a buffer for each channel or timeout -        BOOST_FOREACH(xport_chan_props_type &props, _props){ -            if (not props.buff) props.buff = props.get_buff(timeout); -            if (not props.buff) return 0; //timeout +        // get a buffer for each channel or timeout +        BOOST_FOREACH (xport_chan_props_type& props, _props) { +            if (not props.buff) +                props.buff = props.get_buff(timeout); +            if (not props.buff) +                return 0; // timeout          } -        //setup the data to share with converter threads -        _convert_nsamps = nsamps_per_buff; -        _convert_buffs = &buffs; +        // setup the data to share with converter threads +        _convert_nsamps              = nsamps_per_buff; +        _convert_buffs               = &buffs;          _convert_buffer_offset_bytes = buffer_offset_bytes; -        _convert_if_packet_info = &if_packet_info; +        _convert_if_packet_info      = &if_packet_info; -        //perform N channels of conversion +        // perform N channels of conversion          for (size_t i = 0; i < this->size(); i++) {              convert_to_in_buff(i);          } -        _next_packet_seq++; //increment sequence after commits +        _next_packet_seq++; // increment sequence after commits          return nsamps_per_buff;      } @@ -389,75 +424,76 @@ private:       */      UHD_INLINE void convert_to_in_buff(const size_t index)      { -        //shortcut references to local data structures -        managed_send_buffer::sptr &buff = _props[index].buff; +        // shortcut references to local data structures +        managed_send_buffer::sptr& buff      = _props[index].buff;          vrt::if_packet_info_t if_packet_info = *_convert_if_packet_info; -        const tx_streamer::buffs_type &buffs = *_convert_buffs; +        const tx_streamer::buffs_type& buffs = *_convert_buffs; -        //fill IO buffs with pointers into the output buffer -        const void *io_buffs[4/*max interleave*/]; -        for (size_t i = 0; i < _num_inputs; i++){ -            const char *b = reinterpret_cast<const char *>(buffs[index*_num_inputs + i]); -            io_buffs[i] = b + _convert_buffer_offset_bytes; +        // fill IO buffs with pointers into the output buffer +        const void* io_buffs[4 /*max interleave*/]; +        for (size_t i = 0; i < _num_inputs; i++) { +            const char* b = reinterpret_cast<const char*>(buffs[index * _num_inputs + i]); +            io_buffs[i]   = b + _convert_buffer_offset_bytes;          } -        const ref_vector<const void *> in_buffs(io_buffs, _num_inputs); +        const ref_vector<const void*> in_buffs(io_buffs, _num_inputs); -        //pack metadata into a vrt header -        uint32_t *otw_mem = buff->cast<uint32_t *>() + _header_offset_words32; +        // pack metadata into a vrt header +        uint32_t* otw_mem      = buff->cast<uint32_t*>() + _header_offset_words32;          if_packet_info.has_sid = _props[index].has_sid; -        if_packet_info.sid = _props[index].sid; +        if_packet_info.sid     = _props[index].sid;          _vrt_packer(otw_mem, if_packet_info);          otw_mem += if_packet_info.num_header_words32; -        //perform the conversion operation +        // perform the conversion operation          _converter->conv(in_buffs, otw_mem, _convert_nsamps); -        //commit the samples to the zero-copy interface -        const size_t num_vita_words32 = _header_offset_words32+if_packet_info.num_packet_words32; -        buff->commit(num_vita_words32*sizeof(uint32_t)); -        buff.reset(); //effectively a release +        // commit the samples to the zero-copy interface +        const size_t num_vita_words32 = +            _header_offset_words32 + if_packet_info.num_packet_words32; +        buff->commit(num_vita_words32 * sizeof(uint32_t)); +        buff.reset(); // effectively a release -        if (_props[index].go_postal) -        { +        if (_props[index].go_postal) {              _props[index].go_postal();          }      }      //! Shared variables for the worker threads      size_t _convert_nsamps; -    const tx_streamer::buffs_type *_convert_buffs; +    const tx_streamer::buffs_type* _convert_buffs;      size_t _convert_buffer_offset_bytes; -    vrt::if_packet_info_t *_convert_if_packet_info; - +    vrt::if_packet_info_t* _convert_if_packet_info;  }; -class send_packet_streamer : public send_packet_handler, public tx_streamer{ +class send_packet_streamer : public send_packet_handler, public tx_streamer +{  public: -    send_packet_streamer(const size_t max_num_samps){ +    send_packet_streamer(const size_t max_num_samps) +    {          _max_num_samps = max_num_samps;          this->set_max_samples_per_packet(_max_num_samps);      } -    size_t get_num_channels(void) const{ +    size_t get_num_channels(void) const +    {          return this->size();      } -    size_t get_max_num_samps(void) const{ +    size_t get_max_num_samps(void) const +    {          return _max_num_samps;      } -    size_t send( -        const tx_streamer::buffs_type &buffs, +    size_t send(const tx_streamer::buffs_type& buffs,          const size_t nsamps_per_buff, -        const uhd::tx_metadata_t &metadata, -        const double timeout -    ){ +        const uhd::tx_metadata_t& metadata, +        const double timeout) +    {          return send_packet_handler::send(buffs, nsamps_per_buff, metadata, timeout);      } -    bool recv_async_msg( -        uhd::async_metadata_t &async_metadata, double timeout = 0.1 -    ){ +    bool recv_async_msg(uhd::async_metadata_t& async_metadata, double timeout = 0.1) +    {          return send_packet_handler::recv_async_msg(async_metadata, timeout);      } @@ -465,8 +501,6 @@ private:      size_t _max_num_samps;  }; -} // namespace sph -} // namespace transport -} // namespace uhd +}}} // namespace uhd::transport::sph  #endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP */ diff --git a/host/lib/transport/tcp_zero_copy.cpp b/host/lib/transport/tcp_zero_copy.cpp index a52d089a8..5cb713427 100644 --- a/host/lib/transport/tcp_zero_copy.cpp +++ b/host/lib/transport/tcp_zero_copy.cpp @@ -6,15 +6,15 @@  //  #include "udp_common.hpp" -#include <uhd/transport/tcp_zero_copy.hpp>  #include <uhd/transport/buffer_pool.hpp> +#include <uhd/transport/tcp_zero_copy.hpp>  #include <uhd/utils/log.hpp>  #include <uhdlib/utils/atomic.hpp>  #include <boost/format.hpp>  #include <boost/make_shared.hpp> -#include <vector>  #include <chrono>  #include <thread> +#include <vector>  using namespace uhd;  using namespace uhd::transport; @@ -27,38 +27,44 @@ static const size_t DEFAULT_FRAME_SIZE = 2048;   * Reusable managed receiver buffer:   *  - get_new performs the recv operation   **********************************************************************/ -class tcp_zero_copy_asio_mrb : public managed_recv_buffer{ +class tcp_zero_copy_asio_mrb : public managed_recv_buffer +{  public: -    tcp_zero_copy_asio_mrb(void *mem, int sock_fd, const size_t frame_size): -        _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) { /*NOP*/ } +    tcp_zero_copy_asio_mrb(void* mem, int sock_fd, const size_t frame_size) +        : _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) +    { /*NOP*/ +    } -    void release(void){ +    void release(void) +    {          _claimer.release();      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index){ -        if (not _claimer.claim_with_wait(timeout)) return sptr(); +    UHD_INLINE sptr get_new(const double timeout, size_t& index) +    { +        if (not _claimer.claim_with_wait(timeout)) +            return sptr(); -        #ifdef MSG_DONTWAIT //try a non-blocking recv() if supported -        _len = ::recv(_sock_fd, (char *)_mem, _frame_size, MSG_DONTWAIT); -        if (_len > 0){ -            index++; //advances the caller's buffer +#ifdef MSG_DONTWAIT // try a non-blocking recv() if supported +        _len = ::recv(_sock_fd, (char*)_mem, _frame_size, MSG_DONTWAIT); +        if (_len > 0) { +            index++; // advances the caller's buffer              return make(this, _mem, size_t(_len));          } -        #endif +#endif -        if (wait_for_recv_ready(_sock_fd, timeout)){ -            _len = ::recv(_sock_fd, (char *)_mem, _frame_size, 0); -            index++; //advances the caller's buffer +        if (wait_for_recv_ready(_sock_fd, timeout)) { +            _len = ::recv(_sock_fd, (char*)_mem, _frame_size, 0); +            index++; // advances the caller's buffer              return make(this, _mem, size_t(_len));          } -        _claimer.release(); //undo claim -        return sptr(); //null for timeout +        _claimer.release(); // undo claim +        return sptr(); // null for timeout      }  private: -    void *_mem; +    void* _mem;      int _sock_fd;      size_t _frame_size;      ssize_t _len; @@ -69,44 +75,50 @@ private:   * Reusable managed send buffer:   *  - commit performs the send operation   **********************************************************************/ -class tcp_zero_copy_asio_msb : public managed_send_buffer{ +class tcp_zero_copy_asio_msb : public managed_send_buffer +{  public: -    tcp_zero_copy_asio_msb(void *mem, int sock_fd, const size_t frame_size): -        _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) { /*NOP*/ } - -    void release(void){ -        //Retry logic because send may fail with ENOBUFS. -        //This is known to occur at least on some OSX systems. -        //But it should be safe to always check for the error. -        while (true) -        { -            this->commit(_frame_size); //always full size frames to avoid pkt coalescing -            const ssize_t ret = ::send(_sock_fd, (const char *)_mem, size(), 0); -            if (ret == ssize_t(size())) break; -            if (ret == -1 and errno == ENOBUFS) -            { +    tcp_zero_copy_asio_msb(void* mem, int sock_fd, const size_t frame_size) +        : _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) +    { /*NOP*/ +    } + +    void release(void) +    { +        // Retry logic because send may fail with ENOBUFS. +        // This is known to occur at least on some OSX systems. +        // But it should be safe to always check for the error. +        while (true) { +            this->commit(_frame_size); // always full size frames to avoid pkt coalescing +            const ssize_t ret = ::send(_sock_fd, (const char*)_mem, size(), 0); +            if (ret == ssize_t(size())) +                break; +            if (ret == -1 and errno == ENOBUFS) {                  std::this_thread::sleep_for(std::chrono::microseconds(1)); -                continue; //try to send again +                continue; // try to send again              }              UHD_ASSERT_THROW(ret == ssize_t(size()));          }          _claimer.release();      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index){ -        if (not _claimer.claim_with_wait(timeout)) return sptr(); -        index++; //advances the caller's buffer +    UHD_INLINE sptr get_new(const double timeout, size_t& index) +    { +        if (not _claimer.claim_with_wait(timeout)) +            return sptr(); +        index++; // advances the caller's buffer          return make(this, _mem, _frame_size);      }  private: -    void *_mem; +    void* _mem;      int _sock_fd;      size_t _frame_size;      simple_claimer _claimer;  }; -tcp_zero_copy::~tcp_zero_copy(void){ +tcp_zero_copy::~tcp_zero_copy(void) +{      /* NOP */  } @@ -117,51 +129,53 @@ tcp_zero_copy::~tcp_zero_copy(void){   *   However, it is not a true zero copy implementation as each   *   send and recv requires a copy operation to/from userspace.   **********************************************************************/ -class tcp_zero_copy_asio_impl : public tcp_zero_copy{ +class tcp_zero_copy_asio_impl : public tcp_zero_copy +{  public:      typedef boost::shared_ptr<tcp_zero_copy_asio_impl> sptr;      tcp_zero_copy_asio_impl( -        const std::string &addr, -        const std::string &port, -        const device_addr_t &hints -    ): -        _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", DEFAULT_FRAME_SIZE))), -        _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_FRAMES))), -        _send_frame_size(size_t(hints.cast<double>("send_frame_size", DEFAULT_FRAME_SIZE))), -        _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_FRAMES))), -        _recv_buffer_pool(buffer_pool::make(_num_recv_frames, _recv_frame_size)), -        _send_buffer_pool(buffer_pool::make(_num_send_frames, _send_frame_size)), -        _next_recv_buff_index(0), _next_send_buff_index(0) +        const std::string& addr, const std::string& port, const device_addr_t& hints) +        : _recv_frame_size( +              size_t(hints.cast<double>("recv_frame_size", DEFAULT_FRAME_SIZE))) +        , _num_recv_frames( +              size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_FRAMES))) +        , _send_frame_size( +              size_t(hints.cast<double>("send_frame_size", DEFAULT_FRAME_SIZE))) +        , _num_send_frames( +              size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_FRAMES))) +        , _recv_buffer_pool(buffer_pool::make(_num_recv_frames, _recv_frame_size)) +        , _send_buffer_pool(buffer_pool::make(_num_send_frames, _send_frame_size)) +        , _next_recv_buff_index(0) +        , _next_send_buff_index(0)      { -        UHD_LOGGER_TRACE("TCP") << boost::format("Creating tcp transport for %s %s") % addr % port ; +        UHD_LOGGER_TRACE("TCP") +            << boost::format("Creating tcp transport for %s %s") % addr % port; -        //resolve the address +        // resolve the address          asio::ip::tcp::resolver resolver(_io_service);          asio::ip::tcp::resolver::query query(asio::ip::tcp::v4(), addr, port);          asio::ip::tcp::endpoint receiver_endpoint = *resolver.resolve(query); -        //create, open, and connect the socket +        // create, open, and connect the socket          _socket.reset(new asio::ip::tcp::socket(_io_service));          _socket->connect(receiver_endpoint);          _sock_fd = _socket->native_handle(); -        //packets go out ASAP +        // packets go out ASAP          asio::ip::tcp::no_delay option(true);          _socket->set_option(option); -        //allocate re-usable managed receive buffers -        for (size_t i = 0; i < get_num_recv_frames(); i++){ +        // allocate re-usable managed receive buffers +        for (size_t i = 0; i < get_num_recv_frames(); i++) {              _mrb_pool.push_back(boost::make_shared<tcp_zero_copy_asio_mrb>( -                _recv_buffer_pool->at(i), _sock_fd, get_recv_frame_size() -            )); +                _recv_buffer_pool->at(i), _sock_fd, get_recv_frame_size()));          } -        //allocate re-usable managed send buffers -        for (size_t i = 0; i < get_num_send_frames(); i++){ +        // allocate re-usable managed send buffers +        for (size_t i = 0; i < get_num_send_frames(); i++) {              _msb_pool.push_back(boost::make_shared<tcp_zero_copy_asio_msb>( -                _send_buffer_pool->at(i), _sock_fd, get_send_frame_size() -            )); +                _send_buffer_pool->at(i), _sock_fd, get_send_frame_size()));          }      } @@ -169,51 +183,66 @@ public:       * Receive implementation:       * Block on the managed buffer's get call and advance the index.       ******************************************************************/ -    managed_recv_buffer::sptr get_recv_buff(double timeout){ -        if (_next_recv_buff_index == _num_recv_frames) _next_recv_buff_index = 0; +    managed_recv_buffer::sptr get_recv_buff(double timeout) +    { +        if (_next_recv_buff_index == _num_recv_frames) +            _next_recv_buff_index = 0;          return _mrb_pool[_next_recv_buff_index]->get_new(timeout, _next_recv_buff_index);      } -    size_t get_num_recv_frames(void) const {return _num_recv_frames;} -    size_t get_recv_frame_size(void) const {return _recv_frame_size;} +    size_t get_num_recv_frames(void) const +    { +        return _num_recv_frames; +    } +    size_t get_recv_frame_size(void) const +    { +        return _recv_frame_size; +    }      /*******************************************************************       * Send implementation:       * Block on the managed buffer's get call and advance the index.       ******************************************************************/ -    managed_send_buffer::sptr get_send_buff(double timeout){ -        if (_next_send_buff_index == _num_send_frames) _next_send_buff_index = 0; +    managed_send_buffer::sptr get_send_buff(double timeout) +    { +        if (_next_send_buff_index == _num_send_frames) +            _next_send_buff_index = 0;          return _msb_pool[_next_send_buff_index]->get_new(timeout, _next_send_buff_index);      } -    size_t get_num_send_frames(void) const {return _num_send_frames;} -    size_t get_send_frame_size(void) const {return _send_frame_size;} +    size_t get_num_send_frames(void) const +    { +        return _num_send_frames; +    } +    size_t get_send_frame_size(void) const +    { +        return _send_frame_size; +    }  private: -    //memory management -> buffers and fifos +    // memory management -> buffers and fifos      const size_t _recv_frame_size, _num_recv_frames;      const size_t _send_frame_size, _num_send_frames;      buffer_pool::sptr _recv_buffer_pool, _send_buffer_pool; -    std::vector<boost::shared_ptr<tcp_zero_copy_asio_msb> > _msb_pool; -    std::vector<boost::shared_ptr<tcp_zero_copy_asio_mrb> > _mrb_pool; +    std::vector<boost::shared_ptr<tcp_zero_copy_asio_msb>> _msb_pool; +    std::vector<boost::shared_ptr<tcp_zero_copy_asio_mrb>> _mrb_pool;      size_t _next_recv_buff_index, _next_send_buff_index; -    //asio guts -> socket and service -    asio::io_service        _io_service; +    // asio guts -> socket and service +    asio::io_service _io_service;      boost::shared_ptr<asio::ip::tcp::socket> _socket; -    int                     _sock_fd; +    int _sock_fd;  };  /***********************************************************************   * TCP zero copy make function   **********************************************************************/  zero_copy_if::sptr tcp_zero_copy::make( -    const std::string &addr, -    const std::string &port, -    const device_addr_t &hints -){ +    const std::string& addr, const std::string& port, const device_addr_t& hints) +{      zero_copy_if::sptr xport;      xport.reset(new tcp_zero_copy_asio_impl(addr, port, hints)); -    while (xport->get_recv_buff(0.0)){} //flush +    while (xport->get_recv_buff(0.0)) { +    } // flush      return xport;  } diff --git a/host/lib/transport/udp_common.hpp b/host/lib/transport/udp_common.hpp index 19457903b..f320e3d85 100644 --- a/host/lib/transport/udp_common.hpp +++ b/host/lib/transport/udp_common.hpp @@ -11,60 +11,61 @@  #include <uhd/config.hpp>  #include <boost/asio.hpp> -namespace uhd{ namespace transport{ +namespace uhd { namespace transport { -    // Jumbo frames can be up to 9600 bytes; -    static const size_t MAX_ETHERNET_MTU = 9600; +// Jumbo frames can be up to 9600 bytes; +static const size_t MAX_ETHERNET_MTU = 9600;  #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) -    // MacOS limits socket buffer size to 1 Mib -    static const size_t MAX_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib +// MacOS limits socket buffer size to 1 Mib +static const size_t MAX_BUFF_SIZE_ETH_MACOS = 0x100000; // 1Mib  #endif -    typedef boost::shared_ptr<boost::asio::ip::udp::socket> socket_sptr; +typedef boost::shared_ptr<boost::asio::ip::udp::socket> socket_sptr; -    /*! -     * Wait for the socket to become ready for a receive operation. -     * \param sock_fd the open socket file descriptor -     * \param timeout the timeout duration in seconds -     * \return true when the socket is ready for receive -     */ -    UHD_INLINE bool wait_for_recv_ready(int sock_fd, double timeout){ +/*! + * Wait for the socket to become ready for a receive operation. + * \param sock_fd the open socket file descriptor + * \param timeout the timeout duration in seconds + * \return true when the socket is ready for receive + */ +UHD_INLINE bool wait_for_recv_ready(int sock_fd, double timeout) +{  #ifdef UHD_PLATFORM_WIN32 // select is more portable than poll unfortunately -        //setup timeval for timeout -        timeval tv; -        //If the tv_usec > 1 second on some platforms, select will -        //error EINVAL: An invalid timeout interval was specified. -        tv.tv_sec = int(timeout); -        tv.tv_usec = int(timeout*1000000)%1000000; +    // setup timeval for timeout +    timeval tv; +    // If the tv_usec > 1 second on some platforms, select will +    // error EINVAL: An invalid timeout interval was specified. +    tv.tv_sec  = int(timeout); +    tv.tv_usec = int(timeout * 1000000) % 1000000; -        //setup rset for timeout -        fd_set rset; -        FD_ZERO(&rset); -        FD_SET(sock_fd, &rset); +    // setup rset for timeout +    fd_set rset; +    FD_ZERO(&rset); +    FD_SET(sock_fd, &rset); -        //http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html -        //This macro is provided with gcc to properly deal with EINTR. -        //If not provided, define an empty macro, assume that is OK -        #ifndef TEMP_FAILURE_RETRY -            #define TEMP_FAILURE_RETRY(x) (x) -        #endif +// http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html +// This macro is provided with gcc to properly deal with EINTR. +// If not provided, define an empty macro, assume that is OK +#    ifndef TEMP_FAILURE_RETRY +#        define TEMP_FAILURE_RETRY(x) (x) +#    endif -        //call select with timeout on receive socket -        return TEMP_FAILURE_RETRY(::select(sock_fd+1, &rset, NULL, NULL, &tv)) > 0; +    // call select with timeout on receive socket +    return TEMP_FAILURE_RETRY(::select(sock_fd + 1, &rset, NULL, NULL, &tv)) > 0;  #else -        //calculate the total timeout in milliseconds (from seconds) -        int total_timeout = int(timeout*1000); +    // calculate the total timeout in milliseconds (from seconds) +    int total_timeout = int(timeout * 1000); -        pollfd pfd_read; -        pfd_read.fd = sock_fd; -        pfd_read.events = POLLIN; +    pollfd pfd_read; +    pfd_read.fd     = sock_fd; +    pfd_read.events = POLLIN; -        //call poll with timeout on receive socket -        return ::poll(&pfd_read, 1, total_timeout) > 0; +    // call poll with timeout on receive socket +    return ::poll(&pfd_read, 1, total_timeout) > 0;  #endif -    } +} -}} //namespace uhd::transport +}} // namespace uhd::transport  #endif /* INCLUDED_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP */ diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index e3936afc2..48d7b500e 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -16,58 +16,68 @@ namespace asio = boost::asio;  /***********************************************************************   * UDP simple implementation: connected and broadcast   **********************************************************************/ -class udp_simple_impl : public udp_simple{ +class udp_simple_impl : public udp_simple +{  public:      udp_simple_impl( -        const std::string &addr, const std::string &port, bool bcast, bool connect -    ):_connected(connect){ -        UHD_LOGGER_TRACE("UDP") << boost::format("Creating udp transport for %s %s") % addr % port ; +        const std::string& addr, const std::string& port, bool bcast, bool connect) +        : _connected(connect) +    { +        UHD_LOGGER_TRACE("UDP") +            << boost::format("Creating udp transport for %s %s") % addr % port; -        //resolve the address +        // resolve the address          asio::ip::udp::resolver resolver(_io_service); -        asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port, -            asio::ip::resolver_query_base::all_matching); +        asio::ip::udp::resolver::query query( +            asio::ip::udp::v4(), addr, port, asio::ip::resolver_query_base::all_matching);          _send_endpoint = *resolver.resolve(query); -        //create and open the socket +        // create and open the socket          _socket = socket_sptr(new asio::ip::udp::socket(_io_service));          _socket->open(asio::ip::udp::v4()); -        //allow broadcasting +        // allow broadcasting          _socket->set_option(asio::socket_base::broadcast(bcast)); -        //connect the socket -        if (connect) _socket->connect(_send_endpoint); - +        // connect the socket +        if (connect) +            _socket->connect(_send_endpoint);      } -    size_t send(const asio::const_buffer &buff){ -        if (_connected) return _socket->send(asio::buffer(buff)); +    size_t send(const asio::const_buffer& buff) +    { +        if (_connected) +            return _socket->send(asio::buffer(buff));          return _socket->send_to(asio::buffer(buff), _send_endpoint);      } -    size_t recv(const asio::mutable_buffer &buff, double timeout){ -        if (not wait_for_recv_ready(_socket->native_handle(), timeout)) return 0; +    size_t recv(const asio::mutable_buffer& buff, double timeout) +    { +        if (not wait_for_recv_ready(_socket->native_handle(), timeout)) +            return 0;          return _socket->receive_from(asio::buffer(buff), _recv_endpoint);      } -    std::string get_recv_addr(void){ +    std::string get_recv_addr(void) +    {          return _recv_endpoint.address().to_string();      } -    std::string get_send_addr(void){ +    std::string get_send_addr(void) +    {          return _send_endpoint.address().to_string();      }  private: -    bool                    _connected; -    asio::io_service        _io_service; -    socket_sptr             _socket; +    bool _connected; +    asio::io_service _io_service; +    socket_sptr _socket;      asio::ip::udp::endpoint _send_endpoint;      asio::ip::udp::endpoint _recv_endpoint;  }; -udp_simple::~udp_simple(void){ +udp_simple::~udp_simple(void) +{      /* NOP */  } @@ -75,14 +85,14 @@ udp_simple::~udp_simple(void){   * UDP public make functions   **********************************************************************/  udp_simple::sptr udp_simple::make_connected( -    const std::string &addr, const std::string &port -){ +    const std::string& addr, const std::string& port) +{      return sptr(new udp_simple_impl(addr, port, false, true /* no bcast, connect */));  }  udp_simple::sptr udp_simple::make_broadcast( -    const std::string &addr, const std::string &port -){ +    const std::string& addr, const std::string& port) +{      return sptr(new udp_simple_impl(addr, port, true, false /* bcast, no connect */));  } @@ -90,36 +100,44 @@ udp_simple::sptr udp_simple::make_broadcast(   * Simple UART over UDP   **********************************************************************/  #include <boost/thread/thread.hpp> -class udp_simple_uart_impl : public uhd::uart_iface{ +class udp_simple_uart_impl : public uhd::uart_iface +{  public: -    udp_simple_uart_impl(udp_simple::sptr udp){ +    udp_simple_uart_impl(udp_simple::sptr udp) +    {          _udp = udp;          _len = 0;          _off = 0; -        this->write_uart(""); //send an empty packet to init +        this->write_uart(""); // send an empty packet to init      } -    void write_uart(const std::string &buf){ +    void write_uart(const std::string& buf) +    {          _udp->send(asio::buffer(buf));      } -    std::string read_uart(double timeout){ +    std::string read_uart(double timeout) +    {          std::string line; -        const boost::system_time exit_time = boost::get_system_time() + boost::posix_time::milliseconds(long(timeout*1000)); -        do{ -            //drain anything in current buffer -            while (_off < _len){ +        const boost::system_time exit_time = +            boost::get_system_time() +            + boost::posix_time::milliseconds(long(timeout * 1000)); +        do { +            // drain anything in current buffer +            while (_off < _len) {                  const char ch = _buf[_off++];                  _line += ch; -                if (ch == '\n') -                { +                if (ch == '\n') {                      line.swap(_line);                      return line;                  }              } -            //recv a new packet into the buffer -            _len = _udp->recv(asio::buffer(_buf), std::max((exit_time - boost::get_system_time()).total_milliseconds()/1000., 0.0)); +            // recv a new packet into the buffer +            _len = _udp->recv(asio::buffer(_buf), +                std::max( +                    (exit_time - boost::get_system_time()).total_milliseconds() / 1000., +                    0.0));              _off = 0;          } while (_len != 0); @@ -133,6 +151,7 @@ private:      std::string _line;  }; -uhd::uart_iface::sptr udp_simple::make_uart(sptr udp){ +uhd::uart_iface::sptr udp_simple::make_uart(sptr udp) +{      return uart_iface::sptr(new udp_simple_uart_impl(udp));  } diff --git a/host/lib/transport/udp_wsa_zero_copy.cpp b/host/lib/transport/udp_wsa_zero_copy.cpp index 1bdf18095..c1eeb7cb1 100644 --- a/host/lib/transport/udp_wsa_zero_copy.cpp +++ b/host/lib/transport/udp_wsa_zero_copy.cpp @@ -6,10 +6,9 @@  //  #include "udp_common.hpp" -#include <uhd/transport/udp_zero_copy.hpp> -#include <uhd/transport/udp_simple.hpp> //mtu  #include <uhd/transport/buffer_pool.hpp> - +#include <uhd/transport/udp_simple.hpp> //mtu +#include <uhd/transport/udp_zero_copy.hpp>  #include <uhd/utils/log.hpp>  #include <boost/format.hpp>  #include <vector> @@ -18,31 +17,38 @@ using namespace uhd;  using namespace uhd::transport;  namespace asio = boost::asio; -//A reasonable number of frames for send/recv and async/sync +// A reasonable number of frames for send/recv and async/sync  constexpr size_t UDP_ZERO_COPY_DEFAULT_NUM_FRAMES = 1; -constexpr size_t UDP_ZERO_COPY_DEFAULT_FRAME_SIZE = 1472; // Based on common 1500 byte MTU for 1GbE. +constexpr size_t UDP_ZERO_COPY_DEFAULT_FRAME_SIZE = +    1472; // Based on common 1500 byte MTU for 1GbE.  /***********************************************************************   * Check registry for correct fast-path setting (windows only)   **********************************************************************/  #ifdef HAVE_ATLBASE_H -#define CHECK_REG_SEND_THRESH -#include <atlbase.h> //CRegKey -static void check_registry_for_fast_send_threshold(const size_t mtu){ +#    define CHECK_REG_SEND_THRESH +#    include <atlbase.h> //CRegKey +static void check_registry_for_fast_send_threshold(const size_t mtu) +{      static bool warned = false; -    if (warned) return; //only allow one printed warning per process +    if (warned) +        return; // only allow one printed warning per process      CRegKey reg_key; -    DWORD threshold = 1024; //system default when threshold is not specified -    if ( -        reg_key.Open(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\AFD\\Parameters", KEY_READ) != ERROR_SUCCESS or -        reg_key.QueryDWORDValue("FastSendDatagramThreshold", threshold) != ERROR_SUCCESS or threshold < mtu -    ){ -        UHD_LOGGER_WARNING("UDP") << boost::format( -            "The MTU (%d) is larger than the FastSendDatagramThreshold (%d)!\n" -            "This will negatively affect the transmit performance.\n" -            "See the transport application notes for more detail.\n" -        ) % mtu % threshold ; +    DWORD threshold = 1024; // system default when threshold is not specified +    if (reg_key.Open(HKEY_LOCAL_MACHINE, +            "System\\CurrentControlSet\\Services\\AFD\\Parameters", +            KEY_READ) +            != ERROR_SUCCESS +        or reg_key.QueryDWORDValue("FastSendDatagramThreshold", threshold) +               != ERROR_SUCCESS +        or threshold < mtu) { +        UHD_LOGGER_WARNING("UDP") +            << boost::format( +                   "The MTU (%d) is larger than the FastSendDatagramThreshold (%d)!\n" +                   "This will negatively affect the transmit performance.\n" +                   "See the transport application notes for more detail.\n") +                   % mtu % threshold;          warned = true;      }      reg_key.Close(); @@ -52,13 +58,16 @@ static void check_registry_for_fast_send_threshold(const size_t mtu){  /***********************************************************************   * Static initialization to take care of WSA init and cleanup   **********************************************************************/ -struct uhd_wsa_control{ -    uhd_wsa_control(void){ +struct uhd_wsa_control +{ +    uhd_wsa_control(void) +    {          WSADATA wsaData;          WSAStartup(MAKEWORD(2, 2), &wsaData); /*windows socket startup */      } -    ~uhd_wsa_control(void){ +    ~uhd_wsa_control(void) +    {          WSACleanup();      }  }; @@ -68,34 +77,38 @@ struct uhd_wsa_control{   *  - Initialize with memory and a release callback.   *  - Call get new with a length in bytes to re-use.   **********************************************************************/ -class udp_zero_copy_asio_mrb : public managed_recv_buffer{ +class udp_zero_copy_asio_mrb : public managed_recv_buffer +{  public: -    udp_zero_copy_asio_mrb(void *mem, int sock_fd, const size_t frame_size): -        _sock_fd(sock_fd), _frame_size(frame_size) +    udp_zero_copy_asio_mrb(void* mem, int sock_fd, const size_t frame_size) +        : _sock_fd(sock_fd), _frame_size(frame_size)      { -        _wsa_buff.buf = reinterpret_cast<char *>(mem); +        _wsa_buff.buf = reinterpret_cast<char*>(mem);          ZeroMemory(&_overlapped, sizeof(_overlapped));          _overlapped.hEvent = WSACreateEvent();          UHD_ASSERT_THROW(_overlapped.hEvent != WSA_INVALID_EVENT); -        this->release(); //makes buffer available via get_new +        this->release(); // makes buffer available via get_new      } -    ~udp_zero_copy_asio_mrb(void){ +    ~udp_zero_copy_asio_mrb(void) +    {          WSACloseEvent(_overlapped.hEvent);      } -    void release(void){ +    void release(void) +    {          _wsa_buff.len = _frame_size; -        _flags = 0; +        _flags        = 0;          WSARecv(_sock_fd, &_wsa_buff, 1, &_wsa_buff.len, &_flags, &_overlapped, NULL);      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index){ +    UHD_INLINE sptr get_new(const double timeout, size_t& index) +    {          const DWORD result = WSAWaitForMultipleEvents( -            1, &_overlapped.hEvent, true, DWORD(timeout*1000), true -        ); -        if (result == WSA_WAIT_TIMEOUT) return managed_recv_buffer::sptr(); -        index++; //advances the caller's buffer +            1, &_overlapped.hEvent, true, DWORD(timeout * 1000), true); +        if (result == WSA_WAIT_TIMEOUT) +            return managed_recv_buffer::sptr(); +        index++; // advances the caller's buffer          WSAGetOverlappedResult(_sock_fd, &_overlapped, &_wsa_buff.len, true, &_flags); @@ -116,33 +129,37 @@ private:   *  - committing the buffer calls the asynchronous socket send   *  - getting a new buffer performs the blocking wait for completion   **********************************************************************/ -class udp_zero_copy_asio_msb : public managed_send_buffer{ +class udp_zero_copy_asio_msb : public managed_send_buffer +{  public: -    udp_zero_copy_asio_msb(void *mem, int sock_fd, const size_t frame_size): -        _sock_fd(sock_fd), _frame_size(frame_size) +    udp_zero_copy_asio_msb(void* mem, int sock_fd, const size_t frame_size) +        : _sock_fd(sock_fd), _frame_size(frame_size)      { -        _wsa_buff.buf = reinterpret_cast<char *>(mem); +        _wsa_buff.buf = reinterpret_cast<char*>(mem);          ZeroMemory(&_overlapped, sizeof(_overlapped));          _overlapped.hEvent = WSACreateEvent();          UHD_ASSERT_THROW(_overlapped.hEvent != WSA_INVALID_EVENT); -        WSASetEvent(_overlapped.hEvent); //makes buffer available via get_new +        WSASetEvent(_overlapped.hEvent); // makes buffer available via get_new      } -    ~udp_zero_copy_asio_msb(void){ +    ~udp_zero_copy_asio_msb(void) +    {          WSACloseEvent(_overlapped.hEvent);      } -    void release(void){ +    void release(void) +    {          _wsa_buff.len = size();          WSASend(_sock_fd, &_wsa_buff, 1, NULL, 0, &_overlapped, NULL);      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index){ +    UHD_INLINE sptr get_new(const double timeout, size_t& index) +    {          const DWORD result = WSAWaitForMultipleEvents( -            1, &_overlapped.hEvent, true, DWORD(timeout*1000), true -        ); -        if (result == WSA_WAIT_TIMEOUT) return managed_send_buffer::sptr(); -        index++; //advances the caller's buffer +            1, &_overlapped.hEvent, true, DWORD(timeout * 1000), true); +        if (result == WSA_WAIT_TIMEOUT) +            return managed_send_buffer::sptr(); +        index++; // advances the caller's buffer          WSAResetEvent(_overlapped.hEvent);          _wsa_buff.len = _frame_size; @@ -166,87 +183,108 @@ private:   *   This has better performance than the overlapped IO.   *   For send, use overlapped IO to submit async sends.   **********************************************************************/ -class udp_zero_copy_wsa_impl : public udp_zero_copy{ +class udp_zero_copy_wsa_impl : public udp_zero_copy +{  public:      typedef boost::shared_ptr<udp_zero_copy_wsa_impl> sptr; -    udp_zero_copy_wsa_impl( -        const std::string &addr, -        const std::string &port, +    udp_zero_copy_wsa_impl(const std::string& addr, +        const std::string& port,          zero_copy_xport_params& xport_params, -        const device_addr_t &hints -    ): -        _recv_frame_size(xport_params.recv_frame_size), -        _num_recv_frames(xport_params.num_recv_frames), -        _send_frame_size(xport_params.send_frame_size), -        _num_send_frames(xport_params.num_send_frames), -        _recv_buffer_pool(buffer_pool::make(xport_params.num_recv_frames, xport_params.recv_frame_size)), -        _send_buffer_pool(buffer_pool::make(xport_params.num_send_frames, xport_params.send_frame_size)), -        _next_recv_buff_index(0), _next_send_buff_index(0) +        const device_addr_t& hints) +        : _recv_frame_size(xport_params.recv_frame_size) +        , _num_recv_frames(xport_params.num_recv_frames) +        , _send_frame_size(xport_params.send_frame_size) +        , _num_send_frames(xport_params.num_send_frames) +        , _recv_buffer_pool(buffer_pool::make( +              xport_params.num_recv_frames, xport_params.recv_frame_size)) +        , _send_buffer_pool(buffer_pool::make( +              xport_params.num_send_frames, xport_params.send_frame_size)) +        , _next_recv_buff_index(0) +        , _next_send_buff_index(0)      { -        #ifdef CHECK_REG_SEND_THRESH +#ifdef CHECK_REG_SEND_THRESH          check_registry_for_fast_send_threshold(this->get_send_frame_size()); -        #endif /*CHECK_REG_SEND_THRESH*/ +#endif /*CHECK_REG_SEND_THRESH*/          UHD_LOGGER_TRACE("UDP") -            << boost::format("Creating WSA UDP transport to %s:%s") -               % addr % port; +            << boost::format("Creating WSA UDP transport to %s:%s") % addr % port; -        static uhd_wsa_control uhd_wsa; //makes wsa start happen via lazy initialization +        static uhd_wsa_control uhd_wsa; // makes wsa start happen via lazy initialization          UHD_ASSERT_THROW(_num_send_frames <= WSA_MAXIMUM_WAIT_EVENTS); -        //resolve the address +        // resolve the address          asio::io_service io_service;          asio::ip::udp::resolver resolver(io_service);          asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port);          asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); -        //create the socket -        _sock_fd = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED); -        if (_sock_fd == INVALID_SOCKET){ +        // create the socket +        _sock_fd = +            WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED); +        if (_sock_fd == INVALID_SOCKET) {              const DWORD error = WSAGetLastError(); -            throw uhd::os_error(str(boost::format("WSASocket() failed with error %d") % error)); +            throw uhd::os_error( +                str(boost::format("WSASocket() failed with error %d") % error));          } -        //set the socket non-blocking for recv -        //u_long mode = 1; -        //ioctlsocket(_sock_fd, FIONBIO, &mode); +        // set the socket non-blocking for recv +        // u_long mode = 1; +        // ioctlsocket(_sock_fd, FIONBIO, &mode); -        //resize the socket buffers +        // resize the socket buffers          const int recv_buff_size = int(hints.cast<double>("recv_buff_size", 0.0));          const int send_buff_size = int(hints.cast<double>("send_buff_size", 0.0)); -        if (recv_buff_size > 0) setsockopt(_sock_fd, SOL_SOCKET, SO_RCVBUF, (const char *)&recv_buff_size, sizeof(recv_buff_size)); -        if (send_buff_size > 0) setsockopt(_sock_fd, SOL_SOCKET, SO_SNDBUF, (const char *)&send_buff_size, sizeof(send_buff_size)); - -        //connect the socket so we can send/recv -        const asio::ip::udp::endpoint::data_type &servaddr = *receiver_endpoint.data(); -        if (WSAConnect(_sock_fd, (const struct sockaddr *)&servaddr, sizeof(servaddr), NULL, NULL, NULL, NULL) != 0){ +        if (recv_buff_size > 0) +            setsockopt(_sock_fd, +                SOL_SOCKET, +                SO_RCVBUF, +                (const char*)&recv_buff_size, +                sizeof(recv_buff_size)); +        if (send_buff_size > 0) +            setsockopt(_sock_fd, +                SOL_SOCKET, +                SO_SNDBUF, +                (const char*)&send_buff_size, +                sizeof(send_buff_size)); + +        // connect the socket so we can send/recv +        const asio::ip::udp::endpoint::data_type& servaddr = *receiver_endpoint.data(); +        if (WSAConnect(_sock_fd, +                (const struct sockaddr*)&servaddr, +                sizeof(servaddr), +                NULL, +                NULL, +                NULL, +                NULL) +            != 0) {              const DWORD error = WSAGetLastError();              closesocket(_sock_fd); -            throw uhd::os_error(str(boost::format("WSAConnect() failed with error %d") % error)); +            throw uhd::os_error( +                str(boost::format("WSAConnect() failed with error %d") % error));          } -        UHD_LOGGER_TRACE("UDP") -            << boost::format("Local WSA UDP socket endpoint: %s:%s") -            % get_local_addr() % get_local_port(); - -        //allocate re-usable managed receive buffers -        for (size_t i = 0; i < get_num_recv_frames(); i++){ -            _mrb_pool.push_back(boost::shared_ptr<udp_zero_copy_asio_mrb>( -                new udp_zero_copy_asio_mrb(_recv_buffer_pool->at(i), _sock_fd, get_recv_frame_size()) -            )); +        UHD_LOGGER_TRACE("UDP") << boost::format("Local WSA UDP socket endpoint: %s:%s") +                                       % get_local_addr() % get_local_port(); + +        // allocate re-usable managed receive buffers +        for (size_t i = 0; i < get_num_recv_frames(); i++) { +            _mrb_pool.push_back( +                boost::shared_ptr<udp_zero_copy_asio_mrb>(new udp_zero_copy_asio_mrb( +                    _recv_buffer_pool->at(i), _sock_fd, get_recv_frame_size())));          } -        //allocate re-usable managed send buffers -        for (size_t i = 0; i < get_num_send_frames(); i++){ -            _msb_pool.push_back(boost::shared_ptr<udp_zero_copy_asio_msb>( -                new udp_zero_copy_asio_msb(_send_buffer_pool->at(i), _sock_fd, get_send_frame_size()) -            )); +        // allocate re-usable managed send buffers +        for (size_t i = 0; i < get_num_send_frames(); i++) { +            _msb_pool.push_back( +                boost::shared_ptr<udp_zero_copy_asio_msb>(new udp_zero_copy_asio_msb( +                    _send_buffer_pool->at(i), _sock_fd, get_send_frame_size())));          }      } -    ~udp_zero_copy_wsa_impl(void){ +    ~udp_zero_copy_wsa_impl(void) +    {          closesocket(_sock_fd);      } @@ -254,45 +292,62 @@ public:       * Receive implementation:       * Block on the managed buffer's get call and advance the index.       ******************************************************************/ -    managed_recv_buffer::sptr get_recv_buff(double timeout){ -        if (_next_recv_buff_index == _num_recv_frames) _next_recv_buff_index = 0; +    managed_recv_buffer::sptr get_recv_buff(double timeout) +    { +        if (_next_recv_buff_index == _num_recv_frames) +            _next_recv_buff_index = 0;          return _mrb_pool[_next_recv_buff_index]->get_new(timeout, _next_recv_buff_index);      } -    size_t get_num_recv_frames(void) const {return _num_recv_frames;} -    size_t get_recv_frame_size(void) const {return _recv_frame_size;} +    size_t get_num_recv_frames(void) const +    { +        return _num_recv_frames; +    } +    size_t get_recv_frame_size(void) const +    { +        return _recv_frame_size; +    }      /*******************************************************************       * Send implementation:       * Block on the managed buffer's get call and advance the index.       ******************************************************************/ -    managed_send_buffer::sptr get_send_buff(double timeout){ -        if (_next_send_buff_index == _num_send_frames) _next_send_buff_index = 0; +    managed_send_buffer::sptr get_send_buff(double timeout) +    { +        if (_next_send_buff_index == _num_send_frames) +            _next_send_buff_index = 0;          return _msb_pool[_next_send_buff_index]->get_new(timeout, _next_send_buff_index);      } -    size_t get_num_send_frames(void) const {return _num_send_frames;} -    size_t get_send_frame_size(void) const {return _send_frame_size;} +    size_t get_num_send_frames(void) const +    { +        return _num_send_frames; +    } +    size_t get_send_frame_size(void) const +    { +        return _send_frame_size; +    } -    uint16_t get_local_port(void) const { +    uint16_t get_local_port(void) const +    {          struct sockaddr_in addr_info; -        int addr_len = sizeof(addr_info); +        int addr_len        = sizeof(addr_info);          uint16_t local_port = 0; -        if (getsockname( _sock_fd, (SOCKADDR*) &addr_info, -                         &addr_len) == 0){ +        if (getsockname(_sock_fd, (SOCKADDR*)&addr_info, &addr_len) == 0) {              local_port = ntohs(addr_info.sin_port);          }          return local_port;      } -    std::string get_local_addr(void) const { +    std::string get_local_addr(void) const +    {          // Behold the beauty of winsock          struct sockaddr_in addr_info;          int addr_len = sizeof(addr_info);          std::string local_addr; -        if (getsockname(_sock_fd, (SOCKADDR*) &addr_info, &addr_len) == 0) { +        if (getsockname(_sock_fd, (SOCKADDR*)&addr_info, &addr_len) == 0) {              // inet_ntoa() guarantees either NULL or null-terminated array -            char *local_ip = inet_ntoa(addr_info.sin_addr); +            char* local_ip = inet_ntoa(addr_info.sin_addr);              if (local_ip) {                  local_addr = std::string(local_ip);              } @@ -301,86 +356,77 @@ public:      }      //! Read back the socket's buffer space reserved for receives -    size_t get_recv_buff_size(void) { +    size_t get_recv_buff_size(void) +    {          int recv_buff_size = 0; -        int opt_len = sizeof(recv_buff_size); +        int opt_len        = sizeof(recv_buff_size);          getsockopt( -                _sock_fd, -                SOL_SOCKET, -                SO_RCVBUF, -                (char *)&recv_buff_size, -                (int *)&opt_len -        ); +            _sock_fd, SOL_SOCKET, SO_RCVBUF, (char*)&recv_buff_size, (int*)&opt_len); -        return (size_t) recv_buff_size; +        return (size_t)recv_buff_size;      }      //! Read back the socket's buffer space reserved for sends -    size_t get_send_buff_size(void) { +    size_t get_send_buff_size(void) +    {          int send_buff_size = 0; -        int opt_len = sizeof(send_buff_size); +        int opt_len        = sizeof(send_buff_size);          getsockopt( -                _sock_fd, -                SOL_SOCKET, -                SO_SNDBUF, -                (char *)&send_buff_size, -                (int *)&opt_len -        ); +            _sock_fd, SOL_SOCKET, SO_SNDBUF, (char*)&send_buff_size, (int*)&opt_len); -        return (size_t) send_buff_size; +        return (size_t)send_buff_size;      }  private: -    //memory management -> buffers and fifos +    // memory management -> buffers and fifos      const size_t _recv_frame_size, _num_recv_frames;      const size_t _send_frame_size, _num_send_frames;      buffer_pool::sptr _recv_buffer_pool, _send_buffer_pool; -    std::vector<boost::shared_ptr<udp_zero_copy_asio_msb> > _msb_pool; -    std::vector<boost::shared_ptr<udp_zero_copy_asio_mrb> > _mrb_pool; +    std::vector<boost::shared_ptr<udp_zero_copy_asio_msb>> _msb_pool; +    std::vector<boost::shared_ptr<udp_zero_copy_asio_mrb>> _mrb_pool;      size_t _next_recv_buff_index, _next_send_buff_index; -    //socket guts -    SOCKET                  _sock_fd; +    // socket guts +    SOCKET _sock_fd;  };  /***********************************************************************   * UDP zero copy make function   **********************************************************************/ -void check_usr_buff_size( -    size_t actual_buff_size, +void check_usr_buff_size(size_t actual_buff_size,      size_t user_buff_size, // Set this to zero for no user-defined preference -    const std::string tx_rx -){ -    UHD_LOGGER_DEBUG("UDP") -        << boost::format("Target/actual %s sock buff size: %d/%d bytes") -           % tx_rx -           % user_buff_size -           % actual_buff_size -    ; -    if ((user_buff_size != 0.0) and (actual_buff_size < user_buff_size)) UHD_LOGGER_WARNING("UDP") << boost::format( -        "The %s buffer could not be resized sufficiently.\n" -        "Target sock buff size: %d bytes.\n" -        "Actual sock buff size: %d bytes.\n" -        "See the transport application notes on buffer resizing.\n" -    ) % tx_rx % user_buff_size % actual_buff_size; +    const std::string tx_rx) +{ +    UHD_LOGGER_DEBUG("UDP") << boost::format( +                                   "Target/actual %s sock buff size: %d/%d bytes") +                                   % tx_rx % user_buff_size % actual_buff_size; +    if ((user_buff_size != 0.0) and (actual_buff_size < user_buff_size)) +        UHD_LOGGER_WARNING("UDP") +            << boost::format("The %s buffer could not be resized sufficiently.\n" +                             "Target sock buff size: %d bytes.\n" +                             "Actual sock buff size: %d bytes.\n" +                             "See the transport application notes on buffer resizing.\n") +                   % tx_rx % user_buff_size % actual_buff_size;  } - -udp_zero_copy::sptr udp_zero_copy::make( -    const std::string &addr, -    const std::string &port, -    const zero_copy_xport_params &default_buff_args, +udp_zero_copy::sptr udp_zero_copy::make(const std::string& addr, +    const std::string& port, +    const zero_copy_xport_params& default_buff_args,      udp_zero_copy::buff_params& buff_params_out, -    const device_addr_t &hints -){ -    //Initialize xport_params +    const device_addr_t& hints) +{ +    // Initialize xport_params      zero_copy_xport_params xport_params = default_buff_args; -    xport_params.recv_frame_size = size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size)); -    xport_params.num_recv_frames = size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames)); -    xport_params.send_frame_size = size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size)); -    xport_params.num_send_frames = size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames)); +    xport_params.recv_frame_size = +        size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size)); +    xport_params.num_recv_frames = +        size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames)); +    xport_params.send_frame_size = +        size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size)); +    xport_params.num_send_frames = +        size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames));      if (xport_params.num_recv_frames == 0) {          UHD_LOG_TRACE("UDP", @@ -405,27 +451,34 @@ udp_zero_copy::sptr udp_zero_copy::make(          xport_params.send_frame_size = UDP_ZERO_COPY_DEFAULT_FRAME_SIZE;      } -    //extract buffer size hints from the device addr and check if they match up +    // extract buffer size hints from the device addr and check if they match up      size_t usr_recv_buff_size = size_t(hints.cast<double>("recv_buff_size", 0.0));      size_t usr_send_buff_size = size_t(hints.cast<double>("send_buff_size", 0.0));      if (hints.has_key("recv_buff_size")) { -        if (usr_recv_buff_size < xport_params.recv_frame_size * xport_params.num_recv_frames) { -            throw uhd::value_error((boost::format( -                "recv_buff_size must be equal to or greater than (num_recv_frames * recv_frame_size) where num_recv_frames=%d, recv_frame_size=%d") -                % xport_params.num_recv_frames % xport_params.recv_frame_size).str()); +        if (usr_recv_buff_size +            < xport_params.recv_frame_size * xport_params.num_recv_frames) { +            throw uhd::value_error( +                (boost::format( +                     "recv_buff_size must be equal to or greater than (num_recv_frames * " +                     "recv_frame_size) where num_recv_frames=%d, recv_frame_size=%d") +                    % xport_params.num_recv_frames % xport_params.recv_frame_size) +                    .str());          }      }      if (hints.has_key("send_buff_size")) { -        if (usr_send_buff_size < xport_params.send_frame_size * xport_params.num_send_frames) { -            throw uhd::value_error((boost::format( -                "send_buff_size must be equal to or greater than (num_send_frames * send_frame_size) where num_send_frames=%d, send_frame_size=%d") -                % xport_params.num_send_frames % xport_params.send_frame_size).str()); +        if (usr_send_buff_size +            < xport_params.send_frame_size * xport_params.num_send_frames) { +            throw uhd::value_error( +                (boost::format( +                     "send_buff_size must be equal to or greater than (num_send_frames * " +                     "send_frame_size) where num_send_frames=%d, send_frame_size=%d") +                    % xport_params.num_send_frames % xport_params.send_frame_size) +                    .str());          }      }      udp_zero_copy_wsa_impl::sptr udp_trans( -        new udp_zero_copy_wsa_impl(addr, port, xport_params, hints) -    ); +        new udp_zero_copy_wsa_impl(addr, port, xport_params, hints));      // Read back the actual socket buffer sizes      buff_params_out.recv_buff_size = udp_trans->get_recv_buff_size(); diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp index 2b637639b..1ccee72a2 100644 --- a/host/lib/transport/udp_zero_copy.cpp +++ b/host/lib/transport/udp_zero_copy.cpp @@ -6,45 +6,52 @@  //  #include "udp_common.hpp" -#include <uhd/transport/udp_zero_copy.hpp> -#include <uhd/transport/udp_simple.hpp> //mtu  #include <uhd/transport/buffer_pool.hpp> - +#include <uhd/transport/udp_simple.hpp> //mtu +#include <uhd/transport/udp_zero_copy.hpp>  #include <uhd/utils/log.hpp>  #include <uhdlib/utils/atomic.hpp>  #include <boost/format.hpp>  #include <boost/make_shared.hpp> -#include <vector>  #include <chrono>  #include <thread> +#include <vector>  using namespace uhd;  using namespace uhd::transport; -namespace asio = boost::asio; +namespace asio                                    = boost::asio;  constexpr size_t UDP_ZERO_COPY_DEFAULT_NUM_FRAMES = 1; -constexpr size_t UDP_ZERO_COPY_DEFAULT_FRAME_SIZE = 1472; // Based on common 1500 byte MTU for 1GbE. -constexpr size_t UDP_ZERO_COPY_DEFAULT_BUFF_SIZE = 2500000; // 20ms of data for 1GbE link (in bytes) +constexpr size_t UDP_ZERO_COPY_DEFAULT_FRAME_SIZE = +    1472; // Based on common 1500 byte MTU for 1GbE. +constexpr size_t UDP_ZERO_COPY_DEFAULT_BUFF_SIZE = +    2500000; // 20ms of data for 1GbE link (in bytes)  /***********************************************************************   * Check registry for correct fast-path setting (windows only)   **********************************************************************/  #ifdef HAVE_ATLBASE_H -#define CHECK_REG_SEND_THRESH -#include <atlbase.h> //CRegKey -static void check_registry_for_fast_send_threshold(const size_t mtu){ +#    define CHECK_REG_SEND_THRESH +#    include <atlbase.h> //CRegKey +static void check_registry_for_fast_send_threshold(const size_t mtu) +{      static bool warned = false; -    if (warned) return; //only allow one printed warning per process +    if (warned) +        return; // only allow one printed warning per process      CRegKey reg_key; -    DWORD threshold = 1024; //system default when threshold is not specified -    if ( -        reg_key.Open(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\AFD\\Parameters", KEY_READ) != ERROR_SUCCESS or -        reg_key.QueryDWORDValue("FastSendDatagramThreshold", threshold) != ERROR_SUCCESS or threshold < mtu -    ){ -        UHD_LOGGER_WARNING("UDP") << boost::format( -            "The MTU (%d) is larger than the FastSendDatagramThreshold (%d)!\n" -            "This will negatively affect the transmit performance.\n" -            "See the transport application notes for more detail.\n" -        ) % mtu % threshold ; +    DWORD threshold = 1024; // system default when threshold is not specified +    if (reg_key.Open(HKEY_LOCAL_MACHINE, +            "System\\CurrentControlSet\\Services\\AFD\\Parameters", +            KEY_READ) +            != ERROR_SUCCESS +        or reg_key.QueryDWORDValue("FastSendDatagramThreshold", threshold) +               != ERROR_SUCCESS +        or threshold < mtu) { +        UHD_LOGGER_WARNING("UDP") +            << boost::format( +                   "The MTU (%d) is larger than the FastSendDatagramThreshold (%d)!\n" +                   "This will negatively affect the transmit performance.\n" +                   "See the transport application notes for more detail.\n") +                   % mtu % threshold;          warned = true;      }      reg_key.Close(); @@ -55,42 +62,49 @@ static void check_registry_for_fast_send_threshold(const size_t mtu){   * Reusable managed receiver buffer:   *  - get_new performs the recv operation   **********************************************************************/ -class udp_zero_copy_asio_mrb : public managed_recv_buffer{ +class udp_zero_copy_asio_mrb : public managed_recv_buffer +{  public: -    udp_zero_copy_asio_mrb(void *mem, int sock_fd, const size_t frame_size): -        _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size), _len(0) { /*NOP*/ } +    udp_zero_copy_asio_mrb(void* mem, int sock_fd, const size_t frame_size) +        : _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size), _len(0) +    { /*NOP*/ +    } -    void release(void){ +    void release(void) +    {          _claimer.release();      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index){ -        if (not _claimer.claim_with_wait(timeout)) return sptr(); +    UHD_INLINE sptr get_new(const double timeout, size_t& index) +    { +        if (not _claimer.claim_with_wait(timeout)) +            return sptr(); -        #ifdef MSG_DONTWAIT //try a non-blocking recv() if supported -        _len = ::recv(_sock_fd, (char *)_mem, _frame_size, MSG_DONTWAIT); -        if (_len > 0){ -            index++; //advances the caller's buffer +#ifdef MSG_DONTWAIT // try a non-blocking recv() if supported +        _len = ::recv(_sock_fd, (char*)_mem, _frame_size, MSG_DONTWAIT); +        if (_len > 0) { +            index++; // advances the caller's buffer              return make(this, _mem, size_t(_len));          } -        #endif +#endif -        if (wait_for_recv_ready(_sock_fd, timeout)){ -            _len = ::recv(_sock_fd, (char *)_mem, _frame_size, 0); +        if (wait_for_recv_ready(_sock_fd, timeout)) { +            _len = ::recv(_sock_fd, (char*)_mem, _frame_size, 0);              if (_len == 0)                  throw uhd::io_error("socket closed");              if (_len < 0) -                throw uhd::io_error(str(boost::format("recv error on socket: %s") % strerror(errno))); -            index++; //advances the caller's buffer +                throw uhd::io_error( +                    str(boost::format("recv error on socket: %s") % strerror(errno))); +            index++; // advances the caller's buffer              return make(this, _mem, size_t(_len));          } -        _claimer.release(); //undo claim -        return sptr(); //null for timeout +        _claimer.release(); // undo claim +        return sptr(); // null for timeout      }  private: -    void *_mem; +    void* _mem;      int _sock_fd;      size_t _frame_size;      ssize_t _len; @@ -101,41 +115,46 @@ private:   * Reusable managed send buffer:   *  - commit performs the send operation   **********************************************************************/ -class udp_zero_copy_asio_msb : public managed_send_buffer{ +class udp_zero_copy_asio_msb : public managed_send_buffer +{  public: -    udp_zero_copy_asio_msb(void *mem, int sock_fd, const size_t frame_size): -        _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) { /*NOP*/ } - -    void release(void){ -        //Retry logic because send may fail with ENOBUFS. -        //This is known to occur at least on some OSX systems. -        //But it should be safe to always check for the error. -        while (true) -        { -            const ssize_t ret = ::send(_sock_fd, (const char *)_mem, size(), 0); -            if (ret == ssize_t(size())) break; -            if (ret == -1 and errno == ENOBUFS) -            { +    udp_zero_copy_asio_msb(void* mem, int sock_fd, const size_t frame_size) +        : _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) +    { /*NOP*/ +    } + +    void release(void) +    { +        // Retry logic because send may fail with ENOBUFS. +        // This is known to occur at least on some OSX systems. +        // But it should be safe to always check for the error. +        while (true) { +            const ssize_t ret = ::send(_sock_fd, (const char*)_mem, size(), 0); +            if (ret == ssize_t(size())) +                break; +            if (ret == -1 and errno == ENOBUFS) {                  std::this_thread::sleep_for(std::chrono::microseconds(1)); -                continue; //try to send again +                continue; // try to send again              } -            if (ret == -1) -            { -                throw uhd::io_error(str(boost::format("send error on socket: %s") % strerror(errno))); +            if (ret == -1) { +                throw uhd::io_error( +                    str(boost::format("send error on socket: %s") % strerror(errno)));              }              UHD_ASSERT_THROW(ret == ssize_t(size()));          }          _claimer.release();      } -    UHD_INLINE sptr get_new(const double timeout, size_t &index){ -        if (not _claimer.claim_with_wait(timeout)) return sptr(); -        index++; //advances the caller's buffer +    UHD_INLINE sptr get_new(const double timeout, size_t& index) +    { +        if (not _claimer.claim_with_wait(timeout)) +            return sptr(); +        index++; // advances the caller's buffer          return make(this, _mem, _frame_size);      }  private: -    void *_mem; +    void* _mem;      int _sock_fd;      size_t _frame_size;      simple_claimer _claimer; @@ -148,74 +167,74 @@ private:   *   However, it is not a true zero copy implementation as each   *   send and recv requires a copy operation to/from userspace.   **********************************************************************/ -class udp_zero_copy_asio_impl : public udp_zero_copy{ +class udp_zero_copy_asio_impl : public udp_zero_copy +{  public:      typedef boost::shared_ptr<udp_zero_copy_asio_impl> sptr; -    udp_zero_copy_asio_impl( -        const std::string &addr, -        const std::string &port, -        const zero_copy_xport_params& xport_params -    ): -        _recv_frame_size(xport_params.recv_frame_size), -        _num_recv_frames(xport_params.num_recv_frames), -        _send_frame_size(xport_params.send_frame_size), -        _num_send_frames(xport_params.num_send_frames), -        _recv_buffer_pool(buffer_pool::make(xport_params.num_recv_frames, xport_params.recv_frame_size)), -        _send_buffer_pool(buffer_pool::make(xport_params.num_send_frames, xport_params.send_frame_size)), -        _next_recv_buff_index(0), _next_send_buff_index(0) +    udp_zero_copy_asio_impl(const std::string& addr, +        const std::string& port, +        const zero_copy_xport_params& xport_params) +        : _recv_frame_size(xport_params.recv_frame_size) +        , _num_recv_frames(xport_params.num_recv_frames) +        , _send_frame_size(xport_params.send_frame_size) +        , _num_send_frames(xport_params.num_send_frames) +        , _recv_buffer_pool(buffer_pool::make( +              xport_params.num_recv_frames, xport_params.recv_frame_size)) +        , _send_buffer_pool(buffer_pool::make( +              xport_params.num_send_frames, xport_params.send_frame_size)) +        , _next_recv_buff_index(0) +        , _next_send_buff_index(0)      {          UHD_LOGGER_TRACE("UDP")              << boost::format("Creating UDP transport to %s:%s") % addr % port; -        #ifdef CHECK_REG_SEND_THRESH +#ifdef CHECK_REG_SEND_THRESH          check_registry_for_fast_send_threshold(this->get_send_frame_size()); -        #endif /*CHECK_REG_SEND_THRESH*/ +#endif /*CHECK_REG_SEND_THRESH*/ -        //resolve the address +        // resolve the address          asio::ip::udp::resolver resolver(_io_service);          asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port);          asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); -        //create, open, and connect the socket +        // create, open, and connect the socket          _socket = socket_sptr(new asio::ip::udp::socket(_io_service));          _socket->open(asio::ip::udp::v4());          _socket->connect(receiver_endpoint);          _sock_fd = _socket->native_handle(); -        UHD_LOGGER_TRACE("UDP") -            << boost::format("Local UDP socket endpoint: %s:%s") -            % get_local_addr() % get_local_port(); +        UHD_LOGGER_TRACE("UDP") << boost::format("Local UDP socket endpoint: %s:%s") +                                       % get_local_addr() % get_local_port(); -        //allocate re-usable managed receive buffers -        for (size_t i = 0; i < get_num_recv_frames(); i++){ +        // allocate re-usable managed receive buffers +        for (size_t i = 0; i < get_num_recv_frames(); i++) {              _mrb_pool.push_back(boost::make_shared<udp_zero_copy_asio_mrb>( -                _recv_buffer_pool->at(i), _sock_fd, get_recv_frame_size() -            )); +                _recv_buffer_pool->at(i), _sock_fd, get_recv_frame_size()));          } -        //allocate re-usable managed send buffers -        for (size_t i = 0; i < get_num_send_frames(); i++){ +        // allocate re-usable managed send buffers +        for (size_t i = 0; i < get_num_send_frames(); i++) {              _msb_pool.push_back(boost::make_shared<udp_zero_copy_asio_msb>( -                _send_buffer_pool->at(i), _sock_fd, get_send_frame_size() -            )); +                _send_buffer_pool->at(i), _sock_fd, get_send_frame_size()));          }      } -    //get size for internal socket buffer -    template <typename Opt> size_t get_buff_size(void) const{ +    // get size for internal socket buffer +    template <typename Opt> size_t get_buff_size(void) const +    {          Opt option;          _socket->get_option(option);          return option.value();      } -    //set size for internal socket buffer +    // set size for internal socket buffer      template <typename Opt> size_t resize_buff(size_t num_bytes)      { -        #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) -            //limit buffer resize on macos or it will error -            num_bytes = std::min(num_bytes, MAX_BUFF_SIZE_ETH_MACOS); -        #endif +#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) +        // limit buffer resize on macos or it will error +        num_bytes = std::min(num_bytes, MAX_BUFF_SIZE_ETH_MACOS); +#endif          Opt option(num_bytes);          _socket->set_option(option);          return get_buff_size<Opt>(); @@ -225,25 +244,41 @@ public:       * Receive implementation:       * Block on the managed buffer's get call and advance the index.       ******************************************************************/ -    managed_recv_buffer::sptr get_recv_buff(double timeout){ -        if (_next_recv_buff_index == _num_recv_frames) _next_recv_buff_index = 0; +    managed_recv_buffer::sptr get_recv_buff(double timeout) +    { +        if (_next_recv_buff_index == _num_recv_frames) +            _next_recv_buff_index = 0;          return _mrb_pool[_next_recv_buff_index]->get_new(timeout, _next_recv_buff_index);      } -    size_t get_num_recv_frames(void) const {return _num_recv_frames;} -    size_t get_recv_frame_size(void) const {return _recv_frame_size;} +    size_t get_num_recv_frames(void) const +    { +        return _num_recv_frames; +    } +    size_t get_recv_frame_size(void) const +    { +        return _recv_frame_size; +    }      /*******************************************************************       * Send implementation:       * Block on the managed buffer's get call and advance the index.       ******************************************************************/ -    managed_send_buffer::sptr get_send_buff(double timeout){ -        if (_next_send_buff_index == _num_send_frames) _next_send_buff_index = 0; +    managed_send_buffer::sptr get_send_buff(double timeout) +    { +        if (_next_send_buff_index == _num_send_frames) +            _next_send_buff_index = 0;          return _msb_pool[_next_send_buff_index]->get_new(timeout, _next_send_buff_index);      } -    size_t get_num_send_frames(void) const {return _num_send_frames;} -    size_t get_send_frame_size(void) const {return _send_frame_size;} +    size_t get_num_send_frames(void) const +    { +        return _num_send_frames; +    } +    size_t get_send_frame_size(void) const +    { +        return _send_frame_size; +    }      uint16_t get_local_port(void) const      { @@ -256,149 +291,153 @@ public:      }  private: -    //memory management -> buffers and fifos +    // memory management -> buffers and fifos      const size_t _recv_frame_size, _num_recv_frames;      const size_t _send_frame_size, _num_send_frames;      buffer_pool::sptr _recv_buffer_pool, _send_buffer_pool; -    std::vector<boost::shared_ptr<udp_zero_copy_asio_msb> > _msb_pool; -    std::vector<boost::shared_ptr<udp_zero_copy_asio_mrb> > _mrb_pool; +    std::vector<boost::shared_ptr<udp_zero_copy_asio_msb>> _msb_pool; +    std::vector<boost::shared_ptr<udp_zero_copy_asio_mrb>> _mrb_pool;      size_t _next_recv_buff_index, _next_send_buff_index; -    //asio guts -> socket and service -    asio::io_service        _io_service; -    socket_sptr             _socket; -    int                     _sock_fd; +    // asio guts -> socket and service +    asio::io_service _io_service; +    socket_sptr _socket; +    int _sock_fd;  };  /***********************************************************************   * UDP zero copy make function   **********************************************************************/ -template<typename Opt> static size_t resize_buff_helper( -    udp_zero_copy_asio_impl::sptr udp_trans, +template <typename Opt> +static size_t resize_buff_helper(udp_zero_copy_asio_impl::sptr udp_trans,      const size_t target_size, -    const std::string &name -){ +    const std::string& name) +{      size_t actual_size = 0;      std::string help_message; -    #if defined(UHD_PLATFORM_LINUX) -        help_message = str(boost::format( -            "Please run: sudo sysctl -w net.core.%smem_max=%d" -        ) % ((name == "recv")?"r":"w") % target_size); -    #endif /*defined(UHD_PLATFORM_LINUX)*/ - -    //resize the buffer if size was provided -    if (target_size > 0){ +#if defined(UHD_PLATFORM_LINUX) +    help_message = str(boost::format("Please run: sudo sysctl -w net.core.%smem_max=%d") +                       % ((name == "recv") ? "r" : "w") % target_size); +#endif /*defined(UHD_PLATFORM_LINUX)*/ + +    // resize the buffer if size was provided +    if (target_size > 0) {          actual_size = udp_trans->resize_buff<Opt>(target_size);          UHD_LOGGER_TRACE("UDP") -            << boost::format("Target/actual %s sock buff size: %d/%d bytes") -               % name -               % target_size -               % actual_size -        ; -        if (actual_size < target_size) UHD_LOGGER_WARNING("UDP") << boost::format( -            "The %s buffer could not be resized sufficiently.\n" -            "Target sock buff size: %d bytes.\n" -            "Actual sock buff size: %d bytes.\n" -            "See the transport application notes on buffer resizing.\n%s" -        ) % name % target_size % actual_size % help_message; +            << boost::format("Target/actual %s sock buff size: %d/%d bytes") % name +                   % target_size % actual_size; +        if (actual_size < target_size) +            UHD_LOGGER_WARNING("UDP") +                << boost::format( +                       "The %s buffer could not be resized sufficiently.\n" +                       "Target sock buff size: %d bytes.\n" +                       "Actual sock buff size: %d bytes.\n" +                       "See the transport application notes on buffer resizing.\n%s") +                       % name % target_size % actual_size % help_message;      }      return actual_size;  } -udp_zero_copy::sptr udp_zero_copy::make( -    const std::string &addr, -    const std::string &port, -    const zero_copy_xport_params &default_buff_args, +udp_zero_copy::sptr udp_zero_copy::make(const std::string& addr, +    const std::string& port, +    const zero_copy_xport_params& default_buff_args,      udp_zero_copy::buff_params& buff_params_out, -    const device_addr_t &hints -){ -    //Initialize xport_params +    const device_addr_t& hints) +{ +    // Initialize xport_params      zero_copy_xport_params xport_params = default_buff_args; -    xport_params.recv_frame_size = size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size)); -    xport_params.num_recv_frames = size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames)); -    xport_params.send_frame_size = size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size)); -    xport_params.num_send_frames = size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames)); -    xport_params.recv_buff_size = size_t(hints.cast<double>("recv_buff_size", default_buff_args.recv_buff_size)); -    xport_params.send_buff_size = size_t(hints.cast<double>("send_buff_size", default_buff_args.send_buff_size)); +    xport_params.recv_frame_size = +        size_t(hints.cast<double>("recv_frame_size", default_buff_args.recv_frame_size)); +    xport_params.num_recv_frames = +        size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames)); +    xport_params.send_frame_size = +        size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size)); +    xport_params.num_send_frames = +        size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames)); +    xport_params.recv_buff_size = +        size_t(hints.cast<double>("recv_buff_size", default_buff_args.recv_buff_size)); +    xport_params.send_buff_size = +        size_t(hints.cast<double>("send_buff_size", default_buff_args.send_buff_size));      if (xport_params.num_recv_frames == 0) { -        UHD_LOG_TRACE("UDP", "Default value for num_recv_frames: " -            << UDP_ZERO_COPY_DEFAULT_NUM_FRAMES -        ); +        UHD_LOG_TRACE("UDP", +            "Default value for num_recv_frames: " << UDP_ZERO_COPY_DEFAULT_NUM_FRAMES);          xport_params.num_recv_frames = UDP_ZERO_COPY_DEFAULT_NUM_FRAMES;      }      if (xport_params.num_send_frames == 0) { -        UHD_LOG_TRACE("UDP", "Default value for no num_send_frames: " -            << UDP_ZERO_COPY_DEFAULT_NUM_FRAMES -        ); +        UHD_LOG_TRACE("UDP", +            "Default value for no num_send_frames: " << UDP_ZERO_COPY_DEFAULT_NUM_FRAMES);          xport_params.num_send_frames = UDP_ZERO_COPY_DEFAULT_NUM_FRAMES;      }      if (xport_params.recv_frame_size == 0) { -        UHD_LOG_TRACE("UDP", "Using default value for  recv_frame_size: " -            << UDP_ZERO_COPY_DEFAULT_FRAME_SIZE -        ); +        UHD_LOG_TRACE("UDP", +            "Using default value for  recv_frame_size: " +                << UDP_ZERO_COPY_DEFAULT_FRAME_SIZE);          xport_params.recv_frame_size = UDP_ZERO_COPY_DEFAULT_FRAME_SIZE;      }      if (xport_params.send_frame_size == 0) { -        UHD_LOG_TRACE("UDP", "Using default value for send_frame_size, " -            << UDP_ZERO_COPY_DEFAULT_FRAME_SIZE -        ); +        UHD_LOG_TRACE("UDP", +            "Using default value for send_frame_size, " +                << UDP_ZERO_COPY_DEFAULT_FRAME_SIZE);          xport_params.send_frame_size = UDP_ZERO_COPY_DEFAULT_FRAME_SIZE;      }      if (xport_params.recv_buff_size == 0) {          UHD_LOG_TRACE("UDP", "Using default value for recv_buff_size"); -        xport_params.recv_buff_size = std::max( -                UDP_ZERO_COPY_DEFAULT_BUFF_SIZE, -                xport_params.num_recv_frames*MAX_ETHERNET_MTU -            ); -        UHD_LOG_TRACE("UDP", "Using default value for recv_buff_size" -            << xport_params.recv_buff_size -        ); +        xport_params.recv_buff_size = std::max(UDP_ZERO_COPY_DEFAULT_BUFF_SIZE, +            xport_params.num_recv_frames * MAX_ETHERNET_MTU); +        UHD_LOG_TRACE("UDP", +            "Using default value for recv_buff_size" << xport_params.recv_buff_size);      }      if (xport_params.send_buff_size == 0) {          UHD_LOG_TRACE("UDP", "default_buff_args has no send_buff_size"); -        xport_params.send_buff_size = std::max( -                UDP_ZERO_COPY_DEFAULT_BUFF_SIZE, -                xport_params.num_send_frames*MAX_ETHERNET_MTU -        ); +        xport_params.send_buff_size = std::max(UDP_ZERO_COPY_DEFAULT_BUFF_SIZE, +            xport_params.num_send_frames * MAX_ETHERNET_MTU);      } -    #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) -        //limit default buffer size on macos to avoid the warning issued by resize_buff_helper -        if (not hints.has_key("recv_buff_size") and xport_params.recv_buff_size > MAX_BUFF_SIZE_ETH_MACOS) -        { -            xport_params.recv_buff_size = MAX_BUFF_SIZE_ETH_MACOS; -        } -        if (not hints.has_key("send_buff_size") and xport_params.send_buff_size > MAX_BUFF_SIZE_ETH_MACOS) -        { -            xport_params.send_buff_size = MAX_BUFF_SIZE_ETH_MACOS; -        } -    #endif +#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) +    // limit default buffer size on macos to avoid the warning issued by +    // resize_buff_helper +    if (not hints.has_key("recv_buff_size") +        and xport_params.recv_buff_size > MAX_BUFF_SIZE_ETH_MACOS) { +        xport_params.recv_buff_size = MAX_BUFF_SIZE_ETH_MACOS; +    } +    if (not hints.has_key("send_buff_size") +        and xport_params.send_buff_size > MAX_BUFF_SIZE_ETH_MACOS) { +        xport_params.send_buff_size = MAX_BUFF_SIZE_ETH_MACOS; +    } +#endif      udp_zero_copy_asio_impl::sptr udp_trans( -        new udp_zero_copy_asio_impl(addr, port, xport_params) -    ); - -    //call the helper to resize send and recv buffers -    buff_params_out.recv_buff_size = resize_buff_helper<asio::socket_base::receive_buffer_size>( -        udp_trans, xport_params.recv_buff_size, "recv"); -    buff_params_out.send_buff_size = resize_buff_helper<asio::socket_base::send_buffer_size> ( -        udp_trans, xport_params.send_buff_size, "send"); - -    if (buff_params_out.recv_buff_size < xport_params.num_recv_frames * MAX_ETHERNET_MTU){ -        UHD_LOG_WARNING("UDP", "The current recv_buff_size of " << xport_params.recv_buff_size -                        << " is less than the minimum recommended size of " -                        << xport_params.num_recv_frames * MAX_ETHERNET_MTU -                        << " and may result in dropped packets on some NICs"); +        new udp_zero_copy_asio_impl(addr, port, xport_params)); + +    // call the helper to resize send and recv buffers +    buff_params_out.recv_buff_size = +        resize_buff_helper<asio::socket_base::receive_buffer_size>( +            udp_trans, xport_params.recv_buff_size, "recv"); +    buff_params_out.send_buff_size = +        resize_buff_helper<asio::socket_base::send_buffer_size>( +            udp_trans, xport_params.send_buff_size, "send"); + +    if (buff_params_out.recv_buff_size +        < xport_params.num_recv_frames * MAX_ETHERNET_MTU) { +        UHD_LOG_WARNING("UDP", +            "The current recv_buff_size of " +                << xport_params.recv_buff_size +                << " is less than the minimum recommended size of " +                << xport_params.num_recv_frames * MAX_ETHERNET_MTU +                << " and may result in dropped packets on some NICs");      } -    if (buff_params_out.send_buff_size < xport_params.num_send_frames * MAX_ETHERNET_MTU){ -        UHD_LOG_WARNING("UDP", "The current send_buff_size of " << xport_params.send_buff_size -                        << " is less than the minimum recommended size of " -                        << xport_params.num_send_frames * MAX_ETHERNET_MTU -                        << " and may result in dropped packets on some NICs"); +    if (buff_params_out.send_buff_size +        < xport_params.num_send_frames * MAX_ETHERNET_MTU) { +        UHD_LOG_WARNING("UDP", +            "The current send_buff_size of " +                << xport_params.send_buff_size +                << " is less than the minimum recommended size of " +                << xport_params.num_send_frames * MAX_ETHERNET_MTU +                << " and may result in dropped packets on some NICs");      }      return udp_trans; diff --git a/host/lib/transport/usb_dummy_impl.cpp b/host/lib/transport/usb_dummy_impl.cpp index 81aad97c6..8e5084a9b 100644 --- a/host/lib/transport/usb_dummy_impl.cpp +++ b/host/lib/transport/usb_dummy_impl.cpp @@ -5,44 +5,48 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <uhd/transport/usb_device_handle.hpp> +#include <uhd/exception.hpp>  #include <uhd/transport/usb_control.hpp> +#include <uhd/transport/usb_device_handle.hpp>  #include <uhd/transport/usb_zero_copy.hpp> -#include <uhd/exception.hpp>  using namespace uhd;  using namespace uhd::transport; -usb_control::~usb_control(void){ +usb_control::~usb_control(void) +{      /* NOP */  } -usb_device_handle::~usb_device_handle(void) { +usb_device_handle::~usb_device_handle(void) +{      /* NOP */  } -usb_zero_copy::~usb_zero_copy(void) { +usb_zero_copy::~usb_zero_copy(void) +{      /* NOP */  } -std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(uint16_t, uint16_t){ -    return std::vector<usb_device_handle::sptr>(); //empty list +std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list( +    uint16_t, uint16_t) +{ +    return std::vector<usb_device_handle::sptr>(); // empty list  } -usb_control::sptr usb_control::make( -        usb_device_handle::sptr, -        const int -) { -    throw uhd::not_implemented_error("no usb support -> usb_control::make not implemented"); +usb_control::sptr usb_control::make(usb_device_handle::sptr, const int) +{ +    throw uhd::not_implemented_error( +        "no usb support -> usb_control::make not implemented");  } -usb_zero_copy::sptr usb_zero_copy::make( -    usb_device_handle::sptr, +usb_zero_copy::sptr usb_zero_copy::make(usb_device_handle::sptr,      const int,      const unsigned char,      const int,      const unsigned char, -    const device_addr_t & -){ -    throw uhd::not_implemented_error("no usb support -> usb_zero_copy::make not implemented"); +    const device_addr_t&) +{ +    throw uhd::not_implemented_error( +        "no usb support -> usb_zero_copy::make not implemented");  } diff --git a/host/lib/transport/xport_benchmarker.cpp b/host/lib/transport/xport_benchmarker.cpp index 0351d5106..67582ff2c 100644 --- a/host/lib/transport/xport_benchmarker.cpp +++ b/host/lib/transport/xport_benchmarker.cpp @@ -11,8 +11,7 @@  namespace uhd { namespace transport { -const device_addr_t& xport_benchmarker::benchmark_throughput_chdr -( +const device_addr_t& xport_benchmarker::benchmark_throughput_chdr(      zero_copy_if::sptr tx_transport,      zero_copy_if::sptr rx_transport,      uint32_t sid, @@ -24,8 +23,16 @@ const device_addr_t& xport_benchmarker::benchmark_throughput_chdr      _reset_counters();      boost::posix_time::ptime start_time(boost::posix_time::microsec_clock::local_time()); -    _tx_thread.reset(new boost::thread(boost::bind(&xport_benchmarker::_stream_tx, this, tx_transport.get(), &pkt_info, big_endian))); -    _rx_thread.reset(new boost::thread(boost::bind(&xport_benchmarker::_stream_rx, this, rx_transport.get(), &pkt_info, big_endian))); +    _tx_thread.reset(new boost::thread(boost::bind(&xport_benchmarker::_stream_tx, +        this, +        tx_transport.get(), +        &pkt_info, +        big_endian))); +    _rx_thread.reset(new boost::thread(boost::bind(&xport_benchmarker::_stream_rx, +        this, +        rx_transport.get(), +        &pkt_info, +        big_endian)));      std::this_thread::sleep_for(std::chrono::milliseconds(duration_ms)); @@ -35,17 +42,19 @@ const device_addr_t& xport_benchmarker::benchmark_throughput_chdr      _rx_thread->join();      boost::posix_time::ptime stop_time(boost::posix_time::microsec_clock::local_time()); -    double duration_s = ((double)(stop_time-start_time).total_microseconds())/1e6; - -    uint64_t tx_bytes = pkt_info.num_payload_words32*sizeof(uint32_t)*_num_tx_packets; -    uint64_t rx_bytes = pkt_info.num_payload_words32*sizeof(uint32_t)*_num_rx_packets; -    double tx_rate = (((double)tx_bytes)/duration_s); -    double rx_rate = (((double)rx_bytes)/duration_s); - -    _results["TX-Bytes"] = (boost::format("%.2fMB") % (tx_bytes/(1024*1024))).str(); -    _results["RX-Bytes"] = (boost::format("%.2fMB") % (rx_bytes/(1024*1024))).str(); -    _results["TX-Throughput"] = (boost::format("%.2fMB/s") % (tx_rate/(1024*1024))).str(); -    _results["RX-Throughput"] = (boost::format("%.2fMB/s") % (rx_rate/(1024*1024))).str(); +    double duration_s = ((double)(stop_time - start_time).total_microseconds()) / 1e6; + +    uint64_t tx_bytes = pkt_info.num_payload_words32 * sizeof(uint32_t) * _num_tx_packets; +    uint64_t rx_bytes = pkt_info.num_payload_words32 * sizeof(uint32_t) * _num_rx_packets; +    double tx_rate    = (((double)tx_bytes) / duration_s); +    double rx_rate    = (((double)rx_bytes) / duration_s); + +    _results["TX-Bytes"] = (boost::format("%.2fMB") % (tx_bytes / (1024 * 1024))).str(); +    _results["RX-Bytes"] = (boost::format("%.2fMB") % (rx_bytes / (1024 * 1024))).str(); +    _results["TX-Throughput"] = +        (boost::format("%.2fMB/s") % (tx_rate / (1024 * 1024))).str(); +    _results["RX-Throughput"] = +        (boost::format("%.2fMB/s") % (rx_rate / (1024 * 1024))).str();      _results["TX-Timeouts"] = std::to_string(_num_tx_timeouts);      _results["RX-Timeouts"] = std::to_string(_num_rx_timeouts);      _results["Data-Errors"] = std::to_string(_num_data_errors); @@ -53,20 +62,21 @@ const device_addr_t& xport_benchmarker::benchmark_throughput_chdr      return _results;  } -void xport_benchmarker::_stream_tx(zero_copy_if* transport, vrt::if_packet_info_t* pkt_info, bool big_endian) +void xport_benchmarker::_stream_tx( +    zero_copy_if* transport, vrt::if_packet_info_t* pkt_info, bool big_endian)  {      while (not boost::this_thread::interruption_requested()) {          managed_send_buffer::sptr buff = transport->get_send_buff(_tx_timeout);          if (buff) { -            uint32_t *packet_buff = buff->cast<uint32_t *>(); -            //Populate packet +            uint32_t* packet_buff = buff->cast<uint32_t*>(); +            // Populate packet              if (big_endian) {                  vrt::if_hdr_pack_be(packet_buff, *pkt_info);              } else {                  vrt::if_hdr_pack_le(packet_buff, *pkt_info);              } -            //send the buffer over the interface -            buff->commit(sizeof(uint32_t)*(pkt_info->num_packet_words32)); +            // send the buffer over the interface +            buff->commit(sizeof(uint32_t) * (pkt_info->num_packet_words32));              _num_tx_packets++;          } else {              _num_tx_timeouts++; @@ -74,20 +84,21 @@ void xport_benchmarker::_stream_tx(zero_copy_if* transport, vrt::if_packet_info_      }  } -void xport_benchmarker::_stream_rx(zero_copy_if* transport, const vrt::if_packet_info_t* exp_pkt_info, bool big_endian) +void xport_benchmarker::_stream_rx( +    zero_copy_if* transport, const vrt::if_packet_info_t* exp_pkt_info, bool big_endian)  {      while (not boost::this_thread::interruption_requested()) {          managed_recv_buffer::sptr buff = transport->get_recv_buff(_rx_timeout);          if (buff) { -            //Extract packet info +            // Extract packet info              vrt::if_packet_info_t pkt_info; -            pkt_info.link_type = exp_pkt_info->link_type; -            pkt_info.num_packet_words32 = buff->size()/sizeof(uint32_t); -            const uint32_t *packet_buff = buff->cast<const uint32_t *>(); +            pkt_info.link_type          = exp_pkt_info->link_type; +            pkt_info.num_packet_words32 = buff->size() / sizeof(uint32_t); +            const uint32_t* packet_buff = buff->cast<const uint32_t*>();              _num_rx_packets++; -            //unpacking can fail +            // unpacking can fail              try {                  if (big_endian) {                      vrt::if_hdr_unpack_be(packet_buff, pkt_info); @@ -95,11 +106,11 @@ void xport_benchmarker::_stream_rx(zero_copy_if* transport, const vrt::if_packet                      vrt::if_hdr_unpack_le(packet_buff, pkt_info);                  } -                if (exp_pkt_info->packet_type != pkt_info.packet_type || -                    exp_pkt_info->num_payload_bytes != pkt_info.num_payload_bytes) { +                if (exp_pkt_info->packet_type != pkt_info.packet_type +                    || exp_pkt_info->num_payload_bytes != pkt_info.num_payload_bytes) {                      _num_data_errors++;                  } -            } catch(const std::exception &ex) { +            } catch (const std::exception& ex) {                  _num_data_errors++;              }          } else { @@ -110,15 +121,14 @@ void xport_benchmarker::_stream_rx(zero_copy_if* transport, const vrt::if_packet  void xport_benchmarker::_reset_counters(void)  { -    _num_tx_packets = 0; -    _num_rx_packets = 0; +    _num_tx_packets  = 0; +    _num_rx_packets  = 0;      _num_tx_timeouts = 0;      _num_rx_timeouts = 0;      _num_data_errors = 0;  } -void xport_benchmarker::_initialize_chdr( -    zero_copy_if::sptr tx_transport, +void xport_benchmarker::_initialize_chdr(zero_copy_if::sptr tx_transport,      zero_copy_if::sptr rx_transport,      uint32_t sid,      vrt::if_packet_info_t& pkt_info) @@ -126,22 +136,23 @@ void xport_benchmarker::_initialize_chdr(      _tx_timeout = 0.5;      _rx_timeout = 0.5; -    size_t frame_size = std::min(tx_transport->get_send_frame_size(), rx_transport->get_recv_frame_size()); +    size_t frame_size = std::min( +        tx_transport->get_send_frame_size(), rx_transport->get_recv_frame_size()); -    pkt_info.link_type = vrt::if_packet_info_t::LINK_TYPE_CHDR; -    pkt_info.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; -    pkt_info.num_packet_words32 = (frame_size/sizeof(uint32_t)); +    pkt_info.link_type           = vrt::if_packet_info_t::LINK_TYPE_CHDR; +    pkt_info.packet_type         = vrt::if_packet_info_t::PACKET_TYPE_DATA; +    pkt_info.num_packet_words32  = (frame_size / sizeof(uint32_t));      pkt_info.num_payload_words32 = pkt_info.num_packet_words32 - 2; -    pkt_info.num_payload_bytes = pkt_info.num_payload_words32*sizeof(uint32_t); -    pkt_info.packet_count = 0; -    pkt_info.sob = false; -    pkt_info.eob = false; -    pkt_info.sid = sid; -    pkt_info.has_sid = true; -    pkt_info.has_cid = false; -    pkt_info.has_tsi = false; -    pkt_info.has_tsf = false; -    pkt_info.has_tlr = false; +    pkt_info.num_payload_bytes   = pkt_info.num_payload_words32 * sizeof(uint32_t); +    pkt_info.packet_count        = 0; +    pkt_info.sob                 = false; +    pkt_info.eob                 = false; +    pkt_info.sid                 = sid; +    pkt_info.has_sid             = true; +    pkt_info.has_cid             = false; +    pkt_info.has_tsi             = false; +    pkt_info.has_tsf             = false; +    pkt_info.has_tlr             = false;  } -}} +}} // namespace uhd::transport diff --git a/host/lib/transport/xport_benchmarker.hpp b/host/lib/transport/xport_benchmarker.hpp index c9ddee0e3..bd12c0ad8 100644 --- a/host/lib/transport/xport_benchmarker.hpp +++ b/host/lib/transport/xport_benchmarker.hpp @@ -8,20 +8,20 @@  #ifndef INCLUDED_LIBUHD_XPORT_BENCHMARKER_HPP  #define INCLUDED_LIBUHD_XPORT_BENCHMARKER_HPP +#include <uhd/transport/vrt_if_packet.hpp>  #include <uhd/transport/zero_copy.hpp>  #include <uhd/types/device_addr.hpp>  #include <uhd/utils/log.hpp>  #include <boost/shared_ptr.hpp>  #include <boost/thread/thread.hpp> -#include <uhd/transport/vrt_if_packet.hpp>  namespace uhd { namespace transport { -//Test class to benchmark a low-level transport object with a VITA/C-VITA data stream -class xport_benchmarker : boost::noncopyable { +// Test class to benchmark a low-level transport object with a VITA/C-VITA data stream +class xport_benchmarker : boost::noncopyable +{  public: -    const device_addr_t& benchmark_throughput_chdr( -        zero_copy_if::sptr tx_transport, +    const device_addr_t& benchmark_throughput_chdr(zero_copy_if::sptr tx_transport,          zero_copy_if::sptr rx_transport,          uint32_t sid,          bool big_endian, @@ -29,39 +29,35 @@ public:  private:      void _stream_tx( -        zero_copy_if* transport, -        vrt::if_packet_info_t* pkt_info, -        bool big_endian); +        zero_copy_if* transport, vrt::if_packet_info_t* pkt_info, bool big_endian); -    void _stream_rx( -        zero_copy_if* transport, +    void _stream_rx(zero_copy_if* transport,          const vrt::if_packet_info_t* exp_pkt_info,          bool big_endian); -    void _initialize_chdr( -        zero_copy_if::sptr tx_transport, +    void _initialize_chdr(zero_copy_if::sptr tx_transport,          zero_copy_if::sptr rx_transport,          uint32_t sid,          vrt::if_packet_info_t& pkt_info);      void _reset_counters(void); -    boost::shared_ptr<boost::thread>    _tx_thread; -    boost::shared_ptr<boost::thread>    _rx_thread; +    boost::shared_ptr<boost::thread> _tx_thread; +    boost::shared_ptr<boost::thread> _rx_thread; -    uint64_t     _num_tx_packets; -    uint64_t     _num_rx_packets; -    uint64_t     _num_tx_timeouts; -    uint64_t     _num_rx_timeouts; -    uint64_t     _num_data_errors; +    uint64_t _num_tx_packets; +    uint64_t _num_rx_packets; +    uint64_t _num_tx_timeouts; +    uint64_t _num_rx_timeouts; +    uint64_t _num_data_errors; -    double              _tx_timeout; -    double              _rx_timeout; +    double _tx_timeout; +    double _rx_timeout; -    device_addr_t       _results; +    device_addr_t _results;  }; -}} //namespace +}} // namespace uhd::transport  #endif /* INCLUDED_LIBUHD_XPORT_BENCHMARKER_HPP */ diff --git a/host/lib/transport/zero_copy_flow_ctrl.cpp b/host/lib/transport/zero_copy_flow_ctrl.cpp index 25be35569..7d1ddd7e0 100644 --- a/host/lib/transport/zero_copy_flow_ctrl.cpp +++ b/host/lib/transport/zero_copy_flow_ctrl.cpp @@ -5,16 +5,16 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <uhd/transport/zero_copy_flow_ctrl.hpp>  #include <uhd/transport/bounded_buffer.hpp>  #include <uhd/transport/buffer_pool.hpp> +#include <uhd/transport/zero_copy_flow_ctrl.hpp>  #include <uhd/utils/log.hpp>  #include <uhd/utils/safe_call.hpp> +#include <boost/bind.hpp>  #include <boost/format.hpp>  #include <boost/make_shared.hpp>  #include <boost/thread/mutex.hpp>  #include <boost/thread/thread.hpp> -#include <boost/bind.hpp>  using namespace uhd;  using namespace uhd::transport; @@ -24,11 +24,8 @@ typedef bounded_buffer<managed_send_buffer::sptr> bounded_buffer_t;  class zero_copy_flow_ctrl_msb : public managed_send_buffer  {  public: -    zero_copy_flow_ctrl_msb( -        flow_ctrl_func flow_ctrl -    ) : -        _mb(nullptr), -        _flow_ctrl(flow_ctrl) +    zero_copy_flow_ctrl_msb(flow_ctrl_func flow_ctrl) +        : _mb(nullptr), _flow_ctrl(flow_ctrl)      {          /* NOP */      } @@ -40,18 +37,18 @@ public:      void release()      { -        if (_mb) -        { +        if (_mb) {              _mb->commit(size()); -            while (_flow_ctrl and not _flow_ctrl(_mb)) {} +            while (_flow_ctrl and not _flow_ctrl(_mb)) { +            }              _mb.reset();          }      } -    UHD_INLINE sptr get(sptr &mb) +    UHD_INLINE sptr get(sptr& mb)      {          _mb = mb; -        return make(this, _mb->cast<void *>(), _mb->size()); +        return make(this, _mb->cast<void*>(), _mb->size());      }  private: @@ -62,11 +59,7 @@ private:  class zero_copy_flow_ctrl_mrb : public managed_recv_buffer  {  public: -    zero_copy_flow_ctrl_mrb( -        flow_ctrl_func flow_ctrl -    ) : -        _mb(NULL), -        _flow_ctrl(flow_ctrl) +    zero_copy_flow_ctrl_mrb(flow_ctrl_func flow_ctrl) : _mb(NULL), _flow_ctrl(flow_ctrl)      {          /* NOP */      } @@ -78,17 +71,17 @@ public:      void release()      { -        if (_mb) -        { +        if (_mb) {              _mb.reset();          }      } -    UHD_INLINE sptr get(sptr &mb) +    UHD_INLINE sptr get(sptr& mb)      {          _mb = mb; -        while (_flow_ctrl and not _flow_ctrl(_mb)) {} -        return make(this, _mb->cast<void *>(), _mb->size()); +        while (_flow_ctrl and not _flow_ctrl(_mb)) { +        } +        return make(this, _mb->cast<void*>(), _mb->size());      }  private: @@ -101,36 +94,35 @@ private:   * An intermediate transport that utilizes threading to free   * the main thread from any receive work.   **********************************************************************/ -class zero_copy_flow_ctrl_impl : public zero_copy_flow_ctrl { +class zero_copy_flow_ctrl_impl : public zero_copy_flow_ctrl +{  public:      typedef boost::shared_ptr<zero_copy_flow_ctrl_impl> sptr;      zero_copy_flow_ctrl_impl(zero_copy_if::sptr transport,          flow_ctrl_func send_flow_ctrl, -        flow_ctrl_func recv_flow_ctrl) : -        _transport(transport), -        _send_buffers(transport->get_num_send_frames()), -        _recv_buffers(transport->get_num_recv_frames()), -        _send_buff_index(0), -        _recv_buff_index(0), -        _send_flow_ctrl(send_flow_ctrl), -        _recv_flow_ctrl(recv_flow_ctrl) +        flow_ctrl_func recv_flow_ctrl) +        : _transport(transport) +        , _send_buffers(transport->get_num_send_frames()) +        , _recv_buffers(transport->get_num_recv_frames()) +        , _send_buff_index(0) +        , _recv_buff_index(0) +        , _send_flow_ctrl(send_flow_ctrl) +        , _recv_flow_ctrl(recv_flow_ctrl)      {          UHD_LOG_TRACE("TRANSPORT", "Created zero_copy_flow_ctrl"); -        for (size_t i = 0; i < transport->get_num_send_frames(); i++) -        { -            _send_buffers[i] = boost::make_shared<zero_copy_flow_ctrl_msb>(_send_flow_ctrl); +        for (size_t i = 0; i < transport->get_num_send_frames(); i++) { +            _send_buffers[i] = +                boost::make_shared<zero_copy_flow_ctrl_msb>(_send_flow_ctrl);          } -        for (size_t i = 0; i < transport->get_num_recv_frames(); i++) -        { -            _recv_buffers[i] = boost::make_shared<zero_copy_flow_ctrl_mrb>(_recv_flow_ctrl); +        for (size_t i = 0; i < transport->get_num_recv_frames(); i++) { +            _recv_buffers[i] = +                boost::make_shared<zero_copy_flow_ctrl_mrb>(_recv_flow_ctrl);          }      } -    ~zero_copy_flow_ctrl_impl() -    { -    } +    ~zero_copy_flow_ctrl_impl() {}      /*******************************************************************       * Receive implementation: @@ -140,9 +132,9 @@ public:      {          managed_recv_buffer::sptr ptr;          managed_recv_buffer::sptr buff = _transport->get_recv_buff(timeout); -        if (buff) -        { -            boost::shared_ptr<zero_copy_flow_ctrl_mrb> mb = _recv_buffers[_recv_buff_index++]; +        if (buff) { +            boost::shared_ptr<zero_copy_flow_ctrl_mrb> mb = +                _recv_buffers[_recv_buff_index++];              _recv_buff_index %= _recv_buffers.size();              ptr = mb->get(buff);          } @@ -167,9 +159,9 @@ public:      {          managed_send_buffer::sptr ptr;          managed_send_buffer::sptr buff = _transport->get_send_buff(timeout); -        if (buff) -        { -            boost::shared_ptr<zero_copy_flow_ctrl_msb> mb = _send_buffers[_send_buff_index++]; +        if (buff) { +            boost::shared_ptr<zero_copy_flow_ctrl_msb> mb = +                _send_buffers[_send_buff_index++];              _send_buff_index %= _send_buffers.size();              ptr = mb->get(buff);          } @@ -191,8 +183,8 @@ private:      zero_copy_if::sptr _transport;      // buffers -    std::vector< boost::shared_ptr<zero_copy_flow_ctrl_msb> > _send_buffers; -    std::vector< boost::shared_ptr<zero_copy_flow_ctrl_mrb> > _recv_buffers; +    std::vector<boost::shared_ptr<zero_copy_flow_ctrl_msb>> _send_buffers; +    std::vector<boost::shared_ptr<zero_copy_flow_ctrl_mrb>> _recv_buffers;      size_t _send_buff_index;      size_t _recv_buff_index; @@ -201,15 +193,12 @@ private:      flow_ctrl_func _recv_flow_ctrl;  }; -zero_copy_flow_ctrl::sptr zero_copy_flow_ctrl::make( -        zero_copy_if::sptr transport, -        flow_ctrl_func send_flow_ctrl, -        flow_ctrl_func recv_flow_ctrl -) +zero_copy_flow_ctrl::sptr zero_copy_flow_ctrl::make(zero_copy_if::sptr transport, +    flow_ctrl_func send_flow_ctrl, +    flow_ctrl_func recv_flow_ctrl)  {      zero_copy_flow_ctrl_impl::sptr zero_copy_flow_ctrl( -        new zero_copy_flow_ctrl_impl(transport, send_flow_ctrl, recv_flow_ctrl) -    ); +        new zero_copy_flow_ctrl_impl(transport, send_flow_ctrl, recv_flow_ctrl));      return zero_copy_flow_ctrl;  } diff --git a/host/lib/transport/zero_copy_recv_offload.cpp b/host/lib/transport/zero_copy_recv_offload.cpp index 4a8a07a0c..7329dbdf3 100644 --- a/host/lib/transport/zero_copy_recv_offload.cpp +++ b/host/lib/transport/zero_copy_recv_offload.cpp @@ -5,18 +5,17 @@  // SPDX-License-Identifier: GPL-3.0-or-later  // -#include <uhd/transport/zero_copy_recv_offload.hpp>  #include <uhd/transport/bounded_buffer.hpp>  #include <uhd/transport/buffer_pool.hpp> - +#include <uhd/transport/zero_copy_recv_offload.hpp>  #include <uhd/utils/log.hpp>  #include <uhd/utils/safe_call.hpp>  #include <uhd/utils/thread.hpp> +#include <boost/bind.hpp>  #include <boost/format.hpp>  #include <boost/make_shared.hpp>  #include <boost/thread/mutex.hpp>  #include <boost/thread/thread.hpp> -#include <boost/bind.hpp>  using namespace uhd;  using namespace uhd::transport; @@ -28,23 +27,23 @@ typedef bounded_buffer<managed_recv_buffer::sptr> bounded_buffer_t;   * An intermediate transport that utilizes threading to free   * the main thread from any receive work.   **********************************************************************/ -class zero_copy_recv_offload_impl : public zero_copy_recv_offload { +class zero_copy_recv_offload_impl : public zero_copy_recv_offload +{  public:      typedef boost::shared_ptr<zero_copy_recv_offload_impl> sptr; -    zero_copy_recv_offload_impl(zero_copy_if::sptr transport, -                          const double timeout) : -        _transport(transport), _timeout(timeout), -        _inbox(transport->get_num_recv_frames()), -        _recv_done(false) +    zero_copy_recv_offload_impl(zero_copy_if::sptr transport, const double timeout) +        : _transport(transport) +        , _timeout(timeout) +        , _inbox(transport->get_num_recv_frames()) +        , _recv_done(false)      { -        UHD_LOGGER_TRACE("XPORT") << "Created threaded transport" ; +        UHD_LOGGER_TRACE("XPORT") << "Created threaded transport";          // Create the receive and send threads to offload          // the system calls onto other threads -        _recv_thread = boost::thread( -            boost::bind(&zero_copy_recv_offload_impl::enqueue_recv, this) -        ); +        _recv_thread = +            boost::thread(boost::bind(&zero_copy_recv_offload_impl::enqueue_recv, this));          set_thread_name(&_recv_thread, "zero_copy_recv");      } @@ -67,9 +66,7 @@ public:          set_recv_done();          // Wait for them to join -        UHD_SAFE_CALL( -            _recv_thread.join(); -        ) +        UHD_SAFE_CALL(_recv_thread.join();)      }      // The receive thread function is responsible for @@ -78,7 +75,8 @@ public:      {          while (not is_recv_done()) {              managed_recv_buffer::sptr buff = _transport->get_recv_buff(_timeout); -            if (not buff) continue; +            if (not buff) +                continue;              _inbox.push_with_timed_wait(buff, _timeout);          }      } @@ -135,16 +133,14 @@ private:      // Threading      bool _recv_done;      boost::thread _recv_thread; -    boost::mutex  _recv_mutex; +    boost::mutex _recv_mutex;  };  zero_copy_recv_offload::sptr zero_copy_recv_offload::make( -        zero_copy_if::sptr transport, -        const double timeout) +    zero_copy_if::sptr transport, const double timeout)  {      zero_copy_recv_offload_impl::sptr zero_copy_recv_offload( -        new zero_copy_recv_offload_impl(transport, timeout) -    ); +        new zero_copy_recv_offload_impl(transport, timeout));      return zero_copy_recv_offload;  } | 
