µOS++ IIIe Reference  v6.3.15
“Perfekt ist nicht gut genug”
The third edition of µOS++, a POSIX inspired open source system, written in C++.
lifo.h
Go to the documentation of this file.
1 /*
2  * This file is part of the µOS++ distribution.
3  * (https://github.com/micro-os-plus)
4  * Copyright (c) 2016 Liviu Ionescu.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom
12  * the Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #ifndef CMSIS_PLUS_MEMORY_LIFO_H_
29 #define CMSIS_PLUS_MEMORY_LIFO_H_
30 
31 // ----------------------------------------------------------------------------
32 
33 #if defined(__cplusplus)
34 
36 
37 // ----------------------------------------------------------------------------
38 
39 namespace os
40 {
41  namespace memory
42  {
43 
44  // ========================================================================
45 
79  {
80  public:
81 
92  lifo (void* addr, std::size_t bytes);
93 
100  lifo (const char* name, void* addr, std::size_t bytes);
101 
102  protected:
103 
108  lifo () = default;
109 
114  lifo (const char* name);
115 
116  public:
117 
122  // The rule of five.
123  lifo (const lifo&) = delete;
124  lifo (lifo&&) = delete;
125  lifo&
126  operator= (const lifo&) = delete;
127  lifo&
128  operator= (lifo&&) = delete;
129 
137  virtual
138  ~lifo () override;
139 
144  protected:
145 
157  virtual void*
158  do_allocate (std::size_t bytes, std::size_t alignment) override;
159 
164  };
165 
166  // ========================================================================
167 
180  template<std::size_t N>
181  class lifo_inclusive : public lifo
182  {
183  public:
184 
188  static const std::size_t bytes = N;
189 
200  lifo_inclusive (void);
201 
206  lifo_inclusive (const char* name);
207 
208  public:
209 
214  // The rule of five.
215  lifo_inclusive (const lifo_inclusive&) = delete;
216  lifo_inclusive (lifo_inclusive&&) = delete;
218  operator= (const lifo_inclusive&) = delete;
220  operator= (lifo_inclusive&&) = delete;
221 
229  virtual
230  ~lifo_inclusive ();
231 
236  protected:
237 
245  char arena_[bytes];
246 
251  };
252 
253  // ========================================================================
254 
267  template<typename A = os::rtos::memory::allocator<char>>
268  class lifo_allocated : public lifo
269  {
270  public:
271 
275  using value_type = char;
276 
280  using allocator_type = A;
281 
285  using allocator_traits = std::allocator_traits<A>;
286 
287  // It is recommended to have the same type, but at least the types
288  // should have the same size.
289  static_assert(sizeof(value_type) == sizeof(typename allocator_traits::value_type),
290  "The allocator must be parametrised with a type of same size.");
291 
303  lifo_allocated (std::size_t bytes, const allocator_type& allocator =
304  allocator_type ());
305 
313  lifo_allocated (const char* name, std::size_t bytes,
315 
316  public:
317 
322  // The rule of five.
323  lifo_allocated (const lifo_allocated&) = delete;
324  lifo_allocated (lifo_allocated&&) = delete;
326  operator= (const lifo_allocated&) = delete;
328  operator= (lifo_allocated&&) = delete;
329 
337  virtual
338  ~lifo_allocated ();
339 
344  protected:
345 
358  allocator_type* allocator_ = nullptr;
359 
364  };
365 
366  // -------------------------------------------------------------------------
367  } /* namespace memory */
368 } /* namespace os */
369 
370 // ===== Inline & template implementations ====================================
371 
372 namespace os
373 {
374  namespace memory
375  {
376 
377  // ========================================================================
378 
379  inline
380  lifo::lifo (void* addr, std::size_t bytes) :
382  { nullptr, addr, bytes }
383  {
384  trace::printf ("%s(%p,%u) @%p %s\n", __func__, addr, bytes, this,
385  this->name ());
386  }
387 
388  inline
389  lifo::lifo (const char* name, void* addr, std::size_t bytes) :
391  { name, addr, bytes }
392  {
393  trace::printf ("%s(%p,%u) @%p %s\n", __func__, addr, bytes, this,
394  this->name ());
395  }
396 
397  // ========================================================================
398 
399  template<std::size_t N>
400  inline
402  lifo_inclusive (nullptr)
403  {
404  ;
405  }
406 
407  template<std::size_t N>
408  inline
410  lifo
411  { name }
412  {
413  trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
414 
415  internal_construct_ (&arena_[0], bytes);
416  }
417 
418  template<std::size_t N>
420  {
421  trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
422  }
423 
424  // ========================================================================
425 
426  template<typename A>
427  inline
429  const allocator_type& allocator) :
430  lifo_allocated (nullptr, bytes, allocator)
431  {
432  ;
433  }
434 
435  template<typename A>
436  lifo_allocated<A>::lifo_allocated (const char* name, std::size_t bytes,
437  const allocator_type& allocator) :
438  lifo
439  { name }
440  {
441  trace::printf ("%s(%u) @%p %s\n", __func__, bytes, this, this->name ());
442 
443  // Remember the allocator, it'll be used by the destructor.
444  allocator_ =
445  static_cast<allocator_type*> (&const_cast<allocator_type&> (allocator));
446 
447  void* addr = allocator_->allocate (bytes);
448  if (addr == nullptr)
449  {
451  }
452 
453  internal_construct_ (addr, bytes);
454  }
455 
456  template<typename A>
458  {
459  trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
460 
461  // Skip in case a derived class did the deallocation.
462  if (allocator_ != nullptr)
463  {
464  allocator_->deallocate (
465  static_cast<typename allocator_traits::pointer> (arena_addr_),
466  total_bytes_);
467 
468  // Prevent another deallocation.
469  allocator_ = nullptr;
470  }
471  }
472 
473  // --------------------------------------------------------------------------
474 
475  } /* namespace memory */
476 } /* namespace os */
477 
478 // ----------------------------------------------------------------------------
479 
480 #endif /* __cplusplus */
481 
482 #endif /* CMSIS_PLUS_MEMORY_LIFO_H_ */
char value_type
Standard allocator type definition.
Definition: lifo.h:275
Memory resource implementing the LIFO allocation/deallocation policies, using an existing arena...
Definition: lifo.h:78
virtual ~lifo_allocated()
Destruct the memory resource object instance.
Definition: lifo.h:457
virtual void * do_allocate(std::size_t bytes, std::size_t alignment) override
Implementation of the memory allocator.
Definition: lifo.cpp:77
void internal_construct_(void *addr, std::size_t bytes)
Internal function to construct the memory resource.
lifo()=default
Default constructor. Construct a memory resource object instance.
System namespace.
Memory resource implementing the LIFO allocation policies, using an internal arena.
Definition: lifo.h:181
static const std::size_t bytes
Local constant based on template definition.
Definition: lifo.h:188
const char * name(void) const
Get object name.
Definition: os-decls.h:760
virtual ~lifo_inclusive()
Destruct the memory resource object instance.
Definition: lifo.h:419
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition: trace.cpp:74
virtual ~lifo() override
Destruct the memory resource object instance.
Definition: lifo.cpp:43
Memory resource implementing the LIFO allocation policies, using a dynamically allocated arena...
Definition: lifo.h:268
lifo_allocated(std::size_t bytes, const allocator_type &allocator=allocator_type())
Construct a memory resource object instance.
Definition: lifo.h:428
A allocator_type
Standard allocator type definition.
Definition: lifo.h:280
Memory resource implementing the first fit, top-down allocation policies, using an existing arena...
Definition: first-fit-top.h:59
lifo_inclusive(void)
Construct a memory resource object instance.
Definition: lifo.h:401
std::allocator_traits< A > allocator_traits
Standard allocator traits definition.
Definition: lifo.h:285
allocator_stateless_default_resource< T > allocator
Type of allocator used by the system objects. Must be stateless.
Definition: os-types.h:57
void __throw_bad_alloc(void)