µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
malloc.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#if defined(__ARM_EABI__) || defined(__DOXYGEN__)
13
14// ----------------------------------------------------------------------------
15
16#if defined(OS_USE_OS_APP_CONFIG_H)
17#include <cmsis-plus/os-app-config.h>
18#endif
19
20#include <cmsis-plus/rtos/os.h>
22
23#include <malloc.h>
24
25// ----------------------------------------------------------------------------
26
27using namespace os;
28
29// ----------------------------------------------------------------------------
30
41// These library functions were modified to use the application
42// memory resource and to be thread safe.
83void*
84malloc (size_t bytes)
85{
87
88 void* mem;
89 {
90 // ----- Begin of critical section --------------------------------------
92
93 errno = 0;
95 if (mem == nullptr)
96 {
97 errno = ENOMEM;
98 }
99
100#if defined(OS_TRACE_LIBC_MALLOC)
101 trace::printf ("::%s(%d)=%p\n", __func__, bytes, mem);
102#endif
103 // ----- End of critical section ----------------------------------------
104 }
105
106 return mem;
107}
108
152void*
153calloc (size_t nelem, size_t elbytes)
154{
156
157 errno = 0;
158 if (nelem == 0 || elbytes == 0)
159 {
160 return nullptr;
161 }
162
163 void* mem;
164 {
165 // ----- Begin of critical section ----------------------------------------
167
168 mem = estd::pmr::get_default_resource ()->allocate (nelem * elbytes);
169
170#if defined(OS_TRACE_LIBC_MALLOC)
171 trace::printf ("::%s(%u,%u)=%p\n", __func__, nelem, elbytes, mem);
172#endif
173 // ----- End of critical section ------------------------------------------
174 }
175
176 if (mem != nullptr)
177 {
178 memset (mem, 0, nelem * elbytes);
179 }
180 else
181 {
182 errno = ENOMEM;
183 }
184
185 return mem;
186}
187
253void*
254realloc (void* ptr, size_t bytes)
255{
257
258 void* mem;
259
260 {
261 // ----- Begin of critical section ----------------------------------------
263
264 errno = 0;
265 if (ptr == nullptr)
266 {
268#if defined(OS_TRACE_LIBC_MALLOC)
269 trace::printf ("::%s(%p,%u)=%p\n", __func__, ptr, bytes, mem);
270#endif
271 if (mem == nullptr)
272 {
273 errno = ENOMEM;
274 }
275 return mem;
276 }
277
278 if (bytes == 0)
279 {
281#if defined(OS_TRACE_LIBC_MALLOC)
282 trace::printf ("::%s(%p,%u)=0\n", __func__, ptr, bytes);
283#endif
284 return nullptr;
285 }
286
287#if 0
288 /* TODO: There is chance to shrink the chunk if newly requested
289 * size is much small */
290 if (nano_malloc_usable_size (RCALL ptr) >= bytes)
291 return ptr;
292#endif
293
295 if (mem != nullptr)
296 {
297 memcpy (mem, ptr, bytes);
299 }
300 else
301 {
302 errno = ENOMEM;
303 }
304
305#if defined(OS_TRACE_LIBC_MALLOC)
306 trace::printf ("::%s(%p,%u)=%p", __func__, ptr, bytes, mem);
307#endif
308 // ----- End of critical section ------------------------------------------
309 }
310
311 return mem;
312}
313
346void
347free (void* ptr)
348{
350
351 if (ptr == nullptr)
352 {
353 return;
354 }
355
356 // ----- Begin of critical section ------------------------------------------
358
359#if defined(OS_TRACE_LIBC_MALLOC)
360 trace::printf ("::%s(%p)\n", __func__, ptr);
361#endif
362
363 // Size unknown, pass 0.
365 // ----- End of critical section --------------------------------------------
366}
367
376// ----------------------------------------------------------------------------
377// Redirect impure functions to the implementation, to avoid including
378// weird newlib functions.
383void*
384_malloc_r (/* struct */ _reent* impure __attribute__ ((unused)), size_t size)
385{
386 return malloc (size);
387}
388
389void*
390_calloc_r (/* struct */ _reent* impure __attribute__ ((unused)), size_t n,
391 size_t elem)
392{
393 return calloc (n, elem);
394}
395
396void
397_free_r (/* struct */ _reent* impure __attribute__ ((unused)), void* ptr)
398{
399 free (ptr);
400}
401
402void*
403_realloc_r (/* struct */ _reent* impure __attribute__ ((unused)), void* ptr,
404 size_t size)
405{
406 return realloc (ptr, size);
407}
408
413// ----------------------------------------------------------------------------
414// Not really implemented, but present here to avoid including
415// weird newlib functions.
420#pragma GCC diagnostic push
421#if defined(__clang__)
422#elif defined(__GNUC__)
423#pragma GCC diagnostic ignored "-Waggregate-return"
424#endif
425
426struct mallinfo
427_mallinfo_r (/* struct */ _reent* impure __attribute__ ((unused)))
428{
429 abort ();
430}
431
432#pragma GCC diagnostic pop
433
434void
435_malloc_stats_r (/* struct */ _reent* impure __attribute__ ((unused)))
436{
437 abort ();
438}
439
440size_t
441_malloc_usable_size_r (/* struct */ _reent* reent __attribute__ ((unused)),
442 void* ptr __attribute__ ((unused)))
443{
444 abort ();
445}
446
447int
448_mallopt_r (/* struct */ _reent* impure __attribute__ ((unused)),
449 int parameter_number __attribute__ ((unused)),
450 int parameter_value __attribute__ ((unused)))
451{
452 abort ();
453}
454
455void*
456_memalign_r (/* struct */ _reent* impure __attribute__ ((unused)),
457 size_t align __attribute__ ((unused)),
458 size_t s __attribute__ ((unused)))
459{
460 abort ();
461}
462
463void*
464_pvalloc_r (/* struct */ _reent* impure __attribute__ ((unused)),
465 size_t s __attribute__ ((unused)))
466{
467 abort ();
468}
469
470void*
471_valloc_r (/* struct */ _reent* impure __attribute__ ((unused)),
472 size_t s __attribute__ ((unused)))
473{
474 abort ();
475}
476
481// ----------------------------------------------------------------------------
482
483#endif /* defined(__ARM_EABI__) */
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:1312
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
Definition os-memory.h:1290
Scheduler critical section RAII helper.
Definition os-sched.h:171
void abort(void)
Definition exit.c:43
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
void * realloc(void *ptr, size_t bytes)
Reallocate the memory block (non-initialised).
Definition malloc.cpp:254
void * calloc(size_t nelem, size_t elbytes)
Allocate an array of memory blocks (initialised to zero).
Definition malloc.cpp:153
void * malloc(size_t bytes)
Allocate a memory block (non-initialised).
Definition malloc.cpp:84
void free(void *ptr)
Free the allocated memory block.
Definition malloc.cpp:347
memory_resource * get_default_resource(void) noexcept
Get the default application memory manager.
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1101
System namespace.
Single file µOS++ RTOS definitions.