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