µ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 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28/*
29 * [Partly inspired from the LLVM libcxx sources].
30 * Copyright (c) 2009-2013 by the contributors listed in
31 * 'LLVM libcxx Credits.txt'. See 'LLVM libcxx License.txt' for details.
32 *
33 * References are to ISO/IEC 14882:2011(E) Third edition (2011-09-01).
34 */
35
36#include <cmsis-plus/rtos/os.h>
40
41// ----------------------------------------------------------------------------
42
43#if defined(__clang__)
44#pragma clang diagnostic ignored "-Wc++98-compat"
45#endif
46
47// ----------------------------------------------------------------------------
48
49using namespace os;
50
51// ----------------------------------------------------------------------------
52
53namespace os
54{
55 namespace rtos
56 {
57 namespace memory
58 {
59 // ======================================================================
60
65#pragma GCC diagnostic push
66#if defined(__clang__)
67#pragma clang diagnostic ignored "-Wexit-time-destructors"
68#pragma clang diagnostic ignored "-Wglobal-constructors"
69#endif
70
71 // The memory resources must not be destructed, since some
72 // static objects will want to deallocate memory they manage.
73
74 static std::aligned_storage<sizeof(os::memory::malloc_memory_resource),
75 alignof(os::memory::malloc_memory_resource)>::type malloc_res;
76
77 static std::aligned_storage<sizeof(os::memory::null_memory_resource),
78 alignof(os::memory::null_memory_resource)>::type null_res;
79
80 static std::aligned_storage<
82 alignof(os::memory::new_delete_memory_resource)>::type new_delete_res;
83
84 void
86 {
87 static int guard; // Cleared during BSS init.
88 if (guard == 0)
89 {
90 guard = 1;
91
92 trace::printf ("rtos::memory::%s() \n", __func__);
93
94 new (&malloc_res) os::memory::malloc_memory_resource ("malloc");
95 new (&null_res) os::memory::null_memory_resource ();
96 new (&new_delete_res) os::memory::new_delete_memory_resource ();
97 }
98 }
99
100 // This guarantees that the memory resources are initialised
101 // before entering main().
102 static void
103 __attribute__((constructor))
104 __constructor (void)
105 {
107 }
108
109 // allocator_pool<mutex> allocator_mutex_instance;
110
111#pragma GCC diagnostic pop
112
121 // The default RTOS system memory resource.
122#if !defined(OS_IS_CROSS_BUILD)
123
124 memory_resource* default_resource __attribute__((weak))
125 = reinterpret_cast<memory_resource*> (&malloc_res);
126
127 // ----------------------------------------------------------------------
128
129 memory_resource* resource_thread __attribute__((weak))
130 = reinterpret_cast<memory_resource*> (&malloc_res);
131
132 memory_resource* resource_condition_variable __attribute__((weak))
133 = reinterpret_cast<memory_resource*> (&malloc_res);
134
135 memory_resource* resource_event_flags __attribute__((weak))
136 = reinterpret_cast<memory_resource*> (&malloc_res);
137
138 memory_resource* resource_memory_pool __attribute__((weak))
139 = reinterpret_cast<memory_resource*> (&malloc_res);
140
141 memory_resource* resource_message_queue __attribute__((weak))
142 = reinterpret_cast<memory_resource*> (&malloc_res);
143
144 memory_resource* resource_mutex __attribute__((weak))
145 = reinterpret_cast<memory_resource*> (&malloc_res);
146
147 memory_resource* resource_semaphore __attribute__((weak))
148 = reinterpret_cast<memory_resource*> (&malloc_res);
149
150 memory_resource* resource_timer __attribute__((weak))
151 = reinterpret_cast<memory_resource*> (&malloc_res);
152
153#else
154
155 memory_resource* default_resource __attribute__((weak))
156 = reinterpret_cast<memory_resource*> (&null_res);
157
158 // ----------------------------------------------------------------------
159
160 memory_resource* resource_thread __attribute__((weak))
161 = reinterpret_cast<memory_resource*> (&null_res);
162
163 memory_resource* resource_condition_variable __attribute__((weak))
164 = reinterpret_cast<memory_resource*> (&null_res);
165
166 memory_resource* resource_event_flags __attribute__((weak))
167 = reinterpret_cast<memory_resource*> (&null_res);
168
169 memory_resource* resource_memory_pool __attribute__((weak))
170 = reinterpret_cast<memory_resource*> (&null_res);
171
172 memory_resource* resource_message_queue __attribute__((weak))
173 = reinterpret_cast<memory_resource*> (&null_res);
174
175 memory_resource* resource_mutex __attribute__((weak))
176 = reinterpret_cast<memory_resource*> (&null_res);
177
178 memory_resource* resource_semaphore __attribute__((weak))
179 = reinterpret_cast<memory_resource*> (&null_res);
180
181 memory_resource* resource_timer __attribute__((weak))
182 = reinterpret_cast<memory_resource*> (&null_res);
183
184#endif
185
190 // ----------------------------------------------------------------------
195 malloc_resource (void) noexcept
196 {
197 return reinterpret_cast<memory_resource*> (&malloc_res);
198 }
199
200 // ----------------------------------------------------------------------
201
211 memory_resource*
213 {
214 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
215
216 memory_resource* old = default_resource;
217 default_resource = res;
218
219 return old;
220 }
221
222 // ----------------------------------------------------------------------
223
230 template<>
233 {
234 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
235
236 memory_resource* old = resource_thread;
237 resource_thread = res;
238
239 return old;
240 }
241
248 template<>
251 {
252 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
253
254 memory_resource* old = resource_condition_variable;
255 resource_condition_variable = res;
256
257 return old;
258 }
259
266 template<>
269 {
270 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
271
272 memory_resource* old = resource_event_flags;
273 resource_event_flags = res;
274
275 return old;
276 }
277
284 template<>
287 {
288 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
289
290 memory_resource* old = resource_memory_pool;
291 resource_memory_pool = res;
292
293 return old;
294 }
295
302 template<>
305 {
306 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
307
308 memory_resource* old = resource_message_queue;
309 resource_message_queue = res;
310
311 return old;
312 }
313
320 template<>
323 {
324 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
325
326 memory_resource* old = resource_mutex;
327 resource_mutex = res;
328
329 return old;
330 }
331
338 template<>
341 {
342 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
343
344 memory_resource* old = resource_semaphore;
345 resource_semaphore = res;
346
347 return old;
348 }
349
356 template<>
359 {
360 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
361
362 memory_resource* old = resource_timer;
363 resource_timer = res;
364
365 return old;
366 }
367
368 // ======================================================================
369
371 {
372 ;
373 }
374
422 bool
423 memory_resource::do_is_equal (memory_resource const &other) const noexcept
424 {
425 return &other == this;
426 }
427
438 std::size_t
439 memory_resource::do_max_size (void) const noexcept
440 {
441 return 0;
442 }
443
454 void
456 {
457 return;
458 }
459
470 bool
472 {
473 return false;
474 }
475
476 void
478 std::size_t bytes) noexcept
479 {
480 // Update statistics.
481 // What is subtracted from free is added to allocated.
482 allocated_bytes_ += bytes;
483 if (allocated_bytes_ > max_allocated_bytes_)
484 {
485 max_allocated_bytes_ = allocated_bytes_;
486 }
487 free_bytes_ -= bytes;
488 ++allocated_chunks_;
489 --free_chunks_;
490 }
491
492 void
494 std::size_t bytes) noexcept
495 {
496 // Update statistics.
497 // What is subtracted from allocated is added to free.
498 allocated_bytes_ -= bytes;
499 free_bytes_ += bytes;
500 --allocated_chunks_;
501 ++free_chunks_;
502
503 }
504
505 // ------------------------------------------------------------------------
506
507 } /* namespace memory */
508 } /* namespace rtos */
509} /* namespace os */
510
511namespace os
512{
513 namespace estd
514 {
515 namespace pmr
516 {
522 new_delete_resource (void) noexcept
523 {
524 return reinterpret_cast<memory_resource*> (&rtos::memory::new_delete_res);
525 }
526
528 null_memory_resource (void) noexcept
529 {
530 return reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
531 }
532
533#if !defined(OS_IS_CROSS_BUILD)
534 memory_resource* default_resource __attribute__((weak))
535 = reinterpret_cast<memory_resource*> (&rtos::memory::malloc_res);
536#else
537 memory_resource* default_resource __attribute__((weak))
538 = reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
539#endif
540
544 } /* namespace pmr */
545 } /* namespace estd */
546} /* namespace os */
547
548// ----------------------------------------------------------------------------
A memory manager that allocates memory via the system std::malloc() and deallocates via std::free().
Definition malloc.h:74
A memory manager that allocates memory via the system operator new and deallocates via operator delet...
Definition malloc.h:163
An internal memory manager that throws a bad_alloc() exception when trying to allocate.
Definition null.h:73
Memory resource manager (abstract class).
Definition os-memory.h:165
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:74
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.