µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
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#if defined(__clang__)
47#pragma clang diagnostic ignored "-Wc++98-compat"
48#endif
49
50// ----------------------------------------------------------------------------
51
52using namespace os;
53
54// ----------------------------------------------------------------------------
55
56namespace
57{
65 std::new_handler new_handler_;
66}
67
73namespace std
74{
75 // Constant to be used as parameter to differentiate
76 // the `noexcept` functions.
77 const nothrow_t nothrow = nothrow_t
78 { };
79
96 new_handler
97 set_new_handler (new_handler handler) noexcept
98 {
99 trace::printf ("std::%s(%p) \n", __func__, handler);
100
101 new_handler prev_handler;
102
103 prev_handler = new_handler_;
104 new_handler_ = handler;
105
106 return prev_handler;
107 }
108
118 new_handler
119 get_new_handler () noexcept
120 {
121 return new_handler_;
122 }
123
124} /* namespace std */
125
126// ----------------------------------------------------------------------------
127
152void *
153__attribute__((weak))
154operator new (std::size_t bytes)
155{
157 if (bytes == 0)
158 {
159 bytes = 1;
160 }
161
162 // ----- Begin of critical section ------------------------------------------
164
165 while (true)
166 {
167 void* mem = estd::pmr::get_default_resource ()->allocate (bytes);
168
169 if (mem != nullptr)
170 {
171#if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
172 trace::printf ("::%s(%d)=%p\n", __func__, bytes, mem);
173#endif
174 return mem;
175 }
176
177 // If allocate() fails and there is a new_handler,
178 // call it to try free up memory.
179 if (new_handler_)
180 {
181 new_handler_ ();
182 }
183 else
184 {
186 }
187 }
188
189 // ----- End of critical section --------------------------------------------
190}
191
214void*
215__attribute__((weak))
216operator new (std::size_t bytes,
217 const std::nothrow_t& nothrow __attribute__((unused))) noexcept
218{
220
221 if (bytes == 0)
222 {
223 bytes = 1;
224 }
225
226 // ----- Begin of critical section ------------------------------------------
228
229 while (true)
230 {
231 void* mem = estd::pmr::get_default_resource ()->allocate (bytes);
232
233 if (mem != nullptr)
234 {
235#if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
236 trace::printf ("::%s(%d)=%p\n", __func__, bytes, mem);
237#endif
238 return mem;
239 }
240
241 // If allocate() fails and there is a new_handler,
242 // call it to try free up memory.
243 if (new_handler_)
244 {
245 new_handler_ ();
246 }
247 else
248 {
249 break; // return nullptr
250 }
251 }
252
253 // ----- End of critical section --------------------------------------------
254
255 return nullptr;
256}
257
273void*
274__attribute__((weak))
275operator new[] (std::size_t bytes)
276{
277 return ::operator new (bytes);
278}
279
296void*
297__attribute__((weak))
298operator new[] (std::size_t bytes,
299 const std::nothrow_t& nothrow __attribute__((unused))) noexcept
300{
301 return ::operator new (bytes, std::nothrow);
302}
303
304// ----------------------------------------------------------------------------
305
329void
330__attribute__((weak))
331operator delete (void* ptr) noexcept
332{
333#if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
334 trace::printf ("::%s(%p)\n", __func__, ptr);
335#endif
336
338
339 if (ptr)
340 {
341 // ----- Begin of critical section --------------------------------------
343
344 // The unknown size is passed as 0.
346 // ----- End of critical section ----------------------------------------
347 }
348}
349
350#pragma GCC diagnostic push
351#pragma GCC diagnostic ignored "-Wc++14-compat"
352
353void
354operator delete (void* ptr, std::size_t bytes) noexcept;
355
380void
381__attribute__((weak))
382operator delete (void* ptr, std::size_t bytes) noexcept
383{
384#if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
385 trace::printf ("::%s(%p,%u)\n", __func__, ptr, bytes);
386#endif
387
389
390 if (ptr)
391 {
392 // ----- Begin of critical section --------------------------------------
394
396 // ----- End of critical section ----------------------------------------
397 }
398}
399
400#pragma GCC diagnostic pop
401
420void
421__attribute__((weak))
422operator delete (void* ptr,
423 const std::nothrow_t& nothrow __attribute__((unused))) noexcept
424{
425#if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
426 trace::printf ("::%s(%p)\n", __func__, ptr);
427#endif
428
430
431 if (ptr)
432 {
433 // ----- Begin of critical section --------------------------------------
435
437 // ----- End of critical section ----------------------------------------
438 }
439}
440
459void
460__attribute__((weak))
461operator delete[] (void* ptr) noexcept
462{
463 ::operator delete (ptr);
464}
465
466#pragma GCC diagnostic push
467#pragma GCC diagnostic ignored "-Wc++14-compat"
468
469void
470operator delete[] (void* ptr, std::size_t bytes) noexcept;
471
491void
492__attribute__((weak))
493operator delete[] (void* ptr, std::size_t bytes) noexcept
494{
495 ::operator delete (ptr, bytes);
496}
497
498#pragma GCC diagnostic pop
499
521void
522__attribute__((weak))
523operator delete[] (void* ptr, const std::nothrow_t& nothrow) noexcept
524{
525 ::operator delete (ptr, nothrow);
526}
527
536// ----------------------------------------------------------------------------
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:1316
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
Definition os-memory.h:1294
Scheduler critical section RAII helper.
Definition os-sched.h:182
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
std::new_handler new_handler_
The current new handler.
Definition new.cpp:65
new_handler get_new_handler() noexcept
Get the current handler.
Definition new.cpp:119
new_handler set_new_handler(new_handler handler) noexcept
Establishes the function designated by handler as the current new_handler.
Definition new.cpp:97
memory_resource * get_default_resource(void) noexcept
Get the default application memory manager.
const nothrow_t nothrow
Definition new.cpp:77
void __throw_bad_alloc(void)
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1136
System namespace.
Standard std namespace.
Single file µOS++ RTOS definitions.