From 0021abf18aaf3831d8aaa40574f1876c4f346a92 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 12 Apr 2010 12:22:29 -0700 Subject: Created zero copy interface/framework, made use of it in usrp2 udp transport stuff. --- host/include/uhd/transport/CMakeLists.txt | 2 +- host/include/uhd/transport/smart_buffer.hpp | 45 --------- host/include/uhd/transport/udp_zero_copy.hpp | 28 +----- host/include/uhd/transport/zero_copy.hpp | 133 +++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 69 deletions(-) delete mode 100644 host/include/uhd/transport/smart_buffer.hpp create mode 100644 host/include/uhd/transport/zero_copy.hpp (limited to 'host/include') diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 14b5ccd29..9a94ead1b 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -18,9 +18,9 @@ INSTALL(FILES if_addrs.hpp - smart_buffer.hpp udp_simple.hpp udp_zero_copy.hpp vrt.hpp + zero_copy.hpp DESTINATION ${INCLUDE_DIR}/uhd/transport ) diff --git a/host/include/uhd/transport/smart_buffer.hpp b/host/include/uhd/transport/smart_buffer.hpp deleted file mode 100644 index a9bc259e9..000000000 --- a/host/include/uhd/transport/smart_buffer.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -#ifndef INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP -#define INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP - -#include -#include -#include - -namespace uhd{ namespace transport{ - -/*! - * A buffer that knows how to free itself: - * - * This is just the smart buffer interface. - * A transport implementation will have its own - * internal (custom) smart buffer implementation. - * - * A smart buffer contains a boost asio const buffer. - * On destruction, the buffer contents will be freed. - */ -class smart_buffer : boost::noncopyable{ -public: - typedef boost::shared_ptr sptr; - virtual const boost::asio::const_buffer &get(void) const = 0; -}; - -}} //namespace - -#endif /* INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP */ diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index 0441a8e74..fd1cec46e 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -19,24 +19,22 @@ #define INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP #include -#include -#include -#include +#include #include namespace uhd{ namespace transport{ /*! * A zero copy udp transport provides an efficient way to handle data. - * by avoiding the extra copy when recv() is called on the socket. - * Rather, the zero copy transport gives the caller a memory reference. + * by avoiding the extra copy when recv() or send() is called on the socket. + * Rather, the zero copy transport gives the caller memory references. * The caller informs the transport when it is finished with the reference. * * On linux systems, the zero copy transport can use a kernel packet ring. * If no platform specific solution is available, make returns a boost asio - * implementation that wraps the functionality around a standard recv() call. + * implementation that wraps the functionality around a standard send/recv calls. */ -class UHD_API udp_zero_copy : boost::noncopyable{ +class UHD_API udp_zero_copy : public zero_copy_if{ public: typedef boost::shared_ptr sptr; @@ -54,22 +52,6 @@ public: * \param port a string representing the destination port */ static sptr make(const std::string &addr, const std::string &port); - - /*! - * Send a single buffer. - * Blocks until the data is sent. - * \param buff single asio buffer - * \return the number of bytes sent - */ - virtual size_t send(const boost::asio::const_buffer &buff) = 0; - - /*! - * Receive a buffer. - * Blocks until data is received or a timeout occurs. - * The memory is managed by the implementation. - * \return a smart buffer (empty on timeout) - */ - virtual smart_buffer::sptr recv(void) = 0; }; }} //namespace diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp new file mode 100644 index 000000000..4fc1df9de --- /dev/null +++ b/host/include/uhd/transport/zero_copy.hpp @@ -0,0 +1,133 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP +#define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP + +#include +#include +#include +#include + +namespace uhd{ namespace transport{ + +/*! + * A managed receive buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after reading. + */ +class UHD_API managed_recv_buffer : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Signal to the transport that we are done with the buffer. + * This should be called to release the buffer to the transport. + * After calling, the referenced memory should be considered invalid. + */ + virtual void done(void) = 0; + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + size_t size(void){ + return boost::asio::buffer_size(this->get()); + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template T cast(void){ + return boost::asio::buffer_cast(this->get()); + } + +private: + /*! + * Get a reference to the internal const buffer. + * The buffer has a reference to memory and a size. + * \return a boost asio const buffer + */ + virtual const boost::asio::const_buffer &get(void) = 0; +}; + +/*! + * A managed send buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after writing. + */ +class UHD_API managed_send_buffer : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Signal to the transport that we are done with the buffer. + * This should be called to commit the write to the transport object. + * After calling, the referenced memory should be considered invalid. + * \param num_bytes the number of bytes written into the buffer + */ + virtual void done(size_t num_bytes) = 0; + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + size_t size(void){ + return boost::asio::buffer_size(this->get()); + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template T cast(void){ + return boost::asio::buffer_cast(this->get()); + } + +private: + /*! + * Get a reference to the internal mutable buffer. + * The buffer has a reference to memory and a size. + * \return a boost asio mutable buffer + */ + virtual const boost::asio::mutable_buffer &get(void) = 0; +}; + +/*! + * A zero-copy interface for transport objects. + * Provides a way to get send and receive buffers + * with memory managed by the transport object. + */ +class UHD_API zero_copy_if : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Get a new receive buffer from this transport object. + */ + virtual managed_recv_buffer::sptr get_recv_buff(void) = 0; + + /*! + * Get a new send buffer from this transport object. + */ + virtual managed_send_buffer::sptr get_send_buff(void) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP */ -- cgit v1.2.3