mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cc907fa54e
The correct way to overrride the malloc family of functions in newlib-nano is to provide the *_r (reentrant) variants. Newlib implements the "normal" functions on top of these (see the newlib source code). Also, internally it calls the *_r functions when allocating buffers. If only the "normal" non-reentrant functions are provided this will mean that some of the code will still use the vanilla newlib allocator. Furthermore, if one uses the whole heap as a pool for TLSF then the system may in the best case crash as there is no enough memory for its internall allocations or in the worst case function eratically (this depends on how the heap reserved, there is an upcomming series of commits in that direction). This commit splits the handling between newlib and native. It also prepares the ground for future work on the pool initialization. Right now I could only test this in ARM and native and I cannot ensure it will work on other platforms. Replacing the system's memory allocator is not something that can be taken lightly and will inevitably require diving into the depths of the libc. Therefore I would say that using TLSF as a system wide allocator is ATM supported officially only on those plaftorms. Testing: Aside from reading the newlib sources, you can see the issue in a live system using the debugger. Compile any example (with or without tlsf-malloc), grab a debugger and place a breakpoint in sbrk and _sbrk_r. Doing a backtrace will reveal it gets called by _malloc_r.
102 lines
2.8 KiB
C
102 lines
2.8 KiB
C
/*
|
|
* Copyright (C) 2014-2018 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
/**
|
|
* @defgroup pkg_tlsf_malloc TLSF-based malloc.
|
|
* @ingroup pkg
|
|
* @ingroup sys_memory_management
|
|
*
|
|
* @brief TLSF-based global memory allocator.
|
|
*
|
|
* This is a malloc/free implementation built on top of the TLSF allocator.
|
|
* It defines a global tlsf_control block and performs allocations on that
|
|
* block. This implemetation replaces the system malloc
|
|
*
|
|
* Additionally, the calls to TLSF are wrapped in irq_disable()/irq_restore(),
|
|
* to make it thread-safe.
|
|
*
|
|
* If this module is used as the system memory allocator, then the global memory
|
|
* control block should be initialized as the first thing before the stdlib is
|
|
* used. Boards should use tlsf_add_global_pool() at startup to add all the memory
|
|
* regions they want to make available for dynamic allocation via malloc().
|
|
*
|
|
* @{
|
|
* @file
|
|
*
|
|
* @brief TLSF-based global memory allocator.
|
|
* @author René Kijewski
|
|
* @author Juan I Carrano
|
|
*
|
|
*/
|
|
|
|
#ifndef TLSF_MALLOC_H
|
|
#define TLSF_MALLOC_H
|
|
|
|
#include <stddef.h>
|
|
|
|
#include "tlsf.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Struct to hold the total sizes of free and used blocks
|
|
* Used for @ref tlsf_size_walker()
|
|
*/
|
|
typedef struct {
|
|
unsigned free; /**< total free size */
|
|
unsigned used; /**< total used size */
|
|
} tlsf_size_container_t;
|
|
|
|
/**
|
|
* Walk the memory pool to print all block sizes and to calculate
|
|
* the total amount of free and used block sizes.
|
|
*
|
|
* @note This function is passed to tlsf_walk_pool()
|
|
*
|
|
* @param ptr Pointer to the current block.
|
|
* @param size Size of the current block at @p ptr.
|
|
* @param used Shows whether the current block is used or free.
|
|
* @param user Custom data expected to be of type ``pointer to tlsf_size_container_t``
|
|
*/
|
|
void tlsf_size_walker(void* ptr, size_t size, int used, void* user);
|
|
|
|
/**
|
|
* Add an area of memory to the global allocator pool.
|
|
*
|
|
* The first time this function is called, it will automatically perform a
|
|
* tlsf_create() on the global tlsf_control block.
|
|
*
|
|
* @warning If this module is used, then this function MUST be called at least
|
|
* once, before any allocations take place.
|
|
*
|
|
* @param mem Pointer to memory area. Should be aligned to 4 bytes.
|
|
* @param bytes Size in bytes of the memory area.
|
|
*
|
|
* @return 0 on success, nonzero on failure.
|
|
*/
|
|
int tlsf_add_global_pool(void *mem, size_t bytes);
|
|
|
|
/**
|
|
* Get a pointer to the global tlsf_control block.
|
|
*
|
|
* Use for debugging purposes only.
|
|
*/
|
|
tlsf_t _tlsf_get_global_control(void);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* TLSF_MALLOC_H */
|
|
|
|
/**
|
|
* @}
|
|
*/
|