µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os::memory::lifo_inclusive< N > Class Template Reference

Memory resource implementing the LIFO allocation policies, using an internal arena. More...

#include <cmsis-plus/memory/first-fit-top.h>

+ Inheritance diagram for os::memory::lifo_inclusive< N >:

Public Member Functions

Constructors & Destructor
 lifo_inclusive (void)
 Construct a memory resource object instance.
 
 lifo_inclusive (const char *name)
 Construct a named memory resource object instance.
 
virtual ~lifo_inclusive ()
 Destruct the memory resource object instance.
 
Public Member Functions
void * allocate (std::size_t bytes, std::size_t alignment=max_align)
 Allocate a memory block.
 
void deallocate (void *addr, std::size_t bytes, std::size_t alignment=max_align) noexcept
 Deallocate the previously allocated memory block.
 
bool is_equal (memory_resource const &other) const noexcept
 Compare for equality with another memory_resource.
 
void reset (void) noexcept
 Reset the memory manager to the initial state.
 
bool coalesce (void) noexcept
 Coalesce free blocks.
 
std::size_t max_size (void) const noexcept
 Get the largest value that can be passed to allocate().
 
out_of_memory_handler_t out_of_memory_handler (out_of_memory_handler_t handler)
 Set the out of memory handler.
 
out_of_memory_handler_t out_of_memory_handler (void)
 Get the out of memory handler.
 
std::size_t total_bytes (void)
 Get the total size of managed memory.
 
std::size_t allocated_bytes (void)
 Get the current size of all allocated chunks.
 
std::size_t max_allocated_bytes (void)
 Get the maximum allocated size.
 
std::size_t free_bytes (void)
 Get the current size of all free chunks.
 
std::size_t allocated_chunks (void)
 Get the current number of allocated chunks.
 
std::size_t free_chunks (void)
 Get the current number of free chunks.
 
std::size_t allocations (void)
 Get the number of allocations.
 
std::size_t deallocations (void)
 Get the number of deallocations.
 
void trace_print_statistics (void)
 Print a long message with usage statistics.
 
Public Member Functions
const char * name (void) const
 Get object name.
 

Static Public Attributes

static const std::size_t bytes = N
 Local constant based on template definition.
 
static constexpr std::size_t max_align = alignof (std::max_align_t)
 The largest alignment for the platform. Also default when supplied alignment is not supported.
 

Protected Member Functions

Private Member Functions
virtual void * do_allocate (std::size_t bytes, std::size_t alignment) override
 Implementation of the memory allocator.
 
Private Member Functions
void internal_construct_ (void *addr, std::size_t bytes)
 Internal function to construct the memory resource.
 
void internal_reset_ (void) noexcept
 Internal function to reset the memory resource.
 
void * internal_align_ (chunk_t *chunk, std::size_t bytes, std::size_t alignment)
 Internal function to align a chunk.
 
virtual void do_deallocate (void *addr, std::size_t bytes, std::size_t alignment) noexcept override
 Implementation of the memory deallocator.
 
virtual std::size_t do_max_size (void) const noexcept override
 Implementation of the function to get max size.
 
virtual void do_reset (void) noexcept override
 Implementation of the function to reset the memory manager.
 
Private Member Functions
virtual bool do_is_equal (memory_resource const &other) const noexcept
 Implementation of the equality comparator.
 
virtual bool do_coalesce (void) noexcept
 Implementation of the function to coalesce free blocks.
 
void internal_increase_allocated_statistics (std::size_t bytes) noexcept
 Update statistics after allocation.
 
void internal_decrease_allocated_statistics (std::size_t bytes) noexcept
 Update statistics after deallocation.
 

Detailed Description

template<std::size_t N>
class os::memory::lifo_inclusive< N >

This class template is a convenience class that includes an array of chars to be used as the allocation arena.

The common use case it to define statically allocated memory managers.

Definition at line 170 of file lifo.h.

Constructor & Destructor Documentation

◆ lifo_inclusive() [1/2]

template<std::size_t N>
os::memory::lifo_inclusive< N >::lifo_inclusive ( void  )
inline
Parameters
None.

Definition at line 382 of file lifo.h.

382 : lifo_inclusive (nullptr)
383 {
384 }
lifo_inclusive(void)
Construct a memory resource object instance.
Definition lifo.h:382

◆ lifo_inclusive() [2/2]

template<std::size_t N>
os::memory::lifo_inclusive< N >::lifo_inclusive ( const char *  name)
inline
Parameters
[in]namePointer to name.

Definition at line 387 of file lifo.h.

387 : lifo{ name }
388 {
389 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
390
391 internal_construct_ (&arena_[0], bytes);
392 }
void internal_construct_(void *addr, std::size_t bytes)
Internal function to construct the memory resource.
static const std::size_t bytes
Local constant based on template definition.
Definition lifo.h:176
lifo()=default
Default constructor. Construct a memory resource object instance.
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

