USRP Hardware Driver and Device Manual Version: 4.11.0.0-0-unknown
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>
12#include <condition_variable>
13#include <boost/circular_buffer.hpp>
14#include <functional>
15#include <mutex>
16
17namespace uhd { namespace transport {
18
19template <typename elem_type>
21{
22public:
23 bounded_buffer_detail(size_t capacity) : _buffer(capacity)
24 {
25 _not_full_fcn = std::bind(&bounded_buffer_detail<elem_type>::not_full, this);
26 _not_empty_fcn = std::bind(&bounded_buffer_detail<elem_type>::not_empty, this);
27 }
28
29 UHD_INLINE bool push_with_haste(const elem_type& elem)
30 {
31 std::unique_lock<std::mutex> lock(_mutex);
32 if (_buffer.full()) {
33 return false;
34 }
35 _buffer.push_front(elem);
36 _empty_cond.notify_one();
37 return true;
38 }
39
40 UHD_INLINE bool push_with_pop_on_full(const elem_type& elem)
41 {
42 std::lock_guard<std::mutex> lock(_mutex);
43 if (_buffer.full()) {
44 _buffer.pop_back();
45 _buffer.push_front(elem);
46 _empty_cond.notify_one();
47 return false;
48 } else {
49 _buffer.push_front(elem);
50 _empty_cond.notify_one();
51 return true;
52 }
53 }
54
55 UHD_INLINE void push_with_wait(const elem_type& elem)
56 {
57 std::unique_lock<std::mutex> lock(_mutex);
58 if (_buffer.full()) {
59 _full_cond.wait(lock, _not_full_fcn);
60 }
61 _buffer.push_front(elem);
62 _empty_cond.notify_one();
63 }
64
65 UHD_INLINE bool push_with_timed_wait(const elem_type& elem, double timeout)
66 {
67 std::unique_lock<std::mutex> lock(_mutex);
68 if (_buffer.full()) {
69 if (not _full_cond.wait_for(lock, to_time_dur(timeout), _not_full_fcn)) {
70 return false;
71 }
72 }
73 _buffer.push_front(elem);
74 _empty_cond.notify_one();
75 return true;
76 }
77
78 UHD_INLINE bool pop_with_haste(elem_type& elem)
79 {
80 std::unique_lock<std::mutex> lock(_mutex);
81 if (_buffer.empty()) {
82 return false;
83 }
84 this->pop_back(elem);
85 _full_cond.notify_one();
86 return true;
87 }
88
89 UHD_INLINE void pop_with_wait(elem_type& elem)
90 {
91 std::unique_lock<std::mutex> lock(_mutex);
92 if (_buffer.empty()) {
93 _empty_cond.wait(lock, _not_empty_fcn);
94 }
95 this->pop_back(elem);
96 _full_cond.notify_one();
97 }
98
99 UHD_INLINE bool pop_with_timed_wait(elem_type& elem, double timeout)
100 {
101 std::unique_lock<std::mutex> lock(_mutex);
102 if (_buffer.empty()) {
103 if (not _empty_cond.wait_for(lock, to_time_dur(timeout), _not_empty_fcn)) {
104 return false;
105 }
106 }
107 this->pop_back(elem);
108 _full_cond.notify_one();
109 return true;
110 }
111
112 UHD_INLINE std::vector<elem_type> pop_all()
113 {
114 std::unique_lock<std::mutex> lock(_mutex);
115 std::vector<elem_type> retval(_buffer.size());
116 for (size_t i = 0; i < retval.size(); ++i) {
117 // pop_back will assign the back element to empty and pop it
118 this->pop_back(retval[i]);
119 }
120 _full_cond.notify_all();
121 return retval;
122 }
123
124private:
125 std::mutex _mutex;
126 std::condition_variable _empty_cond, _full_cond;
127 boost::circular_buffer<elem_type> _buffer;
128
129 bool not_full(void) const
130 {
131 return not _buffer.full();
132 }
133 bool not_empty(void) const
134 {
135 return not _buffer.empty();
136 }
137
138 std::function<bool(void)> _not_full_fcn, _not_empty_fcn;
139
146 UHD_INLINE void pop_back(elem_type& elem)
147 {
148 elem = _buffer.back();
149 _buffer.back() = elem_type();
150 _buffer.pop_back();
151 }
152
153 static inline std::chrono::microseconds to_time_dur(double timeout)
154 {
155 return std::chrono::microseconds(long(timeout * 1e6));
156 }
157};
158}} // namespace uhd::transport
UHD_INLINE bool pop_with_haste(elem_type &elem)
Definition bounded_buffer.ipp:78
UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout)
Definition bounded_buffer.ipp:99
UHD_INLINE void pop_with_wait(elem_type &elem)
Definition bounded_buffer.ipp:89
bounded_buffer_detail(size_t capacity)
Definition bounded_buffer.ipp:23
UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout)
Definition bounded_buffer.ipp:65
UHD_INLINE void push_with_wait(const elem_type &elem)
Definition bounded_buffer.ipp:55
UHD_INLINE bool push_with_haste(const elem_type &elem)
Definition bounded_buffer.ipp:29
UHD_INLINE bool push_with_pop_on_full(const elem_type &elem)
Definition bounded_buffer.ipp:40
UHD_INLINE std::vector< elem_type > pop_all()
Definition bounded_buffer.ipp:112
#define UHD_INLINE
Definition config.h:65
Definition adapter_id.hpp:11
Definition build_info.hpp:12
boost::noncopyable noncopyable
Definition noncopyable.hpp:45