Loading...
Searching...
No Matches
bounded_buffer.ipp
Go to the documentation of this file.
//
// Copyright 2010-2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#pragma once
#include <uhd/config.hpp>
#include <uhd/utils/noncopyable.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/thread/condition.hpp>
#include <boost/utility.hpp>
#include <functional>
#include <mutex>
namespace uhd { namespace transport {
template <typename elem_type>
class bounded_buffer_detail : uhd::noncopyable
{
public:
bounded_buffer_detail(size_t capacity) : _buffer(capacity)
{
_not_full_fcn = std::bind(&bounded_buffer_detail<elem_type>::not_full, this);
_not_empty_fcn = std::bind(&bounded_buffer_detail<elem_type>::not_empty, this);
}
UHD_INLINE bool push_with_haste(const elem_type& elem)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_buffer.full()) {
return false;
}
_buffer.push_front(elem);
_empty_cond.notify_one();
return true;
}
UHD_INLINE bool push_with_pop_on_full(const elem_type& elem)
{
std::lock_guard<std::mutex> lock(_mutex);
if (_buffer.full()) {
_buffer.pop_back();
_buffer.push_front(elem);
_empty_cond.notify_one();
return false;
} else {
_buffer.push_front(elem);
_empty_cond.notify_one();
return true;
}
}
UHD_INLINE void push_with_wait(const elem_type& elem)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_buffer.full()) {
_full_cond.wait(lock, _not_full_fcn);
}
_buffer.push_front(elem);
_empty_cond.notify_one();
}
UHD_INLINE bool push_with_timed_wait(const elem_type& elem, double timeout)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_buffer.full()) {
if (not _full_cond.timed_wait(lock, to_time_dur(timeout), _not_full_fcn)) {
return false;
}
}
_buffer.push_front(elem);
_empty_cond.notify_one();
return true;
}
UHD_INLINE bool pop_with_haste(elem_type& elem)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_buffer.empty()) {
return false;
}
this->pop_back(elem);
_full_cond.notify_one();
return true;
}
UHD_INLINE void pop_with_wait(elem_type& elem)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_buffer.empty()) {
_empty_cond.wait(lock, _not_empty_fcn);
}
this->pop_back(elem);
_full_cond.notify_one();
}
UHD_INLINE bool pop_with_timed_wait(elem_type& elem, double timeout)
{
std::unique_lock<std::mutex> lock(_mutex);
if (_buffer.empty()) {
if (not _empty_cond.timed_wait(lock, to_time_dur(timeout), _not_empty_fcn)) {
return false;
}
}
this->pop_back(elem);
_full_cond.notify_one();
return true;
}
UHD_INLINE std::vector<elem_type> pop_all()
{
std::unique_lock<std::mutex> lock(_mutex);
std::vector<elem_type> retval(_buffer.size());
for (size_t i = 0; i < retval.size(); ++i) {
// pop_back will assign the back element to empty and pop it
this->pop_back(retval[i]);
}
_full_cond.notify_all();
return retval;
}
private:
std::mutex _mutex;
boost::condition _empty_cond, _full_cond;
boost::circular_buffer<elem_type> _buffer;
bool not_full(void) const
{
return not _buffer.full();
}
bool not_empty(void) const
{
return not _buffer.empty();
}
std::function<bool(void)> _not_full_fcn, _not_empty_fcn;
UHD_INLINE void pop_back(elem_type& elem)
{
elem = _buffer.back();
_buffer.back() = elem_type();
_buffer.pop_back();
}
static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout)
{
return boost::posix_time::microseconds(long(timeout * 1e6));
}
};
}} // namespace uhd::transport
uhd::transport::bounded_buffer_detail::pop_with_haste
UHD_INLINE bool pop_with_haste(elem_type &elem)
Definition bounded_buffer.ipp:79
uhd::transport::bounded_buffer_detail::pop_with_timed_wait
UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout)
Definition bounded_buffer.ipp:100
uhd::transport::bounded_buffer_detail::pop_with_wait
UHD_INLINE void pop_with_wait(elem_type &elem)
Definition bounded_buffer.ipp:90
uhd::transport::bounded_buffer_detail::bounded_buffer_detail
bounded_buffer_detail(size_t capacity)
Definition bounded_buffer.ipp:24
uhd::transport::bounded_buffer_detail::push_with_timed_wait
UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout)
Definition bounded_buffer.ipp:66
uhd::transport::bounded_buffer_detail::push_with_wait
UHD_INLINE void push_with_wait(const elem_type &elem)
Definition bounded_buffer.ipp:56
uhd::transport::bounded_buffer_detail::push_with_haste
UHD_INLINE bool push_with_haste(const elem_type &elem)
Definition bounded_buffer.ipp:30
uhd::transport::bounded_buffer_detail::push_with_pop_on_full
UHD_INLINE bool push_with_pop_on_full(const elem_type &elem)
Definition bounded_buffer.ipp:41
uhd::transport::bounded_buffer_detail::pop_all
UHD_INLINE std::vector< elem_type > pop_all()
Definition bounded_buffer.ipp:113
UHD_INLINE
#define UHD_INLINE
Definition config.h:65
config.hpp
uhd::transport
Definition adapter_id.hpp:11
uhd
Definition build_info.hpp:12
uhd::noncopyable
boost::noncopyable noncopyable
Definition noncopyable.hpp:45
noncopyable.hpp