diff options
| -rw-r--r-- | host/include/uhd/transport/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/include/uhd/transport/buffer_pool.hpp | 59 | ||||
| -rw-r--r-- | host/include/uhd/transport/if_addrs.hpp | 6 | ||||
| -rw-r--r-- | host/lib/transport/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/transport/buffer_pool.cpp | 80 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_zero_copy.cpp | 10 | ||||
| -rw-r--r-- | host/lib/transport/udp_zero_copy_asio.cpp | 12 | 
7 files changed, 155 insertions, 14 deletions
| diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 2c84c0724..adcfc7598 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -21,6 +21,7 @@ INSTALL(FILES      alignment_buffer.ipp      bounded_buffer.hpp      bounded_buffer.ipp +    buffer_pool.hpp      convert_types.hpp      convert_types.ipp      if_addrs.hpp diff --git a/host/include/uhd/transport/buffer_pool.hpp b/host/include/uhd/transport/buffer_pool.hpp new file mode 100644 index 000000000..b6c683948 --- /dev/null +++ b/host/include/uhd/transport/buffer_pool.hpp @@ -0,0 +1,59 @@ +// +// 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/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP +#define INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP + +#include <uhd/config.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace transport{ + +    /*! +     * A buffer pool manages memory for a homogeneous set of buffers. +     * Each buffer is the pool start at a 16-byte alignment boundary. +     */ +    class UHD_API buffer_pool : boost::noncopyable{ +    public: +        typedef boost::shared_ptr<buffer_pool> sptr; +        typedef void * ptr_type; + +        /*! +         * Make a new buffer pool. +         * \param num_buffs the number of buffers to allocate +         * \param buff_size the size of each buffer in bytes +         * \param alignment the alignment boundary in bytes +         * \return a new buffer pool buff_size X num_buffs +         */ +        static sptr make( +            const size_t num_buffs, +            const size_t buff_size, +            const size_t alignment = 16 +        ); + +        //! Get a pointer to the buffer start at the specified index +        virtual ptr_type at(const size_t index) const = 0; + +        //! Get the number of buffers in this pool +        virtual size_t size(void) const = 0; +    }; + +}} //namespace + + +#endif /* INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP */ diff --git a/host/include/uhd/transport/if_addrs.hpp b/host/include/uhd/transport/if_addrs.hpp index fbbb35e1d..84f24cb5a 100644 --- a/host/include/uhd/transport/if_addrs.hpp +++ b/host/include/uhd/transport/if_addrs.hpp @@ -15,8 +15,8 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // -#ifndef INCLUDED_UHD_IFADDRS_HPP -#define INCLUDED_UHD_IFADDRS_HPP +#ifndef INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP +#define INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP  #include <uhd/config.hpp>  #include <string> @@ -44,4 +44,4 @@ namespace uhd{ namespace transport{  }} //namespace -#endif /* INCLUDED_UHD_IFADDRS_HPP */ +#endif /* INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP */ diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index 0d6226e4c..4bfe03b10 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -109,6 +109,7 @@ SET_SOURCE_FILES_PROPERTIES(  )  LIBUHD_APPEND_SOURCES( +    ${CMAKE_CURRENT_SOURCE_DIR}/buffer_pool.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/udp_simple.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/udp_zero_copy_asio.cpp diff --git a/host/lib/transport/buffer_pool.cpp b/host/lib/transport/buffer_pool.cpp new file mode 100644 index 000000000..9a9ddfedf --- /dev/null +++ b/host/lib/transport/buffer_pool.cpp @@ -0,0 +1,80 @@ +// +// 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/buffer_pool.hpp> +#include <boost/shared_array.hpp> +#include <vector> + +using namespace uhd::transport; + +//! 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; +} + +/*********************************************************************** + * Buffer pool implementation + **********************************************************************/ +class buffer_pool_impl : public buffer_pool{ +public: +    buffer_pool_impl( +        const std::vector<buffer_pool::ptr_type> &ptrs, +        boost::shared_array<char> mem +    ): _ptrs(ptrs), _mem(mem){ +        /* NOP */ +    } + +    ptr_type at(const size_t index) const{ +        return _ptrs.at(index); +    } + +    size_t size(void) const{ +        return _ptrs.size(); +    } + +private: +    std::vector<void *> _ptrs; +    boost::shared_array<char> _mem; +}; + +/*********************************************************************** + * 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 padded_buff_size = pad_to_boundary(buff_size, alignment); +    boost::shared_array<char> mem(new char[padded_buff_size*num_buffs + alignment]); + +    //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); +    } + +    //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/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index f589d7c77..5dc230527 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -18,9 +18,9 @@  #include "libusb1_base.hpp"  #include <uhd/transport/usb_zero_copy.hpp>  #include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/buffer_pool.hpp>  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/assert.hpp> -#include <boost/shared_array.hpp>  #include <boost/foreach.hpp>  #include <boost/thread.hpp>  #include <boost/enable_shared_from_this.hpp> @@ -105,8 +105,8 @@ private:      //! a list of all transfer structs we allocated      std::vector<libusb_transfer *> _all_luts; -    //! a block of memory for the transfer buffers -    boost::shared_array<char> _buffer; +    //! memory allocated for the transfer buffers +    buffer_pool::sptr _buffer_pool;      // Calls for processing asynchronous I/O      libusb_transfer *allocate_transfer(void *mem, size_t len); @@ -157,9 +157,9 @@ usb_endpoint::usb_endpoint(      _input(input)  {      _completed_list = lut_buff_type::make(num_transfers); -    _buffer = boost::shared_array<char>(new char[num_transfers*transfer_size]); +    _buffer_pool = buffer_pool::make(num_transfers, transfer_size);      for (size_t i = 0; i < num_transfers; i++){ -        _all_luts.push_back(allocate_transfer(_buffer.get() + i*transfer_size, transfer_size)); +        _all_luts.push_back(allocate_transfer(_buffer_pool->at(i), transfer_size));          //input luts are immediately submitted to be filled          //output luts go into the completed list as free buffers diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index c758fa894..d979f4377 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -18,10 +18,10 @@  #include <uhd/transport/udp_zero_copy.hpp>  #include <uhd/transport/udp_simple.hpp> //mtu  #include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/buffer_pool.hpp>  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/assert.hpp>  #include <uhd/utils/warning.hpp> -#include <boost/shared_array.hpp>  #include <boost/asio.hpp>  #include <boost/format.hpp>  #include <boost/thread.hpp> @@ -123,16 +123,16 @@ public:      void init(void){          //allocate all recv frames and release them to begin xfers          _pending_recv_buffs = pending_buffs_type::make(_num_recv_frames); -        _recv_buffer = boost::shared_array<char>(new char[_num_recv_frames*_recv_frame_size]); +        _recv_buffer_pool = buffer_pool::make(_num_recv_frames, _recv_frame_size);          for (size_t i = 0; i < _num_recv_frames; i++){ -            release(_recv_buffer.get() + i*_recv_frame_size); +            release(_recv_buffer_pool->at(i));          }          //allocate all send frames and push them into the fifo          _pending_send_buffs = pending_buffs_type::make(_num_send_frames); -        _send_buffer = boost::shared_array<char>(new char[_num_send_frames*_send_frame_size]); +        _send_buffer_pool = buffer_pool::make(_num_send_frames, _send_frame_size);          for (size_t i = 0; i < _num_send_frames; i++){ -            handle_send(_send_buffer.get() + i*_send_frame_size); +            handle_send(_send_buffer_pool->at(i));          }          //spawn the service threads that will run the io service @@ -302,7 +302,7 @@ public:  private:      //memory management -> buffers and fifos      boost::thread_group _thread_group; -    boost::shared_array<char> _send_buffer, _recv_buffer; +    buffer_pool::sptr _send_buffer_pool, _recv_buffer_pool;      typedef bounded_buffer<asio::mutable_buffer> pending_buffs_type;      pending_buffs_type::sptr _pending_recv_buffs, _pending_send_buffs;      const size_t _recv_frame_size, _num_recv_frames; | 
