From 0b609f776494ecff50c7a2a4d9880d3186fe2421 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 29 May 2010 00:50:29 -0700 Subject: added frame count call to zero-copy iface, tweaks for udp asio impl --- host/include/uhd/transport/zero_copy.hpp | 19 +++++++ host/lib/transport/udp_zero_copy_asio.cpp | 85 ++++++++++++++++++------------- 2 files changed, 68 insertions(+), 36 deletions(-) (limited to 'host') diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index 2efabaccf..d6eb89a91 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -123,10 +123,29 @@ namespace uhd{ namespace transport{ */ virtual managed_recv_buffer::sptr get_recv_buff(void) = 0; + /*! + * Get the maximum number of receive frames: + * The maximum number of valid managed recv buffers, + * or the maximum number of frames in the ring buffer, + * depending upon the underlying implementation. + * \return number of frames + */ + virtual size_t get_num_recv_frames(void) const = 0; + /*! * Get a new send buffer from this transport object. */ virtual managed_send_buffer::sptr get_send_buff(void) = 0; + + /*! + * Get the maximum number of send frames: + * The maximum number of valid managed send buffers, + * or the maximum number of frames in the ring buffer, + * depending upon the underlying implementation. + * \return number of frames + */ + virtual size_t get_num_send_frames(void) const = 0; + }; /*! diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 0c604811a..4402437f3 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -46,12 +46,42 @@ class udp_zero_copy_impl: public: typedef boost::shared_ptr sptr; - //structors - udp_zero_copy_impl(const std::string &addr, const std::string &port); - ~udp_zero_copy_impl(void); + udp_zero_copy_impl( + const std::string &addr, + const std::string &port + ): + phony_zero_copy_recv_if(MAX_DGRAM_SIZE), + phony_zero_copy_send_if(MAX_DGRAM_SIZE) + { + //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; + + // resolve the address + boost::asio::ip::udp::resolver resolver(_io_service); + boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port); + boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); + + // create, open, and connect the socket + _socket = new boost::asio::ip::udp::socket(_io_service); + _socket->open(boost::asio::ip::udp::v4()); + _socket->connect(receiver_endpoint); + + // set recv timeout + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = size_t(RECV_TIMEOUT*1e6); + UHD_ASSERT_THROW(setsockopt( + _socket->native(), + SOL_SOCKET, SO_RCVTIMEO, + (const char *)&tv, sizeof(timeval) + ) == 0); + } + + ~udp_zero_copy_impl(void){ + delete _socket; + } //get size for internal socket buffer - template size_t get_buff_size(void){ + template size_t get_buff_size(void) const{ Opt option; _socket->get_option(option); return option.value(); @@ -64,6 +94,20 @@ public: return get_buff_size(); } + + //The number of frames is approximately the buffer size divided by the max datagram size. + //In reality, this is a phony zero-copy interface and the number of frames is infinite. + //However, its sensible to advertise a frame count that is approximate to buffer size. + //This way, the transport caller will have an idea about how much buffering to create. + + size_t get_num_recv_frames(void) const{ + return this->get_buff_size()/MAX_DGRAM_SIZE; + } + + size_t get_num_send_frames(void) const{ + return this->get_buff_size()/MAX_DGRAM_SIZE; + } + private: boost::asio::ip::udp::socket *_socket; boost::asio::io_service _io_service; @@ -77,41 +121,10 @@ private: } }; -udp_zero_copy_impl::udp_zero_copy_impl(const std::string &addr, const std::string &port): - phony_zero_copy_recv_if(MAX_DGRAM_SIZE), - phony_zero_copy_send_if(MAX_DGRAM_SIZE) -{ - //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; - - // resolve the address - boost::asio::ip::udp::resolver resolver(_io_service); - boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port); - boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); - - // create, open, and connect the socket - _socket = new boost::asio::ip::udp::socket(_io_service); - _socket->open(boost::asio::ip::udp::v4()); - _socket->connect(receiver_endpoint); - - // set recv timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = size_t(RECV_TIMEOUT*1e6); - UHD_ASSERT_THROW(setsockopt( - _socket->native(), - SOL_SOCKET, SO_RCVTIMEO, - (const char *)&tv, sizeof(timeval) - ) == 0); -} - -udp_zero_copy_impl::~udp_zero_copy_impl(void){ - delete _socket; -} - /*********************************************************************** * UDP zero copy make function **********************************************************************/ -template static inline void resize_buff_helper( +template static void resize_buff_helper( udp_zero_copy_impl::sptr udp_trans, size_t target_size, const std::string &name -- cgit v1.2.3