aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/udp_zero_copy_asio.cpp16
-rw-r--r--host/lib/transport/vrt_packet_handler.hpp35
2 files changed, 33 insertions, 18 deletions
diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index bfbcf62d8..bbbabf6d0 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -29,7 +29,11 @@ using namespace uhd::transport;
* Constants
**********************************************************************/
//enough buffering for half a second of samples at full rate on usrp2
-static const size_t MIN_SOCK_BUFF_SIZE = size_t(sizeof(boost::uint32_t) * 25e6 * 0.5);
+static const size_t MIN_RECV_SOCK_BUFF_SIZE = size_t(sizeof(boost::uint32_t) * 25e6 * 0.5);
+//Large buffers cause more underflow at high rates.
+//Perhaps this is due to the kernel scheduling,
+//but may change with host-based flow control.
+static const size_t MIN_SEND_SOCK_BUFF_SIZE = size_t(10e3);
static const double RECV_TIMEOUT = 0.1; //100 ms
/***********************************************************************
@@ -143,6 +147,10 @@ template<typename Opt> static void resize_buff_helper(
size_t target_size,
const std::string &name
){
+ size_t min_sock_buff_size = 0;
+ if (name == "recv") min_sock_buff_size = MIN_RECV_SOCK_BUFF_SIZE;
+ if (name == "send") min_sock_buff_size = MIN_SEND_SOCK_BUFF_SIZE;
+
//resize the buffer if size was provided
if (target_size > 0){
size_t actual_size = udp_trans->resize_buff<Opt>(target_size);
@@ -158,14 +166,14 @@ template<typename Opt> static void resize_buff_helper(
" The %s buffer is smaller than the requested size.\n"
" The minimum recommended buffer size is %d bytes.\n"
" See the USRP2 application notes on buffer resizing.\n"
- ) % name % MIN_SOCK_BUFF_SIZE << std::endl;
+ ) % name % min_sock_buff_size << std::endl;
}
//only enable on platforms that are happy with the large buffer resize
#if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)
//otherwise, ensure that the buffer is at least the minimum size
- else if (udp_trans->get_buff_size<Opt>() < MIN_SOCK_BUFF_SIZE){
- resize_buff_helper<Opt>(udp_trans, MIN_SOCK_BUFF_SIZE, name);
+ else if (udp_trans->get_buff_size<Opt>() < min_sock_buff_size){
+ resize_buff_helper<Opt>(udp_trans, min_sock_buff_size, name);
}
#endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/
}
diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp
index cf9d649dd..7e0588f03 100644
--- a/host/lib/transport/vrt_packet_handler.hpp
+++ b/host/lib/transport/vrt_packet_handler.hpp
@@ -35,15 +35,25 @@
namespace vrt_packet_handler{
+template <typename T> UHD_INLINE T get_context_code(
+ const boost::uint32_t *vrt_hdr,
+ const uhd::transport::vrt::if_packet_info_t &if_packet_info
+){
+ //extract the context word (we dont know the endianness so mirror the bytes)
+ boost::uint32_t word0 = vrt_hdr[if_packet_info.num_header_words32] |
+ uhd::byteswap(vrt_hdr[if_packet_info.num_header_words32]);
+ return T(word0 & 0xff);
+}
+
/***********************************************************************
* vrt packet handler for recv
**********************************************************************/
typedef std::vector<uhd::transport::managed_recv_buffer::sptr> managed_recv_buffs_t;
typedef boost::function<bool(managed_recv_buffs_t &)> get_recv_buffs_t;
- typedef boost::function<void(size_t /*which channel*/)> handle_overrun_t;
+ typedef boost::function<void(size_t /*which channel*/)> handle_overflow_t;
typedef boost::function<void(const boost::uint32_t *, uhd::transport::vrt::if_packet_info_t &)> vrt_unpacker_t;
- static inline void handle_overrun_nop(size_t){}
+ static inline void handle_overflow_nop(size_t){}
struct recv_state{
//width of the receiver in channels
@@ -75,7 +85,7 @@ namespace vrt_packet_handler{
uhd::rx_metadata_t &metadata,
double tick_rate,
const vrt_unpacker_t &vrt_unpacker,
- const handle_overrun_t &handle_overrun,
+ const handle_overflow_t &handle_overflow,
size_t vrt_header_offset_words32
){
//vrt unpack each managed buffer
@@ -92,22 +102,19 @@ namespace vrt_packet_handler{
const boost::uint32_t *vrt_hdr = state.managed_buffs[i]->cast<const boost::uint32_t *>() + vrt_header_offset_words32;
if_packet_info.num_packet_words32 = num_packet_words32 - vrt_header_offset_words32;
vrt_unpacker(vrt_hdr, if_packet_info);
- const boost::uint32_t *vrt_data = vrt_hdr + if_packet_info.num_header_words32;
//handle the non-data packet case and parse its contents
if (if_packet_info.packet_type != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA){
- //extract the context word (we dont know the endianness so mirror the bytes)
- boost::uint32_t word0 = vrt_data[0] | uhd::byteswap(vrt_data[0]);
- if (word0 & uhd::rx_metadata_t::ERROR_CODE_OVERRUN) handle_overrun(i);
- metadata.error_code = uhd::rx_metadata_t::error_code_t(word0 & 0xf);
+ metadata.error_code = get_context_code<uhd::rx_metadata_t::error_code_t>(vrt_hdr, if_packet_info);
+ if (metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) handle_overflow(i);
//break to exit loop and store metadata below
state.size_of_copy_buffs = 0; break;
}
//setup the buffer to point to the data
- state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(vrt_data);
+ state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(vrt_hdr + if_packet_info.num_header_words32);
//store the minimum payload length into the copy buffer length
size_t num_payload_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t);
@@ -142,7 +149,7 @@ namespace vrt_packet_handler{
double tick_rate,
const vrt_unpacker_t &vrt_unpacker,
const get_recv_buffs_t &get_recv_buffs,
- const handle_overrun_t &handle_overrun,
+ const handle_overflow_t &handle_overflow,
size_t vrt_header_offset_words32
){
metadata.error_code = uhd::rx_metadata_t::ERROR_CODE_NONE;
@@ -157,7 +164,7 @@ namespace vrt_packet_handler{
try{
_recv1_helper(
state, metadata, tick_rate,
- vrt_unpacker, handle_overrun,
+ vrt_unpacker, handle_overflow,
vrt_header_offset_words32
);
}catch(const std::exception &e){
@@ -216,7 +223,7 @@ namespace vrt_packet_handler{
double tick_rate,
const vrt_unpacker_t &vrt_unpacker,
const get_recv_buffs_t &get_recv_buffs,
- const handle_overrun_t &handle_overrun = &handle_overrun_nop,
+ const handle_overflow_t &handle_overflow = &handle_overflow_nop,
size_t vrt_header_offset_words32 = 0
){
switch(recv_mode){
@@ -233,7 +240,7 @@ namespace vrt_packet_handler{
tick_rate,
vrt_unpacker,
get_recv_buffs,
- handle_overrun,
+ handle_overflow,
vrt_header_offset_words32
);
}
@@ -253,7 +260,7 @@ namespace vrt_packet_handler{
tick_rate,
vrt_unpacker,
get_recv_buffs,
- handle_overrun,
+ handle_overflow,
vrt_header_offset_words32
);
if (num_samps == 0) break; //had a recv timeout or error, break loop