aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/transport/buffer_pool.cpp47
-rw-r--r--host/lib/transport/chdr.cpp107
-rw-r--r--host/lib/transport/dpdk_zero_copy.cpp286
-rw-r--r--host/lib/transport/dpdk_zero_copy.hpp41
-rw-r--r--host/lib/transport/if_addrs.cpp98
-rw-r--r--host/lib/transport/liberio_zero_copy.cpp142
-rw-r--r--host/lib/transport/liberio_zero_copy.hpp18
-rw-r--r--host/lib/transport/libusb1_base.cpp347
-rw-r--r--host/lib/transport/libusb1_base.hpp213
-rw-r--r--host/lib/transport/libusb1_control.cpp53
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp338
-rw-r--r--host/lib/transport/muxed_zero_copy_if.cpp226
-rw-r--r--host/lib/transport/nirio_zero_copy.cpp404
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp806
-rw-r--r--host/lib/transport/super_send_packet_handler.hpp406
-rw-r--r--host/lib/transport/tcp_zero_copy.cpp195
-rw-r--r--host/lib/transport/udp_common.hpp81
-rw-r--r--host/lib/transport/udp_simple.cpp99
-rw-r--r--host/lib/transport/udp_wsa_zero_copy.cpp399
-rw-r--r--host/lib/transport/udp_zero_copy.cpp439
-rw-r--r--host/lib/transport/usb_dummy_impl.cpp38
-rw-r--r--host/lib/transport/xport_benchmarker.cpp107
-rw-r--r--host/lib/transport/xport_benchmarker.hpp42
-rw-r--r--host/lib/transport/zero_copy_flow_ctrl.cpp99
-rw-r--r--host/lib/transport/zero_copy_recv_offload.cpp40
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;
}