aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport/zero_copy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport/zero_copy.cpp')
-rw-r--r--host/lib/transport/zero_copy.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/host/lib/transport/zero_copy.cpp b/host/lib/transport/zero_copy.cpp
new file mode 100644
index 000000000..8a1cde694
--- /dev/null
+++ b/host/lib/transport/zero_copy.cpp
@@ -0,0 +1,143 @@
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/transport/zero_copy.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+using namespace uhd::transport;
+
+/***********************************************************************
+ * The pure-virtual deconstructor needs an implementation to be happy
+ **********************************************************************/
+managed_recv_buffer::~managed_recv_buffer(void){
+ /* NOP */
+}
+
+/***********************************************************************
+ * Phony zero-copy recv interface implementation
+ **********************************************************************/
+
+//! phony zero-copy recv buffer implementation
+class managed_recv_buffer_impl : public managed_recv_buffer{
+public:
+ managed_recv_buffer_impl(const boost::asio::const_buffer &buff) : _buff(buff){
+ /* NOP */
+ }
+
+ ~managed_recv_buffer_impl(void){
+ delete [] this->cast<const boost::uint8_t *>();
+ }
+
+private:
+ const boost::asio::const_buffer &get(void) const{
+ return _buff;
+ }
+
+ const boost::asio::const_buffer _buff;
+};
+
+//! phony zero-copy recv interface implementation
+struct phony_zero_copy_recv_if::impl{
+ impl(size_t max_buff_size) : max_buff_size(max_buff_size){
+ /* NOP */
+ }
+ size_t max_buff_size;
+};
+
+phony_zero_copy_recv_if::phony_zero_copy_recv_if(size_t max_buff_size){
+ _impl = UHD_PIMPL_MAKE(impl, (max_buff_size));
+}
+
+phony_zero_copy_recv_if::~phony_zero_copy_recv_if(void){
+ /* NOP */
+}
+
+managed_recv_buffer::sptr phony_zero_copy_recv_if::get_recv_buff(void){
+ //allocate memory
+ boost::uint8_t *recv_mem = new boost::uint8_t[_impl->max_buff_size];
+
+ //call recv() with timeout option
+ ssize_t num_bytes = this->recv(boost::asio::buffer(recv_mem, _impl->max_buff_size));
+
+ if (num_bytes <= 0) return managed_recv_buffer::sptr(); //NULL sptr
+
+ //create a new managed buffer to house the data
+ return managed_recv_buffer::sptr(
+ new managed_recv_buffer_impl(boost::asio::buffer(recv_mem, num_bytes))
+ );
+}
+
+/***********************************************************************
+ * Phony zero-copy send interface implementation
+ **********************************************************************/
+
+//! phony zero-copy send buffer implementation
+class managed_send_buffer_impl : public managed_send_buffer{
+public:
+ typedef boost::function<ssize_t(const boost::asio::const_buffer &)> send_fcn_t;
+
+ managed_send_buffer_impl(
+ const boost::asio::mutable_buffer &buff,
+ const send_fcn_t &send_fcn
+ ):
+ _buff(buff),
+ _send_fcn(send_fcn)
+ {
+ /* NOP */
+ }
+
+ ~managed_send_buffer_impl(void){
+ /* NOP */
+ }
+
+ ssize_t commit(size_t num_bytes){
+ return _send_fcn(boost::asio::buffer(_buff, num_bytes));
+ }
+
+private:
+ const boost::asio::mutable_buffer &get(void) const{
+ return _buff;
+ }
+
+ const boost::asio::mutable_buffer _buff;
+ const send_fcn_t _send_fcn;
+};
+
+//! phony zero-copy send interface implementation
+struct phony_zero_copy_send_if::impl{
+ boost::uint8_t *send_mem;
+ managed_send_buffer::sptr send_buff;
+};
+
+phony_zero_copy_send_if::phony_zero_copy_send_if(size_t max_buff_size){
+ _impl = UHD_PIMPL_MAKE(impl, ());
+ _impl->send_mem = new boost::uint8_t[max_buff_size];
+ _impl->send_buff = managed_send_buffer::sptr(new managed_send_buffer_impl(
+ boost::asio::buffer(_impl->send_mem, max_buff_size),
+ boost::bind(&phony_zero_copy_send_if::send, this, _1)
+ ));
+}
+
+phony_zero_copy_send_if::~phony_zero_copy_send_if(void){
+ delete [] _impl->send_mem;
+}
+
+managed_send_buffer::sptr phony_zero_copy_send_if::get_send_buff(void){
+ return _impl->send_buff; //FIXME there is only ever one send buff, we assume that the caller doesnt hang onto these
+}