| USRP Hardware Driver and Device Manual Version: 4.10.0.0 UHD and USRP Manual |

Loading...
Searching...
No Matches
bounded_buffer.ipp
Go to the documentation of this file.
1//
2// Copyright 2010-2013 Ettus Research LLC
3// Copyright 2018 Ettus Research, a National Instruments Company
4//
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
7
8#pragma once
9
10#include <uhd/config.hpp>
11#include <uhd/utils/noncopyable.hpp>
12#include <boost/circular_buffer.hpp>
13#include <boost/thread/condition.hpp>
14#include <boost/utility.hpp>
15#include <functional>
16#include <mutex>
17
18 namespace uhd { namespace transport {
19
20 template <typename elem_type>
21 class bounded_buffer_detail : uhd::noncopyable
22{
23 public:
24 bounded_buffer_detail(size_t capacity) : _buffer(capacity)
25 {
26 _not_full_fcn = std::bind(&bounded_buffer_detail<elem_type>::not_full, this);
27 _not_empty_fcn = std::bind(&bounded_buffer_detail<elem_type>::not_empty, this);
28 }
29
30 UHD_INLINE bool push_with_haste(const elem_type& elem)
31 {
32 std::unique_lock<std::mutex> lock(_mutex);
33 if (_buffer.full()) {
34 return false;
35 }
36 _buffer.push_front(elem);
37 _empty_cond.notify_one();
38 return true;
39 }
40
41 UHD_INLINE bool push_with_pop_on_full(const elem_type& elem)
42 {
43 std::lock_guard<std::mutex> lock(_mutex);
44 if (_buffer.full()) {
45 _buffer.pop_back();
46 _buffer.push_front(elem);
47 _empty_cond.notify_one();
48 return false;
49 } else {
50 _buffer.push_front(elem);
51 _empty_cond.notify_one();
52 return true;
53 }
54 }
55
56 UHD_INLINE void push_with_wait(const elem_type& elem)
57 {
58 std::unique_lock<std::mutex> lock(_mutex);
59 if (_buffer.full()) {
60 _full_cond.wait(lock, _not_full_fcn);
61 }
62 _buffer.push_front(elem);
63 _empty_cond.notify_one();
64 }
65
66 UHD_INLINE bool push_with_timed_wait(const elem_type& elem, double timeout)
67 {
68 std::unique_lock<std::mutex> lock(_mutex);
69 if (_buffer.full()) {
70 if (not _full_cond.timed_wait(lock, to_time_dur(timeout), _not_full_fcn)) {
71 return false;
72 }
73 }
74 _buffer.push_front(elem);
75 _empty_cond.notify_one();
76 return true;
77 }
78
79 UHD_INLINE bool pop_with_haste(elem_type& elem)
80 {
81 std::unique_lock<std::mutex> lock(_mutex);
82 if (_buffer.empty()) {
83 return false;
84 }
85 this->pop_back(elem);
86 _full_cond.notify_one();
87 return true;
88 }
89
90 UHD_INLINE void pop_with_wait(elem_type& elem)
91 {
92 std::unique_lock<std::mutex> lock(_mutex);
93 if (_buffer.empty()) {
94 _empty_cond.wait(lock, _not_empty_fcn);
95 }
96 this->pop_back(elem);
97 _full_cond.notify_one();
98 }
99
100 UHD_INLINE bool pop_with_timed_wait(elem_type& elem, double timeout)
101 {
102 std::unique_lock<std::mutex> lock(_mutex);
103 if (_buffer.empty()) {
104 if (not _empty_cond.timed_wait(lock, to_time_dur(timeout), _not_empty_fcn)) {
105 return false;
106 }
107 }
108 this->pop_back(elem);
109 _full_cond.notify_one();
110 return true;
111 }
112
113 UHD_INLINE std::vector<elem_type> pop_all()
114 {
115 std::unique_lock<std::mutex> lock(_mutex);
116 std::vector<elem_type> retval(_buffer.size());
117 for (size_t i = 0; i < retval.size(); ++i) {
118 // pop_back will assign the back element to empty and pop it
119 this->pop_back(retval[i]);
120 }
121 _full_cond.notify_all();
122 return retval;
123 }
124
125 private:
126 std::mutex _mutex;
127 boost::condition _empty_cond, _full_cond;
128 boost::circular_buffer<elem_type> _buffer;
129
130 bool not_full(void) const
131 {
132 return not _buffer.full();
133 }
134 bool not_empty(void) const
135 {
136 return not _buffer.empty();
137 }
138
139 std::function<bool(void)> _not_full_fcn, _not_empty_fcn;
140
147 UHD_INLINE void pop_back(elem_type& elem)
148 {
149 elem = _buffer.back();
150 _buffer.back() = elem_type();
151 _buffer.pop_back();
152 }
153
154 static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout)
155 {
156 return boost::posix_time::microseconds(long(timeout * 1e6));
157 }
158};
159}} // 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