µ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++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#ifndef CMSIS_PLUS_MEMORY_LIFO_H_
13#define CMSIS_PLUS_MEMORY_LIFO_H_
14
15// ----------------------------------------------------------------------------
16
17#if defined(__cplusplus)
18
19// ----------------------------------------------------------------------------
20
22
23// ----------------------------------------------------------------------------
24
25#pragma GCC diagnostic push
26#if defined(__clang__)
27#pragma clang diagnostic ignored "-Wc++98-compat"
28#endif
29
30// ----------------------------------------------------------------------------
31
32namespace os
33{
34 namespace memory
35 {
36
37 // ========================================================================
38
72 {
73 public:
84 lifo (void* addr, std::size_t bytes);
85
92 lifo (const char* name, void* addr, std::size_t bytes);
93
94 protected:
99 lifo () = default;
100
105 lifo (const char* name);
106
107 public:
112 // The rule of five.
113 lifo (const lifo&) = delete;
114 lifo (lifo&&) = delete;
115 lifo&
116 operator= (const lifo&)
117 = delete;
118 lifo&
119 operator= (lifo&&)
120 = delete;
121
129 virtual ~lifo () override;
130
135 protected:
147 virtual void*
148 do_allocate (std::size_t bytes, std::size_t alignment) override;
149
153 };
154
155 // ========================================================================
156
169 template <std::size_t N>
170 class lifo_inclusive : public lifo
171 {
172 public:
176 static const std::size_t bytes = N;
177
188 lifo_inclusive (void);
189
194 lifo_inclusive (const char* name);
195
196 public:
201 // The rule of five.
202 lifo_inclusive (const lifo_inclusive&) = delete;
203 lifo_inclusive (lifo_inclusive&&) = delete;
205 operator= (const lifo_inclusive&)
206 = delete;
208 operator= (lifo_inclusive&&)
209 = delete;
210
218 virtual ~lifo_inclusive ();
219
224 protected:
232 char arena_[bytes];
233
237 };
238
239 // ========================================================================
240
253 template <typename A = os::rtos::memory::allocator<char>>
254 class lifo_allocated : public lifo
255 {
256 public:
260 using value_type = char;
261
265 using allocator_type = A;
266
270 using allocator_traits = std::allocator_traits<A>;
271
272 // It is recommended to have the same type, but at least the types
273 // should have the same size.
274 static_assert (
275 sizeof (value_type)
276 == sizeof (typename allocator_traits::value_type),
277 "The allocator must be parametrised with a type of same size.");
278
290 lifo_allocated (std::size_t bytes,
291 const allocator_type& allocator = allocator_type ());
292
300 lifo_allocated (const char* name, std::size_t bytes,
301 const allocator_type& allocator = allocator_type ());
302
303 public:
308 // The rule of five.
309 lifo_allocated (const lifo_allocated&) = delete;
310 lifo_allocated (lifo_allocated&&) = delete;
312 operator= (const lifo_allocated&)
313 = delete;
315 operator= (lifo_allocated&&)
316 = delete;
317
325 virtual ~lifo_allocated ();
326
331 protected:
345 allocator_type* allocator_ = nullptr;
346
350 };
351
352 // -------------------------------------------------------------------------
353 } /* namespace memory */
354} /* namespace os */
355
356// ===== Inline & template implementations ====================================
357
358namespace os
359{
360 namespace memory
361 {
362
363 // ========================================================================
364
365 inline lifo::lifo (void* addr, std::size_t bytes)
366 : first_fit_top{ nullptr, addr, bytes }
367 {
368 trace::printf ("%s(%p,%u) @%p %s\n", __func__, addr, bytes, this,
369 this->name ());
370 }
371
372 inline lifo::lifo (const char* name, void* addr, std::size_t bytes)
373 : first_fit_top{ name, addr, bytes }
374 {
375 trace::printf ("%s(%p,%u) @%p %s\n", __func__, addr, bytes, this,
376 this->name ());
377 }
378
379 // ========================================================================
380
381 template <std::size_t N>
383 {
384 }
385
386 template <std::size_t N>
387 inline lifo_inclusive<N>::lifo_inclusive (const char* name) : lifo{ name }
388 {
389 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
390
391 internal_construct_ (&arena_[0], bytes);
392 }
393
394 template <std::size_t N>
396 {
397 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
398 }
399
400 // ========================================================================
401
402 template <typename A>
403 inline lifo_allocated<A>::lifo_allocated (std::size_t bytes,
404 const allocator_type& allocator)
405 : lifo_allocated (nullptr, bytes, allocator)
406 {
407 }
408
409 template <typename A>
410 lifo_allocated<A>::lifo_allocated (const char* name, std::size_t bytes,
411 const allocator_type& allocator)
412 : lifo{ name }
413 {
414 trace::printf ("%s(%u) @%p %s\n", __func__, bytes, this, this->name ());
415
416 // Remember the allocator, it'll be used by the destructor.
417 allocator_ = static_cast<allocator_type*> (
418 &const_cast<allocator_type&> (allocator));
419
420 void* addr = allocator_->allocate (bytes);
421 if (addr == nullptr)
422 {
424 }
425
426 internal_construct_ (addr, bytes);
427 }
428
429 template <typename A>
431 {
432 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
433
434 // Skip in case a derived class did the deallocation.
435 if (allocator_ != nullptr)
436 {
437 allocator_->deallocate (
438 static_cast<typename allocator_traits::pointer> (arena_addr_),
439 total_bytes_);
440
441 // Prevent another deallocation.
442 allocator_ = nullptr;
443 }
444 }
445
446 // ------------------------------------------------------------------------
447
448 } /* namespace memory */
449} /* namespace os */
450
451#pragma GCC diagnostic pop
452
453// ----------------------------------------------------------------------------
454
455#endif /* __cplusplus */
456
457// ----------------------------------------------------------------------------
458
459#endif /* CMSIS_PLUS_MEMORY_LIFO_H_ */
Memory resource implementing the first fit, top-down allocation policies, using an existing arena.
void internal_construct_(void *addr, std::size_t bytes)
Internal function to construct the memory resource.
Memory resource implementing the LIFO allocation policies, using a dynamically allocated arena.
Definition lifo.h:255
char value_type
Standard allocator type definition.
Definition lifo.h:260
std::allocator_traits< A > allocator_traits
Standard allocator traits definition.
Definition lifo.h:270
lifo_allocated(std::size_t bytes, const allocator_type &allocator=allocator_type())
Construct a memory resource object instance.
Definition lifo.h:403
virtual ~lifo_allocated()
Destruct the memory resource object instance.
Definition lifo.h:430
A allocator_type
Standard allocator type definition.
Definition lifo.h:265
Memory resource implementing the LIFO allocation policies, using an internal arena.
Definition lifo.h:171
static const std::size_t bytes
Local constant based on template definition.
Definition lifo.h:176
lifo_inclusive(void)
Construct a memory resource object instance.
Definition lifo.h:382
virtual ~lifo_inclusive()
Destruct the memory resource object instance.
Definition lifo.h:395
Memory resource implementing the LIFO allocation/deallocation policies, using an existing arena.
Definition lifo.h:72
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:34
virtual void * do_allocate(std::size_t bytes, std::size_t alignment) override
Implementation of the memory allocator.
Definition lifo.cpp:68
const char * name(void) const
Get object name.
Definition os-decls.h:753
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
void __throw_bad_alloc(void)
System namespace.