diff options
Diffstat (limited to 'host/include/uhd/transport/bounded_buffer.ipp')
-rw-r--r-- | host/include/uhd/transport/bounded_buffer.ipp | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp index e106e229e..edc7faa06 100644 --- a/host/include/uhd/transport/bounded_buffer.ipp +++ b/host/include/uhd/transport/bounded_buffer.ipp @@ -19,17 +19,28 @@ #define INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP #include <boost/bind.hpp> +#include <boost/function.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*/ + static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout){ + return boost::posix_time::microseconds(long(timeout*1e6)); + } + + static UHD_INLINE double from_time_dur(const boost::posix_time::time_duration &time_dur){ + return 1e-6*time_dur.total_microseconds(); + } + template <typename elem_type> class bounded_buffer_impl : public bounded_buffer<elem_type>{ public: bounded_buffer_impl(size_t capacity) : _buffer(capacity){ - /* NOP */ + _not_full_fcn = boost::bind(&bounded_buffer_impl<elem_type>::not_full, this); + _not_empty_fcn = boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this); } UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){ @@ -51,15 +62,17 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/ UHD_INLINE void push_with_wait(const elem_type &elem){ boost::unique_lock<boost::mutex> lock(_mutex); - _full_cond.wait(lock, boost::bind(&bounded_buffer_impl<elem_type>::not_full, this)); + _full_cond.wait(lock, _not_full_fcn); _buffer.push_front(elem); lock.unlock(); _empty_cond.notify_one(); } - bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time){ + UHD_INLINE 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, to_time_dur(timeout), _not_full_fcn + )) return false; _buffer.push_front(elem); lock.unlock(); _empty_cond.notify_one(); @@ -68,16 +81,18 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/ UHD_INLINE void pop_with_wait(elem_type &elem){ boost::unique_lock<boost::mutex> lock(_mutex); - _empty_cond.wait(lock, boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this)); - elem = _buffer.back(); _buffer.pop_back(); + _empty_cond.wait(lock, _not_empty_fcn); + elem = this->pop_back(); lock.unlock(); _full_cond.notify_one(); } - bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time){ + UHD_INLINE 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; - elem = _buffer.back(); _buffer.pop_back(); + if (not _empty_cond.timed_wait( + lock, to_time_dur(timeout), _not_empty_fcn + )) return false; + elem = this->pop_back(); lock.unlock(); _full_cond.notify_one(); return true; @@ -85,7 +100,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/ UHD_INLINE void clear(void){ boost::unique_lock<boost::mutex> lock(_mutex); - while (not_empty()) _buffer.pop_back(); + while (not_empty()) this->pop_back(); lock.unlock(); _full_cond.notify_one(); } @@ -97,6 +112,21 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/ bool not_full(void) const{return not _buffer.full();} bool not_empty(void) const{return not _buffer.empty();} + + boost::function<bool(void)> _not_full_fcn, _not_empty_fcn; + + /*! + * Three part operation to pop an element: + * 1) assign elem to the back element + * 2) assign the back element to empty + * 3) pop the back to move the counter + */ + UHD_INLINE elem_type pop_back(void){ + elem_type elem = _buffer.back(); + _buffer.back() = elem_type(); + _buffer.pop_back(); + return elem; + } }; }}} //namespace |