diff options
Diffstat (limited to 'host/include/uhd/transport/zero_copy.hpp')
-rw-r--r-- | host/include/uhd/transport/zero_copy.hpp | 106 |
1 files changed, 43 insertions, 63 deletions
diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index f80c738aa..1dc0e8e26 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -1,5 +1,5 @@ // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2012 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 @@ -22,23 +22,14 @@ #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> #include <boost/intrusive_ptr.hpp> +#include <boost/detail/atomic_count.hpp> namespace uhd{ namespace transport{ - //! Create smart pointer to a reusable managed buffer - template <typename T> UHD_INLINE boost::intrusive_ptr<T> make_managed_buffer(T *p){ - p->_ref_count = 1; //reset the count to 1 reference - return boost::intrusive_ptr<T>(p, false); - } - - /*! - * 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{ + //! Simple managed buffer with release interface + class UHD_API managed_buffer{ public: - typedef boost::intrusive_ptr<managed_recv_buffer> sptr; + managed_buffer(void):_ref_count(0){} /*! * Signal to the transport that we are done with the buffer. @@ -48,84 +39,73 @@ namespace uhd{ namespace transport{ virtual void release(void) = 0; /*! + * Use commit() to re-write the length (for use with send buffers). + * \param num_bytes the number of bytes written into the buffer + */ + UHD_INLINE void commit(size_t num_bytes){ + _length = num_bytes; + } + + /*! * Get a pointer to the underlying buffer. * \return a pointer into memory */ - template <class T> inline T cast(void) const{ - return static_cast<T>(this->get_buff()); + template <class T> UHD_INLINE T cast(void) const{ + return static_cast<T>(_buffer); } /*! * Get the size of the underlying buffer. * \return the number of bytes */ - inline size_t size(void) const{ - return this->get_size(); + UHD_INLINE size_t size(void) const{ + return _length; } - private: - virtual const void *get_buff(void) const = 0; - virtual size_t get_size(void) const = 0; + //! Create smart pointer to a reusable managed buffer + template <typename T> UHD_INLINE boost::intrusive_ptr<T> make( + T *p, void *buffer, size_t length + ){ + _buffer = buffer; + _length = length; + return boost::intrusive_ptr<T>(p); + } + + boost::detail::atomic_count _ref_count; - public: int _ref_count; + protected: + void *_buffer; + size_t _length; }; - UHD_INLINE void intrusive_ptr_add_ref(managed_recv_buffer *p){ + UHD_INLINE void intrusive_ptr_add_ref(managed_buffer *p){ ++(p->_ref_count); } - UHD_INLINE void intrusive_ptr_release(managed_recv_buffer *p){ + UHD_INLINE void intrusive_ptr_release(managed_buffer *p){ if (--(p->_ref_count) == 0) p->release(); } /*! + * 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 : public managed_buffer{ + public: + typedef boost::intrusive_ptr<managed_recv_buffer> sptr; + }; + + /*! * A managed send buffer: * Contains a reference to transport-managed memory, * and a method to commit the memory after writing. */ - class UHD_API managed_send_buffer{ + class UHD_API managed_send_buffer : public managed_buffer{ public: typedef boost::intrusive_ptr<managed_send_buffer> 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 commit(size_t num_bytes) = 0; - - /*! - * Get a pointer to the underlying buffer. - * \return a pointer into memory - */ - template <class T> inline T cast(void) const{ - return static_cast<T>(this->get_buff()); - } - - /*! - * Get the size of the underlying buffer. - * \return the number of bytes - */ - inline size_t size(void) const{ - return this->get_size(); - } - - private: - virtual void *get_buff(void) const = 0; - virtual size_t get_size(void) const = 0; - - public: int _ref_count; }; - UHD_INLINE void intrusive_ptr_add_ref(managed_send_buffer *p){ - ++(p->_ref_count); - } - - UHD_INLINE void intrusive_ptr_release(managed_send_buffer *p){ - if (--(p->_ref_count) == 0) p->commit(0); - } - /*! * A zero-copy interface for transport objects. * Provides a way to get send and receive buffers |