[Heap] new api for user heap trace callbacks

This commit is contained in:
Chip Weinberger 2023-02-17 13:21:13 -08:00 committed by Mahavir Jain
parent 786851bfbd
commit 1588c61c7b
2 changed files with 100 additions and 8 deletions

View File

@ -31,7 +31,8 @@ possible. This should optimize the amount of RAM accessible to the code without
*/
static esp_alloc_failed_hook_t alloc_failed_callback;
static esp_heap_trace_alloc_hook_t trace_alloc_callback;
static esp_heap_trace_free_hook_t trace_free_callback;
#ifdef CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS
IRAM_ATTR static void hex_to_str(char buf[8], uint32_t n)
@ -99,6 +100,28 @@ esp_err_t heap_caps_register_failed_alloc_callback(esp_alloc_failed_hook_t callb
return ESP_OK;
}
esp_err_t heap_caps_register_trace_alloc_callback(esp_heap_trace_alloc_hook_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
trace_alloc_callback = callback;
return ESP_OK;
}
esp_err_t heap_caps_register_trace_free_callback(esp_heap_trace_free_hook_t callback)
{
if (callback == NULL) {
return ESP_ERR_INVALID_ARG;
}
trace_free_callback = callback;
return ESP_OK;
}
bool heap_caps_match(const heap_t *heap, uint32_t caps)
{
return heap->heap != NULL && ((get_all_caps(heap) & caps) == caps);
@ -188,6 +211,10 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps){
void* ptr = heap_caps_malloc_base(size, caps);
if (trace_alloc_callback) {
trace_alloc_callback(ptr, size);
}
if (!ptr && size > 0){
heap_caps_alloc_failed(size, caps, __func__);
}
@ -228,6 +255,11 @@ IRAM_ATTR void *heap_caps_malloc_default( size_t size )
r=heap_caps_malloc_base( size, MALLOC_CAP_DEFAULT );
}
// trace allocation
if (trace_alloc_callback) {
trace_alloc_callback(r, size);
}
// allocation failure?
if (r==NULL && size > 0){
heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, __func__);
@ -262,6 +294,11 @@ IRAM_ATTR void *heap_caps_realloc_default( void *ptr, size_t size )
r=heap_caps_realloc_base( ptr, size, MALLOC_CAP_DEFAULT);
}
// trace allocation
if (trace_alloc_callback) {
trace_alloc_callback(r, size);
}
// allocation failure?
if (r==NULL && size>0){
heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, __func__);
@ -286,6 +323,9 @@ IRAM_ATTR void *heap_caps_malloc_prefer( size_t size, size_t num, ... )
break;
}
}
if (trace_alloc_callback) {
trace_alloc_callback(r, size);
}
if (r == NULL && size > 0){
heap_caps_alloc_failed(size, caps, __func__);
}
@ -309,6 +349,9 @@ IRAM_ATTR void *heap_caps_realloc_prefer( void *ptr, size_t size, size_t num, ..
break;
}
}
if (trace_alloc_callback) {
trace_alloc_callback(r, size);
}
if (r == NULL && size > 0){
heap_caps_alloc_failed(size, caps, __func__);
}
@ -332,6 +375,9 @@ IRAM_ATTR void *heap_caps_calloc_prefer( size_t n, size_t size, size_t num, ...
break;
}
}
if (trace_alloc_callback) {
trace_alloc_callback(r, size);
}
if (r == NULL && size > 0){
heap_caps_alloc_failed(size, caps, __func__);
}
@ -374,6 +420,10 @@ IRAM_ATTR void heap_caps_free( void *ptr)
heap_t *heap = find_containing_heap(ptr);
assert(heap != NULL && "free() target pointer is outside heap areas");
multi_heap_free(heap->heap, ptr);
if (trace_free_callback) {
trace_free_callback(ptr);
}
}
/*
@ -458,6 +508,9 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, uint32_t caps)
{
ptr = heap_caps_realloc_base(ptr, size, caps);
if (trace_alloc_callback) {
trace_alloc_callback(ptr, size);
}
if (ptr == NULL && size > 0){
heap_caps_alloc_failed(size, caps, __func__);
}
@ -489,6 +542,9 @@ IRAM_ATTR void *heap_caps_calloc( size_t n, size_t size, uint32_t caps)
{
void* ptr = heap_caps_calloc_base(n, size, caps);
if (trace_alloc_callback) {
trace_alloc_callback(ptr, size);
}
if (!ptr && size > 0){
heap_caps_alloc_failed(size, caps, __func__);
}
@ -640,7 +696,7 @@ size_t heap_caps_get_allocated_size( void *ptr )
IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps)
{
void *ret = NULL;
void *ptr = NULL;
if(!alignment) {
return NULL;
@ -675,19 +731,24 @@ IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t
//doesn't cover, see if they're available in other prios.
if ((get_all_caps(heap) & caps) == caps) {
//Just try to alloc, nothing special.
ret = multi_heap_aligned_alloc(heap->heap, size, alignment);
if (ret != NULL) {
return ret;
ptr = multi_heap_aligned_alloc(heap->heap, size, alignment);
if (ptr != NULL) {
break;
}
}
}
}
}
if (trace_alloc_callback) {
trace_alloc_callback(ptr, size);
}
if (size > 0 && ptr != NULL) {
heap_caps_alloc_failed(size, caps, __func__);
}
//Nothing usable found.
return NULL;
return ptr;
}
IRAM_ATTR void heap_caps_aligned_free(void *ptr)

View File

@ -53,6 +53,37 @@ typedef void (*esp_alloc_failed_hook_t) (size_t size, uint32_t caps, const char
*/
esp_err_t heap_caps_register_failed_alloc_callback(esp_alloc_failed_hook_t callback);
/**
* @brief callback called after every allocation
* @param ptr the allocated memory
* @param size in bytes of the allocation
* @note this hook is called on the same thread as the allocation, which may be within a low level operation.
* You should refrain from doing heavy work, logging, flash writes, or any locking.
*/
typedef void (*esp_heap_trace_alloc_hook_t) (void* ptr, size_t size);
/**
* @brief registers a callback function to be invoked after every heap allocation
* @param callback caller defined callback to be invoked
* @return ESP_OK if callback was registered.
*/
esp_err_t heap_caps_register_trace_alloc_callback(esp_heap_trace_alloc_hook_t callback);
/**
* @brief callback called after every free
* @param ptr the memory that was freed
* @note this hook is called on the same thread as the allocation, which may be within a low level operation.
* You should refrain from doing heavy work, logging, flash writes, or any locking.
*/
typedef void (*esp_heap_trace_free_hook_t) (void* ptr);
/**
* @brief registers a callback function to be invoked after every heap allocation
* @param callback caller defined callback to be invoked
* @return ESP_OK if callback was registered.
*/
esp_err_t heap_caps_register_trace_free_callback(esp_heap_trace_free_hook_t callback);
/**
* @brief Allocate a chunk of memory which has the given capabilities
*