µ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.cpp
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/*
13 * [Partly inspired from the LLVM libcxx sources].
14 * Copyright (c) 2009-2013 by the contributors listed in
15 * 'LLVM libcxx Credits.txt'. See 'LLVM libcxx License.txt' for details.
16 *
17 * References are to ISO/IEC 14882:2011(E) Third edition (2011-09-01).
18 */
19
20#if defined(OS_USE_OS_APP_CONFIG_H)
21#include <cmsis-plus/os-app-config.h>
22#endif
23
24#include <cmsis-plus/rtos/os.h>
28
29// ----------------------------------------------------------------------------
30
31#if defined(__clang__)
32#pragma clang diagnostic ignored "-Wc++98-compat"
33#endif
34
35// ----------------------------------------------------------------------------
36
37using namespace os;
38
39// ----------------------------------------------------------------------------
40
41namespace os
42{
43 namespace rtos
44 {
45 namespace memory
46 {
47 // ======================================================================
48
53#pragma GCC diagnostic push
54#if defined(__clang__)
55#pragma clang diagnostic ignored "-Wexit-time-destructors"
56#pragma clang diagnostic ignored "-Wglobal-constructors"
57#endif
58
59 // The memory resources must not be destructed, since some
60 // static objects will want to deallocate memory they manage.
61
62 static std::aligned_storage<
64 alignof (os::memory::malloc_memory_resource)>::type malloc_res;
65
66 static std::aligned_storage<
68 alignof (os::memory::null_memory_resource)>::type null_res;
69
70 static std::aligned_storage<
73 new_delete_res;
74
75 void
77 {
78 static int guard; // Cleared during BSS init.
79 if (guard == 0)
80 {
81 guard = 1;
82
83 trace::printf ("rtos::memory::%s() \n", __func__);
84
85 new (&malloc_res) os::memory::malloc_memory_resource ("malloc");
86 new (&null_res) os::memory::null_memory_resource ();
87 new (&new_delete_res) os::memory::new_delete_memory_resource ();
88 }
89 }
90
91#pragma GCC diagnostic push
92#if defined(__clang__)
93#pragma clang diagnostic ignored "-Wreserved-identifier"
94#endif
95 // This guarantees that the memory resources are initialised
96 // before entering main().
97 static void __attribute__ ((constructor))
98 __constructor (void)
99 {
101 }
102#pragma GCC diagnostic pop
103
104 // allocator_pool<mutex> allocator_mutex_instance;
105
106#pragma GCC diagnostic pop
107
116 // The default RTOS system memory resource.
117#if !defined(OS_IS_CROSS_BUILD)
118
119 memory_resource* default_resource __attribute__ ((weak))
120 = reinterpret_cast<memory_resource*> (&malloc_res);
121
122 // ----------------------------------------------------------------------
123
124 memory_resource* resource_thread __attribute__ ((weak))
125 = reinterpret_cast<memory_resource*> (&malloc_res);
126
127 memory_resource* resource_condition_variable __attribute__ ((weak))
128 = reinterpret_cast<memory_resource*> (&malloc_res);
129
130 memory_resource* resource_event_flags __attribute__ ((weak))
131 = reinterpret_cast<memory_resource*> (&malloc_res);
132
133 memory_resource* resource_memory_pool __attribute__ ((weak))
134 = reinterpret_cast<memory_resource*> (&malloc_res);
135
136 memory_resource* resource_message_queue __attribute__ ((weak))
137 = reinterpret_cast<memory_resource*> (&malloc_res);
138
139 memory_resource* resource_mutex __attribute__ ((weak))
140 = reinterpret_cast<memory_resource*> (&malloc_res);
141
142 memory_resource* resource_semaphore __attribute__ ((weak))
143 = reinterpret_cast<memory_resource*> (&malloc_res);
144
145 memory_resource* resource_timer __attribute__ ((weak))
146 = reinterpret_cast<memory_resource*> (&malloc_res);
147
148#else
149
150 memory_resource* default_resource __attribute__ ((weak))
151 = reinterpret_cast<memory_resource*> (&null_res);
152
153 // ----------------------------------------------------------------------
154
155 memory_resource* resource_thread __attribute__ ((weak))
156 = reinterpret_cast<memory_resource*> (&null_res);
157
158 memory_resource* resource_condition_variable __attribute__ ((weak))
159 = reinterpret_cast<memory_resource*> (&null_res);
160
161 memory_resource* resource_event_flags __attribute__ ((weak))
162 = reinterpret_cast<memory_resource*> (&null_res);
163
164 memory_resource* resource_memory_pool __attribute__ ((weak))
165 = reinterpret_cast<memory_resource*> (&null_res);
166
167 memory_resource* resource_message_queue __attribute__ ((weak))
168 = reinterpret_cast<memory_resource*> (&null_res);
169
170 memory_resource* resource_mutex __attribute__ ((weak))
171 = reinterpret_cast<memory_resource*> (&null_res);
172
173 memory_resource* resource_semaphore __attribute__ ((weak))
174 = reinterpret_cast<memory_resource*> (&null_res);
175
176 memory_resource* resource_timer __attribute__ ((weak))
177 = reinterpret_cast<memory_resource*> (&null_res);
178
179#endif
180
185 // ----------------------------------------------------------------------
190 malloc_resource (void) noexcept
191 {
192 return reinterpret_cast<memory_resource*> (&malloc_res);
193 }
194
195 // ----------------------------------------------------------------------
196
206 memory_resource*
208 {
209 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
210
211 memory_resource* old = default_resource;
212 default_resource = res;
213
214 return old;
215 }
216
217 // ----------------------------------------------------------------------
218
225 template <>
228 {
229 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
230
231 memory_resource* old = resource_thread;
232 resource_thread = res;
233
234 return old;
235 }
236
243 template <>
246 {
247 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
248
249 memory_resource* old = resource_condition_variable;
250 resource_condition_variable = res;
251
252 return old;
253 }
254
261 template <>
264 {
265 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
266
267 memory_resource* old = resource_event_flags;
268 resource_event_flags = res;
269
270 return old;
271 }
272
279 template <>
282 {
283 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
284
285 memory_resource* old = resource_memory_pool;
286 resource_memory_pool = res;
287
288 return old;
289 }
290
297 template <>
300 {
301 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
302
303 memory_resource* old = resource_message_queue;
304 resource_message_queue = res;
305
306 return old;
307 }
308
315 template <>
318 {
319 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
320
321 memory_resource* old = resource_mutex;
322 resource_mutex = res;
323
324 return old;
325 }
326
333 template <>
336 {
337 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
338
339 memory_resource* old = resource_semaphore;
340 resource_semaphore = res;
341
342 return old;
343 }
344
351 template <>
354 {
355 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
356
357 memory_resource* old = resource_timer;
358 resource_timer = res;
359
360 return old;
361 }
362
363 // ======================================================================
364
366 {
367 }
368
418 bool
420 memory_resource const& other) const noexcept
421 {
422 return &other == this;
423 }
424
435 std::size_t
436 memory_resource::do_max_size (void) const noexcept
437 {
438 return 0;
439 }
440
451 void
453 {
454 return;
455 }
456
467 bool
469 {
470 return false;
471 }
472
473 void
475 std::size_t bytes) noexcept
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 }
488
489 void
491 std::size_t bytes) noexcept
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 }
500
501 // ----------------------------------------------------------------------
502
503 } /* namespace memory */
504 } /* namespace rtos */
505} /* namespace os */
506
507namespace os
508{
509 namespace estd
510 {
511 namespace pmr
512 {
518 new_delete_resource (void) noexcept
519 {
520 return reinterpret_cast<memory_resource*> (
521 &rtos::memory::new_delete_res);
522 }
523
525 null_memory_resource (void) noexcept
526 {
527 return reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
528 }
529
530#if !defined(OS_IS_CROSS_BUILD)
531 memory_resource* default_resource __attribute__ ((weak))
532 = reinterpret_cast<memory_resource*> (&rtos::memory::malloc_res);
533#else
534 memory_resource* default_resource __attribute__ ((weak))
535 = reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
536#endif
537
541 } /* namespace pmr */
542 } /* namespace estd */
543} /* namespace os */
544
545// ----------------------------------------------------------------------------
A memory manager that allocates memory via the system std::malloc() and deallocates via std::free().
Definition malloc.h:61
A memory manager that allocates memory via the system operator new and deallocates via operator delet...
Definition malloc.h:151
An internal memory manager that throws a bad_alloc() exception when trying to allocate.
Definition null.h:56
Memory resource manager (abstract class).
Definition os-memory.h:159
virtual bool do_is_equal(memory_resource const &other) const noexcept
Implementation of the equality comparator.
virtual void do_reset(void) noexcept
Implementation of the function to reset the memory manager.
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.
virtual std::size_t do_max_size(void) const noexcept
Implementation of the function to get max size.
virtual ~memory_resource()
Destruct the memory resource object instance.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
void init_once_default_resource(void)
memory_resource * set_default_resource(memory_resource *res) noexcept
Set the default RTOS system memory manager.
memory_resource * malloc_resource(void) noexcept
Get the address of a memory manager based on POSIX malloc().
memory_resource * set_resource_typed< condition_variable >(memory_resource *res) noexcept
memory_resource * set_resource_typed< message_queue >(memory_resource *res) noexcept
memory_resource * set_resource_typed< memory_pool >(memory_resource *res) noexcept
memory_resource * new_delete_resource(void) noexcept
Get the address of a memory manager based on new/delete.
memory_resource * set_resource_typed< event_flags >(memory_resource *res) noexcept
memory_resource * set_resource_typed< mutex >(memory_resource *res) noexcept
memory_resource * set_resource_typed< semaphore >(memory_resource *res) noexcept
memory_resource * set_resource_typed< thread >(memory_resource *res) noexcept
memory_resource * null_memory_resource(void) noexcept
Get the address of an ineffective memory manager.
memory_resource * set_resource_typed< timer >(memory_resource *res) noexcept
rtos::memory::memory_resource memory_resource
memory_resource * default_resource
System namespace.
Single file µOS++ RTOS definitions.