Embedded Template Library 1.0
buffer_descriptors.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2020 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_BUFFER_DESCRIPTORS_INCLUDED
32#define ETL_BUFFER_DESCRIPTORS_INCLUDED
33
34#include "platform.h"
35#include "array.h"
36#include "delegate.h"
37#include "type_traits.h"
38#include "static_assert.h"
39#include "cyclic_value.h"
40#include "algorithm.h"
41
42#include <cstring>
43
44#if ETL_USING_CPP11
45
46namespace etl
47{
48 //***************************************************************************
50 //***************************************************************************
51 template <typename TBuffer, size_t BUFFER_SIZE_, size_t N_BUFFERS_, typename TFlag = bool>
52 class buffer_descriptors
53 {
54 private:
55
56 struct descriptor_item;
57
58 public:
59
60 typedef TBuffer value_type;
61 typedef value_type* pointer;
62 typedef size_t size_type;
63 typedef TFlag flag_type;
64
65 static ETL_CONSTANT size_type N_BUFFERS = N_BUFFERS_;
66 static ETL_CONSTANT size_type BUFFER_SIZE = BUFFER_SIZE_;
67
68 //*********************************
70 //*********************************
71 class descriptor
72 {
73 public:
74
75 friend class buffer_descriptors;
76
77 static ETL_CONSTANT size_type MAX_SIZE = buffer_descriptors::BUFFER_SIZE;
78
79 //*********************************
80 descriptor()
81 : pdesc_item(ETL_NULLPTR)
82 {
83 }
84
85 //*********************************
86 descriptor(const descriptor& other)
87 : pdesc_item(other.pdesc_item)
88 {
89 }
90
91 //*********************************
92 descriptor& operator =(const descriptor& other)
93 {
94 pdesc_item = other.pdesc_item;
95 return *this;
96 }
97
98 //*********************************
99 pointer data() const
100 {
101 assert(pdesc_item != ETL_NULLPTR);
102 return pdesc_item->pbuffer;
103 }
104
105 //*********************************
106 ETL_NODISCARD
107 ETL_CONSTEXPR size_type max_size() const
108 {
109 return BUFFER_SIZE;
110 }
111
112 //*********************************
113 ETL_NODISCARD
114 bool is_allocated() const
115 {
116 return bool(pdesc_item->in_use);
117 }
118
119 //*********************************
120 ETL_NODISCARD
121 bool is_released() const
122 {
123 return bool(!pdesc_item->in_use);
124 }
125
126 //*********************************
127 ETL_NODISCARD
128 bool is_valid() const
129 {
130 return pdesc_item != ETL_NULLPTR;
131 }
132
133 //*********************************
134 void release()
135 {
136 pdesc_item->in_use = false;
137 }
138
139 private:
140
141 //*********************************
142 descriptor(descriptor_item* pdesc_item_)
143 : pdesc_item(pdesc_item_)
144 {
145 }
146
147 //*********************************
148 void allocate()
149 {
150 pdesc_item->in_use = true;;
151 }
152
154 descriptor_item* pdesc_item;
155 };
156
157 //*********************************
159 //*********************************
160 class notification
161 {
162 public:
163
164 //*********************************
165 notification()
166 : desc()
167 , count(0U)
168 {
169 }
170
171 //*********************************
172 notification(descriptor desc_, size_t count_)
173 : desc(desc_)
174 , count(count_)
175 {
176 }
177
178 //*********************************
179 ETL_NODISCARD
180 descriptor get_descriptor() const
181 {
182 return desc;
183 }
184
185 //*********************************
186 ETL_NODISCARD
187 size_t get_count() const
188 {
189 return count;
190 }
191
192 private:
193
194 descriptor desc;
195 size_t count;
196 };
197
198 // The type of the callback function.
199 typedef etl::delegate<void(notification)> callback_type;
200
201 //*********************************
202 buffer_descriptors(TBuffer* pbuffers_, callback_type callback_ = callback_type())
203 : callback(callback_)
204 {
205 for (size_t i = 0UL; i < N_BUFFERS; ++i)
206 {
207 descriptor_items[i].pbuffer = pbuffers_ + (i * BUFFER_SIZE);
208 descriptor_items[i].in_use = false;
209 }
210 }
211
212 //*********************************
213 void set_callback(const callback_type& callback_)
214 {
215 callback = callback_;
216 }
217
218 //*********************************
219 void clear()
220 {
221 for (size_t i = 0UL; i < N_BUFFERS; ++i)
222 {
223 descriptor_items[i].in_use = false;
224 }
225
226 next.to_first();
227 }
228
229 //*********************************
230 ETL_NODISCARD
231 bool is_valid() const
232 {
233 return callback.is_valid();
234 }
235
236 //*********************************
237 void notify(notification n)
238 {
239 // Do we have a valid callback?
240 if (callback.is_valid())
241 {
242 callback(n);
243 }
244 }
245
246 //*********************************
247 ETL_NODISCARD
248 descriptor allocate()
249 {
250 descriptor desc(&descriptor_items[next]);
251
252 if (desc.is_released())
253 {
254 ++next;
255
256 desc.allocate();
257
258 return desc;
259 }
260 else
261 {
262 return descriptor();
263 }
264 }
265
266 //*********************************
267 ETL_NODISCARD
268 descriptor allocate(value_type fill_)
269 {
270 descriptor desc = allocate();
271
272 if (desc.is_valid())
273 {
274 etl::fill_n(desc.data(), BUFFER_SIZE, fill_);
275 }
276
277 return desc;
278 }
279
280 private:
281
282 //*********************************
283 struct descriptor_item
284 {
285 pointer pbuffer;
286 volatile flag_type in_use;
287 };
288
289 callback_type callback;
291 etl::cyclic_value<uint_least8_t, 0U, N_BUFFERS - 1> next;
292 };
293
294 template <typename TBuffer, size_t BUFFER_SIZE_, size_t N_BUFFERS_, typename TFlag>
295 ETL_CONSTANT typename buffer_descriptors<TBuffer, BUFFER_SIZE_, N_BUFFERS_, TFlag>::size_type buffer_descriptors<TBuffer, BUFFER_SIZE_, N_BUFFERS_, TFlag>::N_BUFFERS;
296
297 template <typename TBuffer, size_t BUFFER_SIZE_, size_t N_BUFFERS_, typename TFlag>
298 ETL_CONSTANT typename buffer_descriptors<TBuffer, BUFFER_SIZE_, N_BUFFERS_, TFlag>::size_type buffer_descriptors<TBuffer, BUFFER_SIZE_, N_BUFFERS_, TFlag>::BUFFER_SIZE;
299
300 template <typename TBuffer, size_t BUFFER_SIZE_, size_t N_BUFFERS_, typename TFlag>
301 ETL_CONSTANT typename buffer_descriptors<TBuffer, BUFFER_SIZE_, N_BUFFERS_, TFlag>::size_type buffer_descriptors<TBuffer, BUFFER_SIZE_, N_BUFFERS_, TFlag>::descriptor::MAX_SIZE;
302}
303#endif
304#endif
Provides a value that cycles between two limits.
Definition: cyclic_value.h:53
Declaration.
Definition: delegate_cpp03.h:175
Definition: array.h:88
bitset_ext
Definition: absolute.h:38
size_t max_size() const
Returns the maximum number of items in the variant_pool.
Definition: variant_pool_generator.h:281