µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
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-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#ifndef CMSIS_PLUS_MEMORY_LIFO_H_
14#define CMSIS_PLUS_MEMORY_LIFO_H_
15
16// ----------------------------------------------------------------------------
17
18#if defined(__cplusplus)
19
20// ----------------------------------------------------------------------------
21
23
24// ----------------------------------------------------------------------------
25
26#pragma GCC diagnostic push
27#if defined(__clang__)
28#pragma clang diagnostic ignored "-Wc++98-compat"
29#endif
30
31// ----------------------------------------------------------------------------
32
33namespace os
34{
35 namespace memory
36 {
37
38 // ========================================================================
39
73 {
74 public:
75
86 lifo (void* addr, std::size_t bytes);
87
94 lifo (const char* name, void* addr, std::size_t bytes);
95
96 protected:
97
102 lifo () = default;
103
108 lifo (const char* name);
109
110 public:
111
116 // The rule of five.
117 lifo (const lifo&) = delete;
118 lifo (lifo&&) = delete;
119 lifo&
120 operator= (const lifo&) = delete;
121 lifo&
122 operator= (lifo&&) = delete;
123
131 virtual
132 ~lifo () override;
133
138 protected:
139
151 virtual void*
152 do_allocate (std::size_t bytes, std::size_t alignment) override;
153
158 };
159
160 // ========================================================================
161
174 template<std::size_t N>
175 class lifo_inclusive : public lifo
176 {
177 public:
178
182 static const std::size_t bytes = N;
183
194 lifo_inclusive (void);
195
200 lifo_inclusive (const char* name);
201
202 public:
203
208 // The rule of five.
209 lifo_inclusive (const lifo_inclusive&) = delete;
210 lifo_inclusive (lifo_inclusive&&) = delete;
212 operator= (const lifo_inclusive&) = delete;
214 operator= (lifo_inclusive&&) = delete;
215
223 virtual
225
230 protected:
231
239 char arena_[bytes];
240
245 };
246
247 // ========================================================================
248
261 template<typename A = os::rtos::memory::allocator<char>>
262 class lifo_allocated : public lifo
263 {
264 public:
265
269 using value_type = char;
270
274 using allocator_type = A;
275
279 using allocator_traits = std::allocator_traits<A>;
280
281 // It is recommended to have the same type, but at least the types
282 // should have the same size.
283 static_assert(sizeof(value_type) == sizeof(typename allocator_traits::value_type),
284 "The allocator must be parametrised with a type of same size.");
285
297 lifo_allocated (std::size_t bytes, const allocator_type& allocator =
298 allocator_type ());
299
307 lifo_allocated (const char* name, std::size_t bytes,
308 const allocator_type& allocator = allocator_type ());
309
310 public:
311
316 // The rule of five.
317 lifo_allocated (const lifo_allocated&) = delete;
318 lifo_allocated (lifo_allocated&&) = delete;
320 operator= (const lifo_allocated&) = delete;
322 operator= (lifo_allocated&&) = delete;
323
331 virtual
333
338 protected:
339
352 allocator_type* allocator_ = nullptr;
353
358 };
359
360 // -------------------------------------------------------------------------
361 } /* namespace memory */
362} /* namespace os */
363
364// ===== Inline & template implementations ====================================
365
366namespace os
367{
368 namespace memory
369 {
370
371 // ========================================================================
372
373 inline
374 lifo::lifo (void* addr, std::size_t bytes) :
376 { nullptr, addr, bytes }
377 {
378 trace::printf ("%s(%p,%u) @%p %s\n", __func__, addr, bytes, this,
379 this->name ());
380 }
381
382 inline
383 lifo::lifo (const char* name, void* addr, std::size_t bytes) :
385 { name, addr, bytes }
386 {
387 trace::printf ("%s(%p,%u) @%p %s\n", __func__, addr, bytes, this,
388 this->name ());
389 }
390
391 // ========================================================================
392
393 template<std::size_t N>
394 inline
396 lifo_inclusive (nullptr)
397 {
398 }
399
400 template<std::size_t N>
401 inline
403 lifo
404 { name }
405 {
406 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
407
408 internal_construct_ (&arena_[0], bytes);
409 }
410
411 template<std::size_t N>
413 {
414 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
415 }
416
417 // ========================================================================
418
419 template<typename A>
420 inline
422 const allocator_type& allocator) :
423 lifo_allocated (nullptr, bytes, allocator)
424 {
425 }
426
427 template<typename A>
428 lifo_allocated<A>::lifo_allocated (const char* name, std::size_t bytes,
429 const allocator_type& allocator) :
430 lifo
431 { name }
432 {
433 trace::printf ("%s(%u) @%p %s\n", __func__, bytes, this, this->name ());
434
435 // Remember the allocator, it'll be used by the destructor.
436 allocator_ =
437 static_cast<allocator_type*> (&const_cast<allocator_type&> (allocator));
438
439 void* addr = allocator_->allocate (bytes);
440 if (addr == nullptr)
441 {
443 }
444
445 internal_construct_ (addr, bytes);
446 }
447
448 template<typename A>
450 {
451 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
452
453 // Skip in case a derived class did the deallocation.
454 if (allocator_ != nullptr)
455 {
456 allocator_->deallocate (
457 static_cast<typename allocator_traits::pointer> (arena_addr_),
458 total_bytes_);
459
460 // Prevent another deallocation.
461 allocator_ = nullptr;
462 }
463 }
464
465 // --------------------------------------------------------------------------
466
467 } /* namespace memory */
468} /* namespace os */
469
470#pragma GCC diagnostic pop
471
472// ----------------------------------------------------------------------------
473
474#endif /* __cplusplus */
475
476// ----------------------------------------------------------------------------
477
478#endif /* CMSIS_PLUS_MEMORY_LIFO_H_ */
Memory resource implementing the first fit, top-down allocation policies, using an existing arena.
Memory resource implementing the LIFO allocation policies, using a dynamically allocated arena.
Definition lifo.h:263
char value_type
Standard allocator type definition.
Definition lifo.h:269
std::allocator_traits< A > allocator_traits
Standard allocator traits definition.
Definition lifo.h:279
lifo_allocated(std::size_t bytes, const allocator_type &allocator=allocator_type())
Construct a memory resource object instance.
Definition lifo.h:421
virtual ~lifo_allocated()
Destruct the memory resource object instance.
Definition lifo.h:449
A allocator_type
Standard allocator type definition.
Definition lifo.h:274
Memory resource implementing the LIFO allocation policies, using an internal arena.
Definition lifo.h:176
static const std::size_t bytes
Local constant based on template definition.
Definition lifo.h:182
lifo_inclusive(void)
Construct a memory resource object instance.
Definition lifo.h:395
virtual ~lifo_inclusive()
Destruct the memory resource object instance.
Definition lifo.h:412
Memory resource implementing the LIFO allocation/deallocation policies, using an existing arena.
Definition lifo.h:73
lifo(const char *name)
Construct a named memory resource object instance.
lifo()=default
Default constructor. Construct a memory resource object instance.
virtual ~lifo() override
Destruct the memory resource object instance.
Definition lifo.cpp:35
virtual void * do_allocate(std::size_t bytes, std::size_t alignment) override
Implementation of the memory allocator.
Definition lifo.cpp:69
const char * name(void) const
Get object name.
Definition os-decls.h:759
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
void __throw_bad_alloc(void)
System namespace.