µ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++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#if defined(__ARM_EABI__) || defined(__DOXYGEN__)
14
15// ----------------------------------------------------------------------------
16
17#if defined(OS_USE_OS_APP_CONFIG_H)
18#include <cmsis-plus/os-app-config.h>
19#endif
20
21#include <cmsis-plus/rtos/os.h>
23
24#include <malloc.h>
25
26// ----------------------------------------------------------------------------
27
28using namespace os;
29
30// ----------------------------------------------------------------------------
31
43// These library functions were modified to use the application
44// 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
150void*
151calloc (size_t nelem, size_t elbytes)
152{
154
155 errno = 0;
156 if (nelem == 0 || elbytes == 0)
157 {
158 return nullptr;
159 }
160
161 void* mem;
162 {
163 // ----- Begin of critical section --------------------------------------
165
166 mem = estd::pmr::get_default_resource ()->allocate (nelem * elbytes);
167
168#if defined(OS_TRACE_LIBC_MALLOC)
169 trace::printf ("::%s(%u,%u)=%p\n", __func__, nelem, elbytes, mem);
170#endif
171 // ----- End of critical section ----------------------------------------
172 }
173
174 if (mem != nullptr)
175 {
176 memset (mem, 0, nelem * elbytes);
177 }
178 else
179 {
180 errno = ENOMEM;
181 }
182
183 return mem;
184}
185
249void*
250realloc (void* ptr, size_t bytes)
251{
253
254 void* mem;
255
256 {
257 // ----- Begin of critical section --------------------------------------
259
260 errno = 0;
261 if (ptr == nullptr)
262 {
264#if defined(OS_TRACE_LIBC_MALLOC)
265 trace::printf ("::%s(%p,%u)=%p\n", __func__, ptr, bytes, mem);
266#endif
267 if (mem == nullptr)
268 {
269 errno = ENOMEM;
270 }
271 return mem;
272 }
273
274 if (bytes == 0)
275 {
277#if defined(OS_TRACE_LIBC_MALLOC)
278 trace::printf ("::%s(%p,%u)=0\n", __func__, ptr, bytes);
279#endif
280 return nullptr;
281 }
282
283#if 0
284 /* TODO: There is chance to shrink the chunk if newly requested
285 * size is much small */
286 if (nano_malloc_usable_size (RCALL ptr) >= bytes)
287 return ptr;
288#endif
289
291 if (mem != nullptr)
292 {
293 memcpy (mem, ptr, bytes);
295 }
296 else
297 {
298 errno = ENOMEM;
299 }
300
301#if defined(OS_TRACE_LIBC_MALLOC)
302 trace::printf ("::%s(%p,%u)=%p", __func__, ptr, bytes, mem);
303#endif
304 // ----- End of critical section ----------------------------------------
305 }
306
307 return mem;
308}
309
340void
341free (void* ptr)
342{
344
345 if (ptr == nullptr)
346 {
347 return;
348 }
349
350 // ----- Begin of critical section ------------------------------------------
352
353#if defined(OS_TRACE_LIBC_MALLOC)
354 trace::printf ("::%s(%p)\n", __func__, ptr);
355#endif
356
357 // Size unknown, pass 0.
359 // ----- End of critical section --------------------------------------------
360}
361
370// ----------------------------------------------------------------------------
371// Redirect impure functions to the implementation, to avoid including
372// weird newlib functions.
377void*
378_malloc_r (/* struct */_reent* impure __attribute__((unused)), size_t size)
379{
380 return malloc (size);
381}
382
383void*
384_calloc_r (/* struct */ _reent* impure __attribute__((unused)), size_t n, size_t elem)
385{
386 return calloc (n, elem);
387}
388
389void
390_free_r (/* struct */ _reent* impure __attribute__((unused)), void* ptr)
391{
392 free (ptr);
393}
394
395void*
396_realloc_r (/* struct */ _reent* impure __attribute__((unused)), void* ptr,
397 size_t size)
398{
399 return realloc (ptr, size);
400}
401
406// ----------------------------------------------------------------------------
407// Not really implemented, but present here to avoid including
408// weird newlib functions.
413#pragma GCC diagnostic push
414#if defined(__clang__)
415#elif defined(__GNUC__)
416#pragma GCC diagnostic ignored "-Waggregate-return"
417#endif
418
419struct mallinfo
420_mallinfo_r (/* struct */ _reent* impure __attribute__((unused)))
421{
422 abort ();
423}
424
425#pragma GCC diagnostic pop
426
427void
428_malloc_stats_r (/* struct */ _reent* impure __attribute__((unused)))
429{
430 abort ();
431}
432
433size_t
434_malloc_usable_size_r (/* struct */ _reent* reent __attribute__((unused)),
435 void* ptr __attribute__((unused)))
436{
437 abort ();
438}
439
440int
441_mallopt_r (/* struct */ _reent* impure __attribute__((unused)),
442 int parameter_number __attribute__((unused)),
443 int parameter_value __attribute__((unused)))
444{
445 abort ();
446}
447
448void*
449_memalign_r (/* struct */ _reent* impure __attribute__((unused)),
450 size_t align __attribute__((unused)),
451 size_t s __attribute__((unused)))
452{
453 abort ();
454}
455
456void*
457_pvalloc_r (/* struct */ _reent* impure __attribute__((unused)),
458 size_t s __attribute__((unused)))
459{
460 abort ();
461}
462
463void*
464_valloc_r (/* struct */ _reent* impure __attribute__((unused)),
465 size_t s __attribute__((unused)))
466{
467 abort ();
468}
469
474// ----------------------------------------------------------------------------
475
476#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:1311
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
Definition os-memory.h:1289
Scheduler critical section RAII helper.
Definition os-sched.h:170
void abort(void)
Definition exit.c:45
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
void * realloc(void *ptr, size_t bytes)
Reallocate the memory block (non-initialised).
Definition malloc.cpp:250
void * calloc(size_t nelem, size_t elbytes)
Allocate an array of memory blocks (initialised to zero).
Definition malloc.cpp:151
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:341
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:1108
System namespace.
Single file µOS++ RTOS definitions.