References os::memory::lifo_inclusive< N >::bytes, os::memory::first_fit_top::internal_construct_(), and os::trace::printf().

◆ ~lifo_inclusive()

template<std::size_t N>
os::memory::lifo_inclusive< N >::~lifo_inclusive
virtual

Definition at line 395 of file lifo.h.

396 {
397 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
398 }

References os::trace::printf().

Member Function Documentation

◆ allocate()

void * os::rtos::memory::memory_resource::allocate ( std::size_t  bytes,
std::size_t  alignment = max_align 
)
inlineinherited
Parameters
bytesNumber of bytes to allocate.
alignmentAlignment constraint (power of 2).
Returns
Pointer to newly allocated block, or nullptr.

Allocate storage with a size of at least bytes bytes. The returned storage is aligned to the specified alignment if such alignment is supported, and to alignof(std::max_align_t) otherwise.

If the storage of the requested size and alignment cannot be obtained:

  • if the out of memory handler is not set, return nullptr;
  • if the out of memory handler is set, call it and retry.

Equivalent to return do_allocate(bytes, alignment);.

Exceptions
The code itself throws nothing, but if the out of memory handler is set, it may throw a bad_alloc() exception.
See also
do_allocate();

Definition at line 1290 of file os-memory.h.

1291 {
1292 ++allocations_;
1293 return do_allocate (bytes, alignment);
1294 }
virtual void * do_allocate(std::size_t bytes, std::size_t alignment)=0
Implementation of the memory allocator.

References os::rtos::memory::memory_resource::do_allocate().

Referenced by os::estd::pmr::polymorphic_allocator< T >::allocate(), calloc(), malloc(), operator new(), and realloc().

◆ allocated_bytes()

std::size_t os::rtos::memory::memory_resource::allocated_bytes ( void  )
inlineinherited
Parameters
None.
Returns
Number of bytes.

Definition at line 1402 of file os-memory.h.

