µ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++.
new.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 
41 #include <cmsis-plus/rtos/os.h>
43 
44 // ----------------------------------------------------------------------------
45 
46 using namespace os;
47 
48 // ----------------------------------------------------------------------------
49 
50 namespace
51 {
59  std::new_handler new_handler_;
60 }
61 
67 namespace std
68 {
69  // Constant to be used as parameter to differentiate
70  // the `noexcept` functions.
71  const nothrow_t nothrow = nothrow_t
72  { };
73 
90  new_handler
91  set_new_handler (new_handler handler) noexcept
92  {
93  trace::printf ("std::%s(%p) \n", __func__, handler);
94 
95  new_handler prev_handler;
96 
97  prev_handler = new_handler_;
98  new_handler_ = handler;
99 
100  return prev_handler;
101  }
102 
112  new_handler
113  get_new_handler () noexcept
114  {
115  return new_handler_;
116  }
117 
118 } /* namespace std */
119 
120 // ----------------------------------------------------------------------------
121 
146 void *
147 __attribute__((weak))
148 operator new (std::size_t bytes)
149 {
151  if (bytes == 0)
152  {
153  bytes = 1;
154  }
155 
156  // ----- Begin of critical section ------------------------------------------
158 
159  while (true)
160  {
161  void* mem = estd::pmr::get_default_resource ()->allocate (bytes);
162 
163  if (mem != nullptr)
164  {
165 #if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
166  trace::printf ("::%s(%d)=%p\n", __func__, bytes, mem);
167 #endif
168  return mem;
169  }
170 
171  // If allocate() fails and there is a new_handler,
172  // call it to try free up memory.
173  if (new_handler_)
174  {
175  new_handler_ ();
176  }
177  else
178  {
180  }
181  }
182 
183  // ----- End of critical section --------------------------------------------
184 }
185 
208 void*
209 __attribute__((weak))
210 operator new (std::size_t bytes,
211  const std::nothrow_t& nothrow __attribute__((unused))) noexcept
212 {
214 
215  if (bytes == 0)
216  {
217  bytes = 1;
218  }
219 
220  // ----- Begin of critical section ------------------------------------------
222 
223  while (true)
224  {
225  void* mem = estd::pmr::get_default_resource ()->allocate (bytes);
226 
227  if (mem != nullptr)
228  {
229 #if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
230  trace::printf ("::%s(%d)=%p\n", __func__, bytes, mem);
231 #endif
232  return mem;
233  }
234 
235  // If allocate() fails and there is a new_handler,
236  // call it to try free up memory.
237  if (new_handler_)
238  {
239  new_handler_ ();
240  }
241  else
242  {
243  break; // return nullptr
244  }
245  }
246 
247  // ----- End of critical section --------------------------------------------
248 
249  return nullptr;
250 }
251 
267 void*
268 __attribute__((weak))
269 operator new[] (std::size_t bytes)
270 {
271  return ::operator new (bytes);
272 }
273 
290 void*
291 __attribute__((weak))
292 operator new[] (std::size_t bytes,
293  const std::nothrow_t& nothrow __attribute__((unused))) noexcept
294 {
295  return ::operator new (bytes, std::nothrow);
296 }
297 
298 // ----------------------------------------------------------------------------
299 
323 void
324 __attribute__((weak))
325 operator delete (void* ptr) noexcept
326 {
327 #if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
328  trace::printf ("::%s(%p)\n", __func__, ptr);
329 #endif
330 
332 
333  if (ptr)
334  {
335  // ----- Begin of critical section --------------------------------------
337 
338  // The unknown size is passed as 0.
340  // ----- End of critical section ----------------------------------------
341  }
342 }
343 
344 #pragma GCC diagnostic push
345 #pragma GCC diagnostic ignored "-Wc++14-compat"
346 
347 void
348 operator delete (void* ptr, std::size_t bytes) noexcept;
349 
374 void
375 __attribute__((weak))
376 operator delete (void* ptr, std::size_t bytes) noexcept
377 {
378 #if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
379  trace::printf ("::%s(%p,%u)\n", __func__, ptr, bytes);
380 #endif
381 
383 
384  if (ptr)
385  {
386  // ----- Begin of critical section --------------------------------------
388 
390  // ----- End of critical section ----------------------------------------
391  }
392 }
393 
394 #pragma GCC diagnostic pop
395 
414 void
415 __attribute__((weak))
416 operator delete (void* ptr,
417  const std::nothrow_t& nothrow __attribute__((unused))) noexcept
418 {
419 #if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
420  trace::printf ("::%s(%p)\n", __func__, ptr);
421 #endif
422 
424 
425  if (ptr)
426  {
427  // ----- Begin of critical section --------------------------------------
429 
431  // ----- End of critical section ----------------------------------------
432  }
433 }
434 
453 void
454 __attribute__((weak))
455 operator delete[] (void* ptr) noexcept
456 {
457  ::operator delete (ptr);
458 }
459 
460 #pragma GCC diagnostic push
461 #pragma GCC diagnostic ignored "-Wc++14-compat"
462 
463 void
464 operator delete[] (void* ptr, std::size_t bytes) noexcept;
465 
485 void
486 __attribute__((weak))
487 operator delete[] (void* ptr, std::size_t bytes) noexcept
488 {
489  ::operator delete (ptr, bytes);
490 }
491 
492 #pragma GCC diagnostic pop
493 
515 void
516 __attribute__((weak))
517 operator delete[] (void* ptr, const std::nothrow_t& nothrow) noexcept
518 {
519  ::operator delete (ptr, nothrow);
520 }
521 
530 // ----------------------------------------------------------------------------
memory_resource * get_default_resource(void) noexcept
Get the default application memory manager.
Standard std namespace.
const nothrow_t nothrow
Definition: new.cpp:71
System namespace.
Scheduler critical section RAII helper.
Definition: os-sched.h:170
Single file µOS++ RTOS definitions.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition: trace.cpp:74
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
Definition: os-memory.h:1285
new_handler set_new_handler(new_handler handler) noexcept
Establishes the function designated by handler as the current new_handler.
Definition: new.cpp:91
new_handler get_new_handler() noexcept
Get the current handler.
Definition: new.cpp:113
void deallocate(void *addr, std::size_t bytes, std::size_t alignment=max_align) noexcept
Deallocate the previously allocated memory block.
Definition: os-memory.h:1307
std::new_handler new_handler_
The current new handler.
Definition: new.cpp:59
void __throw_bad_alloc(void)
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition: os-sched.h:1091