diff options
Diffstat (limited to 'host/include')
| -rw-r--r-- | host/include/uhd/device.hpp | 27 | ||||
| -rw-r--r-- | host/include/uhd/device.ipp | 9 | ||||
| -rw-r--r-- | host/include/uhd/transport/alignment_buffer.hpp | 9 | ||||
| -rw-r--r-- | host/include/uhd/transport/alignment_buffer.ipp | 15 | ||||
| -rw-r--r-- | host/include/uhd/transport/bounded_buffer.hpp | 12 | ||||
| -rw-r--r-- | host/include/uhd/transport/bounded_buffer.ipp | 15 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_device_handle.hpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/transport/zero_copy.hpp | 118 | 
8 files changed, 83 insertions, 124 deletions
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index 2077cae62..992276928 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -41,9 +41,6 @@ public:      typedef boost::function<device_addrs_t(const device_addr_t &)> find_t;      typedef boost::function<sptr(const device_addr_t &)> make_t; -    //! A reasonable default timeout for receive -    static const size_t default_recv_timeout_ms = 100; -      /*!       * Register a device into the discovery and factory system.       * @@ -112,12 +109,15 @@ public:       *       * This is a blocking call and will not return until the number       * of samples returned have been read out of each buffer. +     * Under a timeout condition, the number of samples returned +     * may be less than the number of samples specified.       *       * \param buffs a vector of read-only memory containing IF data       * \param nsamps_per_buff the number of samples to send, per buffer       * \param metadata data describing the buffer's contents       * \param io_type the type of data loaded in the buffer       * \param send_mode tells send how to unload the buffer +     * \param timeout the timeout in seconds to wait on a packet       * \return the number of samples sent       */      virtual size_t send( @@ -125,7 +125,8 @@ public:          size_t nsamps_per_buff,          const tx_metadata_t &metadata,          const io_type_t &io_type, -        send_mode_t send_mode +        send_mode_t send_mode, +        double timeout = 0.1      ) = 0;      /*! @@ -136,7 +137,8 @@ public:          size_t nsamps_per_buff,          const tx_metadata_t &metadata,          const io_type_t &io_type, -        send_mode_t send_mode +        send_mode_t send_mode, +        double timeout = 0.1      );      /*! @@ -154,7 +156,9 @@ public:       * See the rx metadata fragment flags and offset fields for details.       *       * This is a blocking call and will not return until the number -     * of samples returned have been written into each buffer or timeout. +     * of samples returned have been written into each buffer. +     * Under a timeout condition, the number of samples returned +     * may be less than the number of samples specified.       *       * When using the full buffer recv mode, the metadata only applies       * to the first packet received and written into the recv buffers. @@ -165,7 +169,7 @@ public:       * \param metadata data to fill describing the buffer       * \param io_type the type of data to fill into the buffer       * \param recv_mode tells recv how to load the buffer -     * \param timeout_ms the timeout in milliseconds to wait for a packet +     * \param timeout the timeout in seconds to wait for a packet       * \return the number of samples received or 0 on error       */      virtual size_t recv( @@ -174,7 +178,7 @@ public:          rx_metadata_t &metadata,          const io_type_t &io_type,          recv_mode_t recv_mode, -        size_t timeout_ms = default_recv_timeout_ms +        double timeout = 0.1      ) = 0;      /*! @@ -186,7 +190,7 @@ public:          rx_metadata_t &metadata,          const io_type_t &io_type,          recv_mode_t recv_mode, -        size_t timeout_ms = default_recv_timeout_ms +        double timeout = 0.1      );      /*! @@ -204,12 +208,11 @@ public:      /*!       * Receive and asynchronous message from the device.       * \param async_metadata the metadata to be filled in -     * \param timeout_ms the timeout in milliseconds to wait for a message +     * \param timeout the timeout in seconds to wait for a message       * \return true when the async_metadata is valid, false for timeout       */      virtual bool recv_async_msg( -        async_metadata_t &async_metadata, -        size_t timeout_ms = default_recv_timeout_ms +        async_metadata_t &async_metadata, double timeout = 0.1      ) = 0;  }; diff --git a/host/include/uhd/device.ipp b/host/include/uhd/device.ipp index 60a3f535d..e2e51ecd0 100644 --- a/host/include/uhd/device.ipp +++ b/host/include/uhd/device.ipp @@ -25,12 +25,13 @@ namespace uhd{          size_t nsamps_per_buff,          const tx_metadata_t &metadata,          const io_type_t &io_type, -        send_mode_t send_mode +        send_mode_t send_mode, +        double timeout      ){          return this->send(              std::vector<const void *>(1, buff),              nsamps_per_buff, metadata, -            io_type, send_mode +            io_type, send_mode, timeout          );      } @@ -40,12 +41,12 @@ namespace uhd{          rx_metadata_t &metadata,          const io_type_t &io_type,          recv_mode_t recv_mode, -        size_t timeout_ms +        double timeout      ){          return this->recv(              std::vector<void *>(1, buff),              nsamps_per_buff, metadata, -            io_type, recv_mode, timeout_ms +            io_type, recv_mode, timeout          );      } diff --git a/host/include/uhd/transport/alignment_buffer.hpp b/host/include/uhd/transport/alignment_buffer.hpp index 29ba74efc..f44a037f8 100644 --- a/host/include/uhd/transport/alignment_buffer.hpp +++ b/host/include/uhd/transport/alignment_buffer.hpp @@ -48,20 +48,17 @@ namespace uhd{ namespace transport{           * \return true if the element fit without popping for space           */          virtual bool push_with_pop_on_full( -            const elem_type &elem, -            const seq_type &seq, -            size_t index +            const elem_type &elem, const seq_type &seq, size_t index          ) = 0;          /*!           * Pop an aligned set of elements from this alignment buffer.           * \param elems a collection to store the aligned elements -         * \param time the timeout time +         * \param timeout the timeout in seconds           * \return false when the operation times out           */          virtual bool pop_elems_with_timed_wait( -            std::vector<elem_type> &elems, -            const time_duration_t &time +            std::vector<elem_type> &elems, double timeout          ) = 0;      }; diff --git a/host/include/uhd/transport/alignment_buffer.ipp b/host/include/uhd/transport/alignment_buffer.ipp index 61b3b60f5..5f09de0d9 100644 --- a/host/include/uhd/transport/alignment_buffer.ipp +++ b/host/include/uhd/transport/alignment_buffer.ipp @@ -41,9 +41,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool push_with_pop_on_full( -            const elem_type &elem, -            const seq_type &seq, -            size_t index +            const elem_type &elem, const seq_type &seq, size_t index          ){              //clear the buffer for this index if the seqs are mis-ordered              if (seq < _last_seqs[index]){ @@ -54,17 +52,16 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool pop_elems_with_timed_wait( -            std::vector<elem_type> &elems, -            const time_duration_t &time +            std::vector<elem_type> &elems, double timeout          ){ -            boost::system_time exit_time = boost::get_system_time() + time; +            boost::system_time exit_time = boost::get_system_time() + boost::posix_time::microseconds(long(timeout*1e6));              buff_contents_type buff_contents_tmp;              std::list<size_t> indexes_to_do(_all_indexes);              //do an initial pop to load an initial sequence id              size_t index = indexes_to_do.front();              if (not _buffs[index]->pop_with_timed_wait( -                buff_contents_tmp, exit_time - boost::get_system_time() +                buff_contents_tmp, 1e-6*(exit_time - boost::get_system_time()).total_microseconds()              )) return false;              elems[index] = buff_contents_tmp.first;              seq_type expected_seq_id = buff_contents_tmp.second; @@ -79,7 +76,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/                      indexes_to_do = _all_indexes;                      index = indexes_to_do.front();                      if (not _buffs[index]->pop_with_timed_wait( -                        buff_contents_tmp, exit_time - boost::get_system_time() +                        buff_contents_tmp, 1e-6*(exit_time - boost::get_system_time()).total_microseconds()                      )) return false;                      elems[index] = buff_contents_tmp.first;                      expected_seq_id = buff_contents_tmp.second; @@ -89,7 +86,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/                  //pop an element off for this index                  index = indexes_to_do.front();                  if (not _buffs[index]->pop_with_timed_wait( -                    buff_contents_tmp, exit_time - boost::get_system_time() +                    buff_contents_tmp, 1e-6*(exit_time - boost::get_system_time()).total_microseconds()                  )) return false;                  //if the sequence id matches: diff --git a/host/include/uhd/transport/bounded_buffer.hpp b/host/include/uhd/transport/bounded_buffer.hpp index d1deece96..aca93b071 100644 --- a/host/include/uhd/transport/bounded_buffer.hpp +++ b/host/include/uhd/transport/bounded_buffer.hpp @@ -20,13 +20,9 @@  #include <uhd/config.hpp>  #include <boost/shared_ptr.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp>  namespace uhd{ namespace transport{ -    //! typedef for the time duration type for wait operations -    typedef boost::posix_time::time_duration time_duration_t; -      /*!       * Implement a templated bounded buffer:       * Used for passing elements between threads in a producer-consumer model. @@ -64,10 +60,10 @@ namespace uhd{ namespace transport{           * Push a new element into the bounded_buffer.           * Wait until the bounded_buffer becomes non-full or timeout.           * \param elem the new element to push -         * \param time the timeout time +         * \param timeout the timeout in seconds           * \return false when the operation times out           */ -        virtual bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time) = 0; +        virtual bool push_with_timed_wait(const elem_type &elem, double timeout) = 0;          /*!           * Pop an element from the bounded_buffer. @@ -80,10 +76,10 @@ namespace uhd{ namespace transport{           * Pop an element from the bounded_buffer.           * Wait until the bounded_buffer becomes non-empty or timeout.           * \param elem the element reference pop to -         * \param time the timeout time +         * \param timeout the timeout in seconds           * \return false when the operation times out           */ -        virtual bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time) = 0; +        virtual bool pop_with_timed_wait(elem_type &elem, double timeout) = 0;          /*!           * Clear all elements from the bounded_buffer. diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp index e106e229e..71143741e 100644 --- a/host/include/uhd/transport/bounded_buffer.ipp +++ b/host/include/uhd/transport/bounded_buffer.ipp @@ -21,6 +21,7 @@  #include <boost/bind.hpp>  #include <boost/circular_buffer.hpp>  #include <boost/thread/condition.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp>  namespace uhd{ namespace transport{ namespace{ /*anon*/ @@ -57,9 +58,12 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/              _empty_cond.notify_one();          } -        bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time){ +        bool push_with_timed_wait(const elem_type &elem, double timeout){              boost::unique_lock<boost::mutex> lock(_mutex); -            if (not _full_cond.timed_wait(lock, time, boost::bind(&bounded_buffer_impl<elem_type>::not_full, this))) return false; +            if (not _full_cond.timed_wait( +                lock, boost::posix_time::microseconds(long(timeout*1e6)), +                boost::bind(&bounded_buffer_impl<elem_type>::not_full, this) +            )) return false;              _buffer.push_front(elem);              lock.unlock();              _empty_cond.notify_one(); @@ -74,9 +78,12 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/              _full_cond.notify_one();          } -        bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time){ +        bool pop_with_timed_wait(elem_type &elem, double timeout){              boost::unique_lock<boost::mutex> lock(_mutex); -            if (not _empty_cond.timed_wait(lock, time, boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this))) return false; +            if (not _empty_cond.timed_wait( +                lock, boost::posix_time::microseconds(long(timeout*1e6)), +                boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this) +            )) return false;              elem = _buffer.back(); _buffer.pop_back();              lock.unlock();              _full_cond.notify_one(); diff --git a/host/include/uhd/transport/usb_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp index 9bb7db9c4..6f8d868be 100644 --- a/host/include/uhd/transport/usb_device_handle.hpp +++ b/host/include/uhd/transport/usb_device_handle.hpp @@ -38,7 +38,7 @@ namespace uhd { namespace transport {   *       a true descriptor serial number string. This interface returns the   *       actual string descriptor.   */ -class usb_device_handle : boost::noncopyable { +class UHD_API usb_device_handle : boost::noncopyable {  public:      typedef boost::shared_ptr<usb_device_handle> sptr; diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index 8ecafd3fb..9dd16280c 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -19,10 +19,10 @@  #define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP  #include <uhd/config.hpp> -#include <uhd/utils/pimpl.hpp>  #include <boost/asio/buffer.hpp>  #include <boost/utility.hpp>  #include <boost/shared_ptr.hpp> +#include <boost/function.hpp>  namespace uhd{ namespace transport{ @@ -34,14 +34,27 @@ namespace uhd{ namespace transport{      class UHD_API managed_recv_buffer : boost::noncopyable{      public:          typedef boost::shared_ptr<managed_recv_buffer> sptr; +        typedef boost::function<void(void)> release_fcn_t; + +        /*! +         * Make a safe managed receive buffer: +         * A safe managed buffer ensures that release is called once, +         * either by the user or automatically upon deconstruction. +         * \param buff a reference to the constant buffer +         * \param release_fcn callback to release the memory +         * \return a new managed receive buffer +         */ +        static sptr make_safe( +            const boost::asio::const_buffer &buff, +            const release_fcn_t &release_fcn +        );          /*! -         * Managed recv buffer destructor:           * Signal to the transport that we are done with the buffer. -         * This should be called to release the buffer to the transport. +         * This should be called to release the buffer to the transport object.           * After calling, the referenced memory should be considered invalid.           */ -        virtual ~managed_recv_buffer(void) = 0; +        virtual void release(void) = 0;          /*!           * Get the size of the underlying buffer. @@ -71,20 +84,34 @@ namespace uhd{ namespace transport{      /*!       * A managed send buffer:       * Contains a reference to transport-managed memory, -     * and a method to release the memory after writing. +     * and a method to commit the memory after writing.       */      class UHD_API managed_send_buffer : boost::noncopyable{      public:          typedef boost::shared_ptr<managed_send_buffer> sptr; +        typedef boost::function<void(size_t)> commit_fcn_t; + +        /*! +         * Make a safe managed send buffer: +         * A safe managed buffer ensures that commit is called once, +         * either by the user or automatically upon deconstruction. +         * In the later case, the deconstructor will call commit(0). +         * \param buff a reference to the mutable buffer +         * \param commit_fcn callback to commit the memory +         * \return a new managed send buffer +         */ +        static sptr make_safe( +            const boost::asio::mutable_buffer &buff, +            const commit_fcn_t &commit_fcn +        );          /*!           * 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 -         * \return the number of bytes written, 0 for timeout, negative for error           */ -        virtual ssize_t commit(size_t num_bytes) = 0; +        virtual void commit(size_t num_bytes) = 0;          /*!           * Get the size of the underlying buffer. @@ -122,10 +149,10 @@ namespace uhd{ namespace transport{          /*!           * Get a new receive buffer from this transport object. -         * \param timeout_ms the timeout to get the buffer in ms +         * \param timeout the timeout to get the buffer in seconds           * \return a managed buffer, or null sptr on timeout/error           */ -        virtual managed_recv_buffer::sptr get_recv_buff(size_t timeout_ms) = 0; +        virtual managed_recv_buffer::sptr get_recv_buff(double timeout = 0.1) = 0;          /*!           * Get the maximum number of receive frames: @@ -138,9 +165,10 @@ namespace uhd{ namespace transport{          /*!           * Get a new send buffer from this transport object. +         * \param timeout the timeout to get the buffer in seconds           * \return a managed buffer, or null sptr on timeout/error           */ -        virtual managed_send_buffer::sptr get_send_buff(void) = 0; +        virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 0;          /*!           * Get the maximum number of send frames: @@ -153,76 +181,6 @@ namespace uhd{ namespace transport{      }; -    /*! -     * A phony-zero-copy interface for transport objects that -     * provides a zero-copy interface on top of copying transport. -     * This interface implements the get managed recv buffer, -     * the base class must implement the private recv method. -     */ -    class UHD_API phony_zero_copy_recv_if : public virtual zero_copy_if{ -    public: -        /*! -         * Create a phony zero copy recv interface. -         * \param max_buff_size max buffer size in bytes -         */ -        phony_zero_copy_recv_if(size_t max_buff_size); - -        //! destructor -        virtual ~phony_zero_copy_recv_if(void); - -        /*! -         * Get a new receive buffer from this transport object. -         * \param timeout_ms the timeout to get the buffer in ms -         * \return a managed buffer, or null sptr on timeout/error -         */ -        managed_recv_buffer::sptr get_recv_buff(size_t timeout_ms); - -    private: -        /*! -         * Perform a private copying recv. -         * \param buff the buffer to write data into -         * \param timeout_ms the timeout to get the buffer in ms -         * \return the number of bytes written to buff, 0 for timeout, negative for error -         */ -        virtual ssize_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0; - -        UHD_PIMPL_DECL(impl) _impl; -    }; - -    /*! -     * A phony-zero-copy interface for transport objects that -     * provides a zero-copy interface on top of copying transport. -     * This interface implements the get managed send buffer, -     * the base class must implement the private send method. -     */ -    class UHD_API phony_zero_copy_send_if : public virtual zero_copy_if{ -    public: -        /*! -         * Create a phony zero copy send interface. -         * \param max_buff_size max buffer size in bytes -         */ -        phony_zero_copy_send_if(size_t max_buff_size); - -        //! destructor -        virtual ~phony_zero_copy_send_if(void); - -        /*! -         * Get a new send buffer from this transport object. -         * \return a managed buffer, or null sptr on timeout/error -         */ -        managed_send_buffer::sptr get_send_buff(void); - -    private: -        /*! -         * Perform a private copying send. -         * \param buff the buffer to read data from -         * \return the number of bytes read from buff, 0 for timeout, negative for error -         */ -        virtual ssize_t send(const boost::asio::const_buffer &buff) = 0; - -        UHD_PIMPL_DECL(impl) _impl; -    }; -  }} //namespace  #endif /* INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP */  | 