1403 {
1404 return allocated_bytes_;
1405 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ allocated_chunks()

std::size_t os::rtos::memory::memory_resource::allocated_chunks ( void  )
inlineinherited
Parameters
None.
Returns
Number of chunks.

Definition at line 1420 of file os-memory.h.

1421 {
1422 return allocated_chunks_;
1423 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ allocations()

std::size_t os::rtos::memory::memory_resource::allocations ( void  )
inlineinherited
Parameters
None.
Returns
Number of allocations.

Definition at line 1432 of file os-memory.h.

1433 {
1434 return allocations_;
1435 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ coalesce()

bool os::rtos::memory::memory_resource::coalesce ( void  )
inlinenoexceptinherited
Parameters
None.
Return values
trueif the operation freed more memory.
falseif the operation was ineffective.

In case the memory manager does not coalesce during deallocation, traverse the list of free blocks and coalesce.

Return true if the operation was successful and at least one larger block resulted.

See also
do_coalesce();

Definition at line 1365 of file os-memory.h.

1366 {
1367 return do_coalesce ();
1368 }
virtual bool do_coalesce(void) noexcept
Implementation of the function to coalesce free blocks.

◆ deallocate()

void os::rtos::memory::memory_resource::deallocate ( void *  addr,
std::size_t  bytes,
std::size_t  alignment = max_align 
)
inlinenoexceptinherited
Parameters
addrAddress of the block to free.
bytesNumber of bytes to deallocate (may be 0 if unknown).
alignmentAlignment constraint (power of 2).
Returns
Nothing.

Deallocate the storage pointed to by addr. The address shall have been returned by a prior call to allocate() on a memory_resource that compares equal to *this, and the storage it points to shall not yet have been deallocated.

Equivalent to return do_deallocate(p, bytes, alignment);.

Exceptions
Throws nothing.
See also
do_deallocate();

Definition at line 1312 of file os-memory.h.

1314 {
1315 ++deallocations_;
1316 do_deallocate (addr, bytes, alignment);
1317 }
virtual void do_deallocate(void *addr, std::size_t bytes, std::size_t alignment) noexcept=0
Implementation of the memory deallocator.

Referenced by os::estd::pmr::polymorphic_allocator< T >::deallocate(), free(), and realloc().

◆ deallocations()

std::size_t os::rtos::memory::memory_resource::deallocations ( void  )
inlineinherited
Parameters
None.
Returns
Number of deallocations

Definition at line 1438 of file os-memory.h.

1439 {
1440 return deallocations_;
1441 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ do_allocate()

void * os::memory::lifo::do_allocate ( std::size_t  bytes,
std::size_t  alignment 
)
overrideprotectedvirtualinherited
Parameters
[in]bytesNumber of bytes to allocate.
[in]alignmentAlignment constraint (power of 2).
Returns
Pointer to newly allocated block, or nullptr.

The allocator is deterministic and fast, it always uses the top part of the first block (memory is allocated top-down). If this block is not large enough, the allocation fails; the free list is never traversed, since this is no longer deterministic.

Deallocating in reverse order restores the first block to its original glory. A slight reorder of deallocations is allowed, but memory is not reused until the previous adjacent block is freed, and so on recursively, increasing back the size of the first block.

With the given top-down allocation policy, recent block have always lower addresses.

Similarly, a block is reused only after all more recently allocated blocks are freed.

Exceptions
Throws nothing itself, but the out of memory handler may throw bad_alloc().

Reimplemented from os::memory::first_fit_top.

Definition at line 68 of file lifo.cpp.

69 {
70 std::size_t block_padding = calc_block_padding (alignment);
71 std::size_t alloc_size = rtos::memory::align_size (bytes, chunk_align);
72 alloc_size += block_padding;
73 alloc_size += chunk_offset;
74
75 std::size_t block_minchunk = calc_block_minchunk (block_padding);
76 alloc_size = os::rtos::memory::max (alloc_size, block_minchunk);
77
78 chunk_t* chunk = nullptr;
79
80 while (true)
81 {
82 // Allocate only from the first block and only if it is
83 // the really first in the arena; this prevents fragmentation.
84 if (free_list_ == reinterpret_cast<chunk_t*> (arena_addr_))
85 {
86 chunk = free_list_;
87
88 int rem = static_cast<int> (chunk->size - alloc_size);
89 if (rem >= 0)
90 {
91 if ((static_cast<std::size_t> (rem)) >= block_minchunk)
92 {
93 // If the chunk is larger than needed
94 // (at least one more chunk is available);
95 // break it into two chunks and return the top one.
96
97 // Shrink bottom chunk to remaining size.
98 chunk->size = static_cast<std::size_t> (rem);
99
100#pragma GCC diagnostic push
101#pragma GCC diagnostic ignored "-Wcast-align"
102#if defined(__clang__)
103#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
104#endif
105 // Compute where top chunk starts.
106 chunk = reinterpret_cast<chunk_t*> (
107 reinterpret_cast<char*> (chunk) + rem);
108#pragma GCC diagnostic pop
109 chunk->size = alloc_size;
110
111 // Splitting one chunk creates one more chunk.
112 ++free_chunks_;
113 }
114 else
115 {
116 // Found a chunk that is exactly the size or slightly
117 // larger than the requested size; return this chunk.
118
119 // Always at the list head.
120 // The next chunk becomes the first list element.
121 free_list_ = chunk->next;
122
123 // If this was the last chunk, the free list is empty.
124 }
125 }
126 }
127
128 if (chunk != nullptr)
129 {
130 break;
131 }
132
133 if (out_of_memory_handler_ == nullptr)
134 {
135#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
136 trace::printf ("lifo::%s(%u,%u)=0 @%p %s\n", __func__, bytes,
137 alignment, this, this->name ());
138#endif
139
140 return nullptr;
141 }
142
143#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
144 trace::printf ("lifo::%s(%u,%u) @%p %s out of memory\n", __func__,
145 bytes, alignment, this, this->name ());
146#endif
147 out_of_memory_handler_ ();
148
149 // If the handler returned, assume it freed some memory
150 // and try again to allocate.
151 }
152
153 void* aligned_payload = internal_align_ (chunk, bytes, alignment);
154
155#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
156 trace::printf ("lifo::%s(%u,%u)=%p,%u @%p %s\n", __func__, bytes,
157 alignment, aligned_payload, alloc_size, this, name ());
158#endif
159
160 return aligned_payload;
161 }
void * internal_align_(chunk_t *chunk, std::size_t bytes, std::size_t alignment)
Internal function to align a chunk.
constexpr std::size_t align_size(std::size_t size, std::size_t align) noexcept
Helper function to align size values.
Definition os-memory.h:85
constexpr std::size_t max(std::size_t a, std::size_t b)
Definition os-memory.h:73

References os::rtos::memory::align_size(), os::memory::first_fit_top::internal_align_(), os::rtos::memory::max(), os::rtos::internal::object_named::name(), and os::trace::printf().

◆ do_coalesce()

bool os::rtos::memory::memory_resource::do_coalesce ( void  )
protectedvirtualnoexceptinherited
Parameters
None.
Return values
trueif the operation resulted in larger blocks.
falseif the operation was ineffective.

The default implementation of this virtual function returns false, meaning the operation was ineffective.

Override this function to perform the action.

Standard compliance
Extension to standard.

Definition at line 468 of file os-memory.cpp.

469 {
470 return false;
471 }

◆ do_deallocate()

void os::memory::first_fit_top::do_deallocate ( void *  addr,
std::size_t  bytes,
std::size_t  alignment 
)
overrideprotectedvirtualnoexceptinherited
Parameters
[in]addrAddress of a previously allocated block to free.
[in]bytesNumber of bytes to deallocate (may be 0 if unknown).
[in]alignmentAlignment constraint (power of 2).
Returns
Nothing.

Deallocation is not guaranteed to be deterministic, but if done in strict reverse allocation order, it becomes deterministic, otherwise a traversal of the free list is required, the older the block, the more nodes to traverse (the free list is kept in ascending addresses order).

If the block is already in the free list, issue a trace message, but otherwise ignore the condition.

Exceptions
Throws nothing.

Implements os::rtos::memory::memory_resource.

Definition at line 231 of file first-fit-top.cpp.

233 {
234#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
235 trace::printf ("first_fit_top::%s(%p,%u,%u) @%p %s\n", __func__, addr,
236 bytes, alignment, this, name ());
237#endif
238
239 // The address must be inside the arena; no exceptions.
240#pragma GCC diagnostic push
241#if defined(__clang__)
242#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
243#endif
244 if ((addr < arena_addr_)
245 || (addr > (static_cast<char*> (arena_addr_) + total_bytes_)))
246 {
247 assert (false);
248 return;
249 }
250#pragma GCC diagnostic pop
251
252#pragma GCC diagnostic push
253#pragma GCC diagnostic ignored "-Wcast-align"
254#if defined(__clang__)
255#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
256#endif
257 // Compute the chunk address from the user address.
258 chunk_t* chunk = reinterpret_cast<chunk_t*> (static_cast<char*> (addr)
259 - chunk_offset);
260
261 // If the block was aligned, the offset appears as size; adjust back.
262 if (static_cast<std::ptrdiff_t> (chunk->size) < 0)
263 {
264 chunk = reinterpret_cast<chunk_t*> (
265 reinterpret_cast<char*> (chunk)
266 + static_cast<std::ptrdiff_t> (chunk->size));
267 }
268#pragma GCC diagnostic pop
269
270 if (bytes)
271 {
272 // If size is known, validate.
273 // (when called from free(), the size is not known).
274 if (bytes + chunk_offset > chunk->size)
275 {
276 assert (false);
277 return;
278 }
279 }
280
281 // Update statistics.
282 // What is subtracted from allocated is added to free.
284
285 // If the free list is empty, create it with the current chunk, alone.
286 if (free_list_ == nullptr)
287 {
288 // Mark the end of the list with a null pointer.
289 chunk->next = nullptr;
290
291 // The chunk becomes the first list element.
292 free_list_ = chunk;
293 assert (free_chunks_ == 1);
294
295 return;
296 }
297
298 // The free list exists; is the chunk before the list head?
299 if (chunk < free_list_)
300 {
301 // Is the chunk *right* before the list head?
302#pragma GCC diagnostic push
303#if defined(__clang__)
304#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
305#endif
306 if (reinterpret_cast<char*> (chunk) + chunk->size
307 == reinterpret_cast<char*> (free_list_))
308 {
309 // Coalesce chunk to the list head.
310 chunk->size += free_list_->size;
311 chunk->next = free_list_->next; // May be nullptr
312
313 // Coalescing means one less chunk.
314 --free_chunks_;
315 }
316 else
317 {
318 // Insert before the list head.
319 chunk->next = free_list_;
320 }
321#pragma GCC diagnostic pop
322 // The chunk becomes the new list head.
323 free_list_ = chunk;
324
325 return;
326 }
327
328 // Walk the free list to find the place to insert,
329 // (the list must be ordered by addresses).
330 // Warning: not deterministic!
331
332 chunk_t* next_chunk = free_list_;
333 chunk_t* prev_chunk;
334 do
335 {
336 prev_chunk = next_chunk;
337 next_chunk = next_chunk->next;
338 }
339 while (next_chunk != nullptr && next_chunk <= chunk);
340
341 // Now prev_chunk <= chunk and either next_chunk == nullptr or
342 // next_chunk > chunk.
343 // Try to merge with chunks immediately before/after it.
344
345#pragma GCC diagnostic push
346#if defined(__clang__)
347#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
348#endif
349 if (reinterpret_cast<char*> (prev_chunk) + prev_chunk->size
350 == reinterpret_cast<char*> (chunk))
351 {
352 // Chunk to be freed is adjacent to a free chunk before it.
353 prev_chunk->size += chunk->size;
354
355 // Coalescing means one less chunk.
356 --free_chunks_;
357
358 // If the merged chunk is also adjacent to the chunk after it,
359 // merge again. Does not match if next_chunk == nullptr.
360 if (reinterpret_cast<char*> (prev_chunk) + prev_chunk->size
361 == reinterpret_cast<char*> (next_chunk))
362 {
363 prev_chunk->size += next_chunk->size;
364 prev_chunk->next = next_chunk->next;
365
366 // Coalescing means one less chunk.
367 --free_chunks_;
368 }
369 }
370 else if (reinterpret_cast<char*> (prev_chunk) + prev_chunk->size
371 > reinterpret_cast<char*> (chunk))
372 {
373 // Already freed.
374
375 // Revert statistics.
376 // What is subtracted from free is added to allocated.
377 allocated_bytes_ += chunk->size;
378 free_bytes_ -= chunk->size;
379 ++allocated_chunks_;
380 --free_chunks_;
381
382 trace::printf ("first_fit_top::%s(%p,%u,%u) @%p %s already freed\n",
383 __func__, addr, bytes, alignment, this, name ());
384
385 return;
386 }
387 // Does not match if next_chunk == nullptr.
388 else if (reinterpret_cast<char*> (chunk) + chunk->size
389 == reinterpret_cast<char*> (next_chunk))
390 {
391 // The chunk to be freed is adjacent to a free chunk after it.
392 chunk->size += next_chunk->size;
393 chunk->next = next_chunk->next; // May be nullptr.
394 prev_chunk->next = chunk;
395
396 // Coalescing means one less chunk.
397 --free_chunks_;
398 }
399 else
400 {
401 // Not adjacent to any chunk. Just insert it.
402 // The result is a new fragment. Not great...
403 chunk->next = next_chunk; // May be nullptr.
404 prev_chunk->next = chunk;
405 }
406 }
void internal_decrease_allocated_statistics(std::size_t bytes) noexcept
Update statistics after deallocation.

References os::trace::printf().

◆ do_is_equal()

bool os::rtos::memory::memory_resource::do_is_equal ( memory_resource const &  other) const
protectedvirtualnoexceptinherited
Parameters
otherReference to another memory_resource.
Return values
trueThe memory_resource objects are equal.
falseThe memory_resource objects are not equal.

Compares *this for equality with other. Two memory_resources compare equal if and only if memory allocated from one memory_resource can be deallocated from the other and vice versa.

The most-derived type of other may not match the most derived type of *this. A derived class implementation therefore must typically check whether the most derived types of *this and other match using dynamic_cast, and immediately return false if the cast fails.

Exceptions
Throws nothing.

Definition at line 419 of file os-memory.cpp.

421 {
422 return &other == this;
423 }

◆ do_max_size()

std::size_t os::memory::first_fit_top::do_max_size ( void  ) const
overrideprotectedvirtualnoexceptinherited
Parameters
None.
Returns
Integer with size in bytes, or 0 if unknown.

Reimplemented from os::rtos::memory::memory_resource.

Definition at line 410 of file first-fit-top.cpp.

411 {
412 return total_bytes_;
413 }

◆ do_reset()

void os::memory::first_fit_top::do_reset ( void  )
overrideprotectedvirtualnoexceptinherited
Parameters
None.
Returns
Nothing.

Reimplemented from os::rtos::memory::memory_resource.

Definition at line 82 of file first-fit-top.cpp.

83 {
84#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
85 trace::printf ("first_fit_top::%s() @%p %s\n", __func__, this, name ());
86#endif
87
89 }
void internal_reset_(void) noexcept
Internal function to reset the memory resource.

References os::trace::printf().

◆ free_bytes()

std::size_t os::rtos::memory::memory_resource::free_bytes ( void  )
inlineinherited
Parameters
None.
Returns
Number of bytes.

Definition at line 1414 of file os-memory.h.

1415 {
1416 return free_bytes_;
1417 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ free_chunks()

std::size_t os::rtos::memory::memory_resource::free_chunks ( void  )
inlineinherited
Parameters
None.
Returns
Number of chunks.

Definition at line 1426 of file os-memory.h.

1427 {
1428 return free_chunks_;
1429 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ internal_align_()

void * os::memory::first_fit_top::internal_align_ ( chunk_t *  chunk,
std::size_t  bytes,
std::size_t  alignment 
)
protectedinherited
Parameters
[in]chunkPointer to chunk.
[in]bytesBytes to allocate.
[in]alignmentPower of two.
Returns
Pointer to aligned payload.

Definition at line 416 of file first-fit-top.cpp.

418 {
419 // Update statistics.
420 // The value subtracted from free is added to allocated.
422
423 // Compute pointer to payload area.
424#pragma GCC diagnostic push
425#if defined(__clang__)
426#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
427#endif
428 char* payload = reinterpret_cast<char*> (chunk) + chunk_offset;
429#pragma GCC diagnostic pop
430
431 // Align it to user provided alignment.
432 void* aligned_payload = payload;
433 std::size_t aligned_size = chunk->size - chunk_offset;
434
435 void* res;
436 res = std::align (alignment, bytes, aligned_payload, aligned_size);
437 if (res == nullptr)
438 {
439 assert (res != nullptr);
440 }
441
442 // Compute the possible alignment offset.
443 std::ptrdiff_t offset = static_cast<char*> (aligned_payload) - payload;
444 if (offset)
445 {
446 // If non-zero, store it in the gap left by alignment in the
447 // chunk header.
448
449#pragma GCC diagnostic push
450#pragma GCC diagnostic ignored "-Wcast-align"
451#if defined(__clang__)
452#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
453#endif
454 chunk_t* adj_chunk = reinterpret_cast<chunk_t*> (
455 static_cast<char*> (aligned_payload) - chunk_offset);
456 adj_chunk->size = static_cast<std::size_t> (-offset);
457#pragma GCC diagnostic pop
458 }
459
460 assert ((reinterpret_cast<uintptr_t> (aligned_payload) & (alignment - 1))
461 == 0);
462
463 return aligned_payload;
464 }
void internal_increase_allocated_statistics(std::size_t bytes) noexcept
Update statistics after allocation.

References os::rtos::memory::memory_resource::internal_increase_allocated_statistics().

Referenced by os::memory::first_fit_top::do_allocate(), and os::memory::lifo::do_allocate().

◆ internal_construct_()

void os::memory::first_fit_top::internal_construct_ ( void *  addr,
std::size_t  bytes 
)
protectedinherited
Parameters
[in]addrBegin of allocator arena.
[in]bytesSize of allocator arena, in bytes.
Returns
Nothing.

Definition at line 40 of file first-fit-top.cpp.

41 {
42 assert (bytes > chunk_minsize);
43
44 arena_addr_ = addr;
45 total_bytes_ = bytes;
46
47 // Align address for first chunk.
48 void* res;
49 // Possibly adjust the last two parameters.
50 res = std::align (chunk_align, chunk_minsize, arena_addr_, total_bytes_);
51 // std::align() will fail if it cannot fit the min chunk.
52 if (res == nullptr)
53 {
54 assert (res != nullptr);
55 }
56 assert ((total_bytes_ % chunk_align) == 0);
57
59 }

References os::memory::first_fit_top::internal_reset_().

Referenced by os::memory::first_fit_top::first_fit_top(), os::memory::first_fit_top_allocated< A >::first_fit_top_allocated(), os::memory::first_fit_top_inclusive< N >::first_fit_top_inclusive(), os::memory::lifo_allocated< A >::lifo_allocated(), and os::memory::lifo_inclusive< N >::lifo_inclusive().

◆ internal_decrease_allocated_statistics()

void os::rtos::memory::memory_resource::internal_decrease_allocated_statistics ( std::size_t  bytes)
protectednoexceptinherited
Parameters
[in]bytesNumber of deallocated bytes.
Returns
Nothing.

Definition at line 490 of file os-memory.cpp.

492 {
493 // Update statistics.
494 // What is subtracted from allocated is added to free.
495 allocated_bytes_ -= bytes;
496 free_bytes_ += bytes;
497 --allocated_chunks_;
498 ++free_chunks_;
499 }

◆ internal_increase_allocated_statistics()

void os::rtos::memory::memory_resource::internal_increase_allocated_statistics ( std::size_t  bytes)
protectednoexceptinherited
Parameters
[in]bytesNumber of allocated bytes.
Returns
Nothing.

Definition at line 474 of file os-memory.cpp.

476 {
477 // Update statistics.
478 // What is subtracted from free is added to allocated.
479 allocated_bytes_ += bytes;
480 if (allocated_bytes_ > max_allocated_bytes_)
481 {
482 max_allocated_bytes_ = allocated_bytes_;
483 }
484 free_bytes_ -= bytes;
485 ++allocated_chunks_;
486 --free_chunks_;
487 }

Referenced by os::memory::block_pool::do_allocate(), and os::memory::first_fit_top::internal_align_().

◆ internal_reset_()

void os::memory::first_fit_top::internal_reset_ ( void  )
protectednoexceptinherited
Parameters
None.

Definition at line 62 of file first-fit-top.cpp.

63 {
64 // Fill it with the first chunk.
65 chunk_t* chunk = reinterpret_cast<chunk_t*> (arena_addr_);
66 // Entire arena is a big free chunk.
67 chunk->size = total_bytes_;
68 // Mark the end of the list with a null pointer.
69 chunk->next = nullptr;
70
71 allocated_bytes_ = 0;
72 max_allocated_bytes_ = 0;
73 free_bytes_ = total_bytes_;
74 allocated_chunks_ = 0;
75 free_chunks_ = 1;
76
77 // Remember first chunk as list head.
78 free_list_ = chunk;
79 }

Referenced by os::memory::first_fit_top::internal_construct_().

◆ is_equal()

bool os::rtos::memory::memory_resource::is_equal ( memory_resource const &  other) const
inlinenoexceptinherited
Parameters
otherReference to another memory_resource.
Return values
trueThe memory_resource objects are equal.
falseThe memory_resource objects are not equal.

Compare *this for equality with other. Two memory_resources compare equal if and only if memory allocated from one memory_resource can be deallocated from the other and vice versa.

Exceptions
Throws nothing.
See also
do_is_equal();

Definition at line 1331 of file os-memory.h.

1332 {
1333 return do_is_equal (other);
1334 }
virtual bool do_is_equal(memory_resource const &other) const noexcept
Implementation of the equality comparator.

◆ max_allocated_bytes()

std::size_t os::rtos::memory::memory_resource::max_allocated_bytes ( void  )
inlineinherited
Parameters
None.
Returns
Number of bytes.

Definition at line 1408 of file os-memory.h.

1409 {
1410 return max_allocated_bytes_;
1411 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ max_size()

std::size_t os::rtos::memory::memory_resource::max_size ( void  ) const
inlinenoexceptinherited
Parameters
None.
Returns
Number of bytes or 0 if unknown.
See also
do_max_size();

Definition at line 1340 of file os-memory.h.

1341 {
1342 return do_max_size ();
1343 }
virtual std::size_t do_max_size(void) const noexcept
Implementation of the function to get max size.

◆ name()

const char * os::rtos::internal::object_named::name ( void  ) const
inlineinherited
Parameters
None.
Returns
A null terminated string.

All objects return a non-null string; anonymous objects return "-".

Note
Can be invoked from Interrupt Service Routines.

Definition at line 753 of file os-decls.h.

754 {
755 return name_;
756 }

Referenced by os::memory::lifo::lifo(), os::memory::malloc_memory_resource::malloc_memory_resource(), os::rtos::message_queue_typed< T, Allocator >::message_queue_typed(), os::memory::block_pool::~block_pool(), os::rtos::event_flags::~event_flags(), os::memory::first_fit_top::~first_fit_top(), os::memory::lifo::~lifo(), os::memory::malloc_memory_resource::~malloc_memory_resource(), os::rtos::memory_pool::~memory_pool(), os::rtos::message_queue::~message_queue(), os::rtos::mutex::~mutex(), os::rtos::semaphore::~semaphore(), os::rtos::thread::~thread(), os::rtos::timer::~timer(), os::rtos::memory_pool::alloc(), os::rtos::thread::cancel(), os::rtos::event_flags::clear(), os::rtos::mutex::consistent(), os::rtos::thread::detach(), os::memory::new_delete_memory_resource::do_allocate(), os::memory::block_pool::do_allocate(), os::memory::first_fit_top::do_allocate(), os::memory::lifo::do_allocate(), os::memory::malloc_memory_resource::do_allocate(), os::rtos::thread::flags_raise(), os::rtos::memory_pool::free(), os::rtos::event_flags::get(), os::rtos::thread::interrupt(), os::rtos::thread::join(), os::rtos::thread::kill(), os::rtos::internal::terminated_threads_list::link(), os::rtos::mutex::lock(), os::rtos::memory::memory_resource::out_of_memory_handler(), os::rtos::semaphore::post(), os::rtos::mutex::prio_ceiling(), os::rtos::mutex::prio_ceiling(), os::rtos::thread::priority(), os::rtos::thread::priority_inherited(), os::rtos::event_flags::raise(), os::rtos::message_queue::receive(), os::rtos::memory_pool::reset(), os::rtos::message_queue::reset(), os::rtos::mutex::reset(), os::rtos::semaphore::reset(), os::rtos::thread::resume(), os::rtos::message_queue::send(), os::rtos::clock::sleep_for(), os::rtos::timer::start(), os::rtos::timer::stop(), os::rtos::memory_pool::timed_alloc(), os::rtos::mutex::timed_lock(), os::rtos::message_queue::timed_receive(), os::rtos::message_queue::timed_send(), os::rtos::semaphore::timed_wait(), os::rtos::event_flags::timed_wait(), os::rtos::memory::memory_resource::trace_print_statistics(), os::rtos::memory_pool::try_alloc(), os::rtos::mutex::try_lock(), os::rtos::message_queue::try_receive(), os::rtos::message_queue::try_send(), os::rtos::event_flags::try_wait(), os::rtos::semaphore::try_wait(), os::rtos::internal::ready_threads_list::unlink_head(), os::rtos::mutex::unlock(), os::rtos::event_flags::wait(), os::rtos::semaphore::wait(), and os::rtos::event_flags::waiting().

◆ out_of_memory_handler() [1/2]

out_of_memory_handler_t os::rtos::memory::memory_resource::out_of_memory_handler ( out_of_memory_handler_t  handler)
inlineinherited
Parameters
handlerPointer to new handler.
Returns
Pointer to old handler.
Standard compliance
Extension to standard.

Definition at line 1375 of file os-memory.h.

1376 {
1377 trace::printf ("%s(%p) @%p %s\n", __func__, handler, this, name ());
1378
1379 out_of_memory_handler_t tmp = out_of_memory_handler_;
1380 out_of_memory_handler_ = handler;
1381
1382 return tmp;
1383 }
void(*)(void) out_of_memory_handler_t
Type of out of memory handler.
Definition os-memory.h:141

References os::rtos::internal::object_named::name(), and os::trace::printf().

Referenced by os_startup_initialize_free_store().

◆ out_of_memory_handler() [2/2]

out_of_memory_handler_t os::rtos::memory::memory_resource::out_of_memory_handler ( void  )
inlineinherited
Parameters
None.
Returns
Pointer to existing handler.
Standard compliance
Extension to standard.

Definition at line 1390 of file os-memory.h.

1391 {
1392 return out_of_memory_handler_;
1393 }

◆ reset()

void os::rtos::memory::memory_resource::reset ( void  )
inlinenoexceptinherited
Parameters
None.
Returns
Nothing.
See also
do_reset();

Definition at line 1349 of file os-memory.h.

1350 {
1351 do_reset ();
1352 }
virtual void do_reset(void) noexcept
Implementation of the function to reset the memory manager.

◆ total_bytes()

std::size_t os::rtos::memory::memory_resource::total_bytes ( void  )
inlineinherited
Returns
Number of bytes.

Definition at line 1396 of file os-memory.h.

1397 {
1398 return total_bytes_;
1399 }

Referenced by os::rtos::memory::memory_resource::trace_print_statistics().

◆ trace_print_statistics()

void os::rtos::memory::memory_resource::trace_print_statistics ( void  )
inlineinherited
Parameters
None.
Returns
Nothing.

Definition at line 1444 of file os-memory.h.

1445 {
1446#if defined(TRACE)
1447 trace::printf ("Memory '%s' @%p: \n"
1448 "\ttotal: %u bytes, \n"
1449 "\tallocated: %u bytes in %u chunk(s), \n"
1450 "\tfree: %u bytes in %u chunk(s), \n"
1451 "\tmax: %u bytes, \n"
1452 "\tcalls: %u allocs, %u deallocs\n",
1453 name (), this, total_bytes (), allocated_bytes (),
1456 deallocations ());
1457#endif /* defined(TRACE) */
1458 }
std::size_t allocated_chunks(void)
Get the current number of allocated chunks.
Definition os-memory.h:1420
std::size_t allocated_bytes(void)
Get the current size of all allocated chunks.
Definition os-memory.h:1402
std::size_t max_allocated_bytes(void)
Get the maximum allocated size.
Definition os-memory.h:1408
std::size_t allocations(void)
Get the number of allocations.
Definition os-memory.h:1432
std::size_t total_bytes(void)
Get the total size of managed memory.
Definition os-memory.h:1396
std::size_t deallocations(void)
Get the number of deallocations.
Definition os-memory.h:1438
std::size_t free_chunks(void)
Get the current number of free chunks.
Definition os-memory.h:1426
std::size_t free_bytes(void)
Get the current size of all free chunks.
Definition os-memory.h:1414

References os::rtos::memory::memory_resource::allocated_bytes(), os::rtos::memory::memory_resource::allocated_chunks(), os::rtos::memory::memory_resource::allocations(), os::rtos::memory::memory_resource::deallocations(), os::rtos::memory::memory_resource::free_bytes(), os::rtos::memory::memory_resource::free_chunks(), os::rtos::memory::memory_resource::max_allocated_bytes(), os::rtos::internal::object_named::name(), os::trace::printf(), and os::rtos::memory::memory_resource::total_bytes().

Referenced by os_terminate_goodbye().

Member Data Documentation

◆ bytes

template<std::size_t N>
const std::size_t os::memory::lifo_inclusive< N >::bytes = N
static

Definition at line 176 of file lifo.h.

Referenced by os::memory::lifo_inclusive< N >::lifo_inclusive().

◆ max_align

constexpr std::size_t os::rtos::memory::memory_resource::max_align = alignof (std::max_align_t)
staticconstexprinherited

Definition at line 166 of file os-memory.h.


The documentation for this class was generated from the following file: