µ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++ 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/*
14 * [Partly inspired from the LLVM libcxx sources].
15 * Copyright (c) 2009-2013 by the contributors listed in
16 * 'LLVM libcxx Credits.txt'. See 'LLVM libcxx License.txt' for details.
17 *
18 * References are to ISO/IEC 14882:2011(E) Third edition (2011-09-01).
19 */
20
21#if defined(OS_USE_OS_APP_CONFIG_H)
22#include <cmsis-plus/os-app-config.h>
23#endif
24
25#include <cmsis-plus/rtos/os.h>
29
30// ----------------------------------------------------------------------------
31
32#if defined(__clang__)
33#pragma clang diagnostic ignored "-Wc++98-compat"
34#endif
35
36// ----------------------------------------------------------------------------
37
38using namespace os;
39
40// ----------------------------------------------------------------------------
41
42namespace os
43{
44 namespace rtos
45 {
46 namespace memory
47 {
48 // ======================================================================
49
54#pragma GCC diagnostic push
55#if defined(__clang__)
56#pragma clang diagnostic ignored "-Wexit-time-destructors"
57#pragma clang diagnostic ignored "-Wglobal-constructors"
58#endif
59
60 // The memory resources must not be destructed, since some
61 // static objects will want to deallocate memory they manage.
62
63 static std::aligned_storage<sizeof(os::memory::malloc_memory_resource),
64 alignof(os::memory::malloc_memory_resource)>::type malloc_res;
65
66 static std::aligned_storage<sizeof(os::memory::null_memory_resource),
67 alignof(os::memory::null_memory_resource)>::type null_res;
68
69 static std::aligned_storage<
71 alignof(os::memory::new_delete_memory_resource)>::type new_delete_res;
72
73 void
75 {
76 static int guard; // Cleared during BSS init.
77 if (guard == 0)
78 {
79 guard = 1;
80
81 trace::printf ("rtos::memory::%s() \n", __func__);
82
83 new (&malloc_res) os::memory::malloc_memory_resource ("malloc");
84 new (&null_res) os::memory::null_memory_resource ();
85 new (&new_delete_res) os::memory::new_delete_memory_resource ();
86 }
87 }
88
89#pragma GCC diagnostic push
90#if defined(__clang__)
91#pragma clang diagnostic ignored "-Wreserved-identifier"
92#endif
93 // This guarantees that the memory resources are initialised
94 // before entering main().
95 static void
96 __attribute__((constructor))
97 __constructor (void)
98 {
100 }
101#pragma GCC diagnostic pop
102
103 // allocator_pool<mutex> allocator_mutex_instance;
104
105#pragma GCC diagnostic pop
106
115 // The default RTOS system memory resource.
116#if !defined(OS_IS_CROSS_BUILD)
117
118 memory_resource* default_resource __attribute__((weak))
119 = reinterpret_cast<memory_resource*> (&malloc_res);
120
121 // ----------------------------------------------------------------------
122
123 memory_resource* resource_thread __attribute__((weak))
124 = reinterpret_cast<memory_resource*> (&malloc_res);
125
126 memory_resource* resource_condition_variable __attribute__((weak))
127 = reinterpret_cast<memory_resource*> (&malloc_res);
128
129 memory_resource* resource_event_flags __attribute__((weak))
130 = reinterpret_cast<memory_resource*> (&malloc_res);
131
132 memory_resource* resource_memory_pool __attribute__((weak))
133 = reinterpret_cast<memory_resource*> (&malloc_res);
134
135 memory_resource* resource_message_queue __attribute__((weak))
136 = reinterpret_cast<memory_resource*> (&malloc_res);
137
138 memory_resource* resource_mutex __attribute__((weak))
139 = reinterpret_cast<memory_resource*> (&malloc_res);
140
141 memory_resource* resource_semaphore __attribute__((weak))
142 = reinterpret_cast<memory_resource*> (&malloc_res);
143
144 memory_resource* resource_timer __attribute__((weak))
145 = reinterpret_cast<memory_resource*> (&malloc_res);
146
147#else
148
149 memory_resource* default_resource __attribute__((weak))
150 = reinterpret_cast<memory_resource*> (&null_res);
151
152 // ----------------------------------------------------------------------
153
154 memory_resource* resource_thread __attribute__((weak))
155 = reinterpret_cast<memory_resource*> (&null_res);
156
157 memory_resource* resource_condition_variable __attribute__((weak))
158 = reinterpret_cast<memory_resource*> (&null_res);
159
160 memory_resource* resource_event_flags __attribute__((weak))
161 = reinterpret_cast<memory_resource*> (&null_res);
162
163 memory_resource* resource_memory_pool __attribute__((weak))
164 = reinterpret_cast<memory_resource*> (&null_res);
165
166 memory_resource* resource_message_queue __attribute__((weak))
167 = reinterpret_cast<memory_resource*> (&null_res);
168
169 memory_resource* resource_mutex __attribute__((weak))
170 = reinterpret_cast<memory_resource*> (&null_res);
171
172 memory_resource* resource_semaphore __attribute__((weak))
173 = reinterpret_cast<memory_resource*> (&null_res);
174
175 memory_resource* resource_timer __attribute__((weak))
176 = reinterpret_cast<memory_resource*> (&null_res);
177
178#endif
179
184 // ----------------------------------------------------------------------
189 malloc_resource (void) noexcept
190 {
191 return reinterpret_cast<memory_resource*> (&malloc_res);
192 }
193
194 // ----------------------------------------------------------------------
195
205 memory_resource*
207 {
208 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
209
210 memory_resource* old = default_resource;
211 default_resource = res;
212
213 return old;
214 }
215
216 // ----------------------------------------------------------------------
217
224 template<>
227 {
228 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
229
230 memory_resource* old = resource_thread;
231 resource_thread = res;
232
233 return old;
234 }
235
242 template<>
245 {
246 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
247
248 memory_resource* old = resource_condition_variable;
249 resource_condition_variable = res;
250
251 return old;
252 }
253
260 template<>
263 {
264 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
265
266 memory_resource* old = resource_event_flags;
267 resource_event_flags = res;
268
269 return old;
270 }
271
278 template<>
281 {
282 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
283
284 memory_resource* old = resource_memory_pool;
285 resource_memory_pool = res;
286
287 return old;
288 }
289
296 template<>
299 {
300 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
301
302 memory_resource* old = resource_message_queue;
303 resource_message_queue = res;
304
305 return old;
306 }
307
314 template<>
317 {
318 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
319
320 memory_resource* old = resource_mutex;
321 resource_mutex = res;
322
323 return old;
324 }
325
332 template<>
335 {
336 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
337
338 memory_resource* old = resource_semaphore;
339 resource_semaphore = res;
340
341 return old;
342 }
343
350 template<>
353 {
354 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
355
356 memory_resource* old = resource_timer;
357 resource_timer = res;
358
359 return old;
360 }
361
362 // ======================================================================
363
365 {
366 }
367
415 bool
416 memory_resource::do_is_equal (memory_resource const &other) const noexcept
417 {
418 return &other == this;
419 }
420
431 std::size_t
432 memory_resource::do_max_size (void) const noexcept
433 {
434 return 0;
435 }
436
447 void
449 {
450 return;
451 }
452
463 bool
465 {
466 return false;
467 }
468
469 void
471 std::size_t bytes) noexcept
472 {
473 // Update statistics.
474 // What is subtracted from free is added to allocated.
475 allocated_bytes_ += bytes;
476 if (allocated_bytes_ > max_allocated_bytes_)
477 {
478 max_allocated_bytes_ = allocated_bytes_;
479 }
480 free_bytes_ -= bytes;
481 ++allocated_chunks_;
482 --free_chunks_;
483 }
484
485 void
487 std::size_t bytes) noexcept
488 {
489 // Update statistics.
490 // What is subtracted from allocated is added to free.
491 allocated_bytes_ -= bytes;
492 free_bytes_ += bytes;
493 --allocated_chunks_;
494 ++free_chunks_;
495
496 }
497
498 // ------------------------------------------------------------------------
499
500 } /* namespace memory */
501 } /* namespace rtos */
502} /* namespace os */
503
504namespace os
505{
506 namespace estd
507 {
508 namespace pmr
509 {
515 new_delete_resource (void) noexcept
516 {
517 return reinterpret_cast<memory_resource*> (&rtos::memory::new_delete_res);
518 }
519
521 null_memory_resource (void) noexcept
522 {
523 return reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
524 }
525
526#if !defined(OS_IS_CROSS_BUILD)
527 memory_resource* default_resource __attribute__((weak))
528 = reinterpret_cast<memory_resource*> (&rtos::memory::malloc_res);
529#else
530 memory_resource* default_resource __attribute__((weak))
531 = reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
532#endif
533
537 } /* namespace pmr */
538 } /* namespace estd */
539} /* namespace os */
540
541// ----------------------------------------------------------------------------
A memory manager that allocates memory via the system std::malloc() and deallocates via std::free().
Definition malloc.h:62
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:57
Memory resource manager (abstract class).
Definition os-memory.h:160
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:60
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.