µOS++ IIIe Reference  v6.3.15
“Perfekt ist nicht gut genug”
The third edition of µOS++, a POSIX inspired open source system, written in C++.
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>
39 #include <cmsis-plus/memory/null.h>
40 
41 // ----------------------------------------------------------------------------
42 
43 using namespace os;
44 
45 // ----------------------------------------------------------------------------
46 
47 namespace os
48 {
49  namespace rtos
50  {
51  namespace memory
52  {
53  // ======================================================================
54 
59 #pragma GCC diagnostic push
60 #if defined(__clang__)
61 #pragma clang diagnostic ignored "-Wexit-time-destructors"
62 #pragma clang diagnostic ignored "-Wglobal-constructors"
63 #endif
64 
65  // The memory resources must not be destructed, since some
66  // static objects will want to deallocate memory they manage.
67 
68  static std::aligned_storage<sizeof(os::memory::malloc_memory_resource),
69  alignof(os::memory::malloc_memory_resource)>::type malloc_res;
70 
71  static std::aligned_storage<sizeof(os::memory::null_memory_resource),
72  alignof(os::memory::null_memory_resource)>::type null_res;
73 
74  static std::aligned_storage<
76  alignof(os::memory::new_delete_memory_resource)>::type new_delete_res;
77 
78  void
80  {
81  static int guard; // Cleared during BSS init.
82  if (guard == 0)
83  {
84  guard = 1;
85 
86  trace::printf ("rtos::memory::%s() \n", __func__);
87 
88  new (&malloc_res) os::memory::malloc_memory_resource ("malloc");
89  new (&null_res) os::memory::null_memory_resource ();
90  new (&new_delete_res) os::memory::new_delete_memory_resource ();
91  }
92  }
93 
94  // This guarantees that the memory resources are initialised
95  // before entering main().
96  static void
97  __attribute__((constructor))
98  __constructor (void)
99  {
101  }
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  // ----------------------------------------------------------------------
191  malloc_resource (void) noexcept
192  {
193  return reinterpret_cast<memory_resource*> (&malloc_res);
194  }
195 
196  // ----------------------------------------------------------------------
197 
209  {
210  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
211 
213  default_resource = res;
214 
215  return old;
216  }
217 
218  // ----------------------------------------------------------------------
219 
226  template<>
229  {
230  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
231 
232  memory_resource* old = resource_thread;
233  resource_thread = res;
234 
235  return old;
236  }
237 
244  template<>
247  {
248  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
249 
250  memory_resource* old = resource_condition_variable;
251  resource_condition_variable = res;
252 
253  return old;
254  }
255 
262  template<>
265  {
266  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
267 
268  memory_resource* old = resource_event_flags;
269  resource_event_flags = res;
270 
271  return old;
272  }
273 
280  template<>
283  {
284  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
285 
286  memory_resource* old = resource_memory_pool;
287  resource_memory_pool = res;
288 
289  return old;
290  }
291 
298  template<>
301  {
302  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
303 
304  memory_resource* old = resource_message_queue;
305  resource_message_queue = res;
306 
307  return old;
308  }
309 
316  template<>
319  {
320  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
321 
322  memory_resource* old = resource_mutex;
323  resource_mutex = res;
324 
325  return old;
326  }
327 
334  template<>
337  {
338  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
339 
340  memory_resource* old = resource_semaphore;
341  resource_semaphore = res;
342 
343  return old;
344  }
345 
352  template<>
355  {
356  trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
357 
358  memory_resource* old = resource_timer;
359  resource_timer = res;
360 
361  return old;
362  }
363 
364  // ======================================================================
365 
370  {
371  ;
372  }
373 
421  bool
422  memory_resource::do_is_equal (memory_resource const &other) const noexcept
423  {
424  return &other == this;
425  }
426 
437  std::size_t
438  memory_resource::do_max_size (void) const noexcept
439  {
440  return 0;
441  }
442 
453  void
455  {
456  return;
457  }
458 
469  bool
471  {
472  return false;
473  }
474 
475  void
477  std::size_t bytes) noexcept
478  {
479  // Update statistics.
480  // What is subtracted from free is added to allocated.
481  allocated_bytes_ += bytes;
482  if (allocated_bytes_ > max_allocated_bytes_)
483  {
484  max_allocated_bytes_ = allocated_bytes_;
485  }
486  free_bytes_ -= bytes;
487  ++allocated_chunks_;
488  --free_chunks_;
489  }
490 
491  void
493  std::size_t bytes) noexcept
494  {
495  // Update statistics.
496  // What is subtracted from allocated is added to free.
497  allocated_bytes_ -= bytes;
498  free_bytes_ += bytes;
499  --allocated_chunks_;
500  ++free_chunks_;
501 
502  }
503 
504  // ------------------------------------------------------------------------
505 
506  } /* namespace memory */
507  } /* namespace rtos */
508 } /* namespace os */
509 
510 namespace os
511 {
512  namespace estd
513  {
514  namespace pmr
515  {
521  new_delete_resource (void) noexcept
522  {
523  return reinterpret_cast<memory_resource*> (&rtos::memory::new_delete_res);
524  }
525 
527  null_memory_resource (void) noexcept
528  {
529  return reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
530  }
531 
532 #if !defined(OS_IS_CROSS_BUILD)
533  memory_resource* default_resource __attribute__((weak))
534  = reinterpret_cast<memory_resource*> (&rtos::memory::malloc_res);
535 #else
536  memory_resource* default_resource __attribute__((weak))
537  = reinterpret_cast<memory_resource*> (&rtos::memory::null_res);
538 #endif
539 
543  ;
544  // Avoid formatter bug
545  } /* namespace pmr */
546  } /* namespace estd */
547 } /* namespace os */
548 
549 // ----------------------------------------------------------------------------
Memory resource manager (abstract class).
Definition: os-memory.h:153
memory_resource * set_resource_typed< mutex >(memory_resource *res) noexcept
Definition: os-memory.cpp:318
memory_resource * set_resource_typed< message_queue >(memory_resource *res) noexcept
Definition: os-memory.cpp:300
A memory manager that allocates memory via the system operator new and deallocates via operator delet...
Definition: malloc.h:152
virtual bool do_coalesce(void) noexcept
Implementation of the function to coalesce free blocks.
Definition: os-memory.cpp:470
virtual void do_reset(void) noexcept
Implementation of the function to reset the memory manager.
Definition: os-memory.cpp:454
rtos::memory::memory_resource memory_resource
Definition: memory_resource:55
A memory manager that allocates memory via the system std::malloc() and deallocates via std::free()...
Definition: malloc.h:63
void internal_decrease_allocated_statistics(std::size_t bytes) noexcept
Update statistics after deallocation.
Definition: os-memory.cpp:492
An internal memory manager that throws a bad_alloc() exception when trying to allocate.
Definition: null.h:62
System namespace.
memory_resource * set_resource_typed< condition_variable >(memory_resource *res) noexcept
Definition: os-memory.cpp:246
memory_resource * set_resource_typed< semaphore >(memory_resource *res) noexcept
Definition: os-memory.cpp:336
memory_resource * set_default_resource(memory_resource *res) noexcept
Set the default RTOS system memory manager.
Definition: os-memory.cpp:208
memory_resource * set_resource_typed< timer >(memory_resource *res) noexcept
Definition: os-memory.cpp:354
memory_resource * set_resource_typed< memory_pool >(memory_resource *res) noexcept
Definition: os-memory.cpp:282
virtual ~memory_resource()
Destruct the memory resource object instance.
Definition: os-memory.cpp:369
virtual bool do_is_equal(memory_resource const &other) const noexcept
Implementation of the equality comparator.
Definition: os-memory.cpp:422
Single file µOS++ RTOS definitions.
void init_once_default_resource(void)
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition: trace.cpp:74
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
Definition: os-memory.cpp:264
void internal_increase_allocated_statistics(std::size_t bytes) noexcept
Update statistics after allocation.
Definition: os-memory.cpp:476
memory_resource * default_resource
memory_resource * malloc_resource(void) noexcept
Get the address of a memory manager based on POSIX malloc().
Definition: os-memory.cpp:191
memory_resource * null_memory_resource(void) noexcept
Get the address of an ineffective memory manager.
virtual std::size_t do_max_size(void) const noexcept
Implementation of the function to get max size.
Definition: os-memory.cpp:438
memory_resource * set_resource_typed< thread >(memory_resource *res) noexcept
Definition: os-memory.cpp:228