heap: add functions to get heap runtime statistics

add functions to get the sys_heap runtime statistics,
include total free bytes, total allocated bytes.

Signed-off-by: Chen Peng1 <peng1.chen@intel.com>
This commit is contained in:
Chen Peng1 2021-10-29 15:49:07 +08:00 committed by Anas Nashif
commit a71cd8790f
5 changed files with 75 additions and 0 deletions

View file

@ -61,6 +61,25 @@ struct z_heap_stress_result {
uint64_t accumulated_in_use_bytes; uint64_t accumulated_in_use_bytes;
}; };
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
struct sys_heap_runtime_stats {
size_t free_bytes;
size_t allocated_bytes;
};
/**
* @brief Get the runtime statistics of a sys_heap
*
* @param heap Pointer to specified sys_heap
* @param stats_t Pointer to struct to copy statistics into
* @return -EINVAL if null pointers, otherwise 0
*/
int sys_heap_runtime_stats_get(struct sys_heap *heap,
struct sys_heap_runtime_stats *stats);
#endif
/** @brief Initialize sys_heap /** @brief Initialize sys_heap
* *
* Initializes a sys_heap struct to manage the specified memory. * Initializes a sys_heap struct to manage the specified memory.

View file

@ -46,6 +46,11 @@ config SYS_HEAP_ALLOC_LOOPS
keeps the maximum runtime at a tight bound so that the heap keeps the maximum runtime at a tight bound so that the heap
is useful in locked or ISR contexts. is useful in locked or ISR contexts.
config SYS_HEAP_RUNTIME_STATS
bool "System heap runtime statistics"
help
Gather system heap runtime statistics.
choice choice
prompt "Supported heap sizes" prompt "Supported heap sizes"
depends on !64BIT depends on !64BIT

View file

@ -386,3 +386,20 @@ void sys_heap_print_info(struct sys_heap *heap, bool dump_chunks)
{ {
heap_print_info(heap->heap, dump_chunks); heap_print_info(heap->heap, dump_chunks);
} }
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
int sys_heap_runtime_stats_get(struct sys_heap *heap,
struct sys_heap_runtime_stats *stats)
{
if ((heap == NULL) || (stats == NULL)) {
return -EINVAL;
}
stats->free_bytes = heap->heap->free_bytes;
stats->allocated_bytes = heap->heap->allocated_bytes;
return 0;
}
#endif

View file

@ -38,6 +38,10 @@ static void free_list_remove_bidx(struct z_heap *h, chunkid_t c, int bidx)
set_next_free_chunk(h, first, second); set_next_free_chunk(h, first, second);
set_prev_free_chunk(h, second, first); set_prev_free_chunk(h, second, first);
} }
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->free_bytes -= chunksz_to_bytes(h, chunk_size(h, c));
#endif
} }
static void free_list_remove(struct z_heap *h, chunkid_t c) static void free_list_remove(struct z_heap *h, chunkid_t c)
@ -72,6 +76,10 @@ static void free_list_add_bidx(struct z_heap *h, chunkid_t c, int bidx)
set_next_free_chunk(h, first, c); set_next_free_chunk(h, first, c);
set_prev_free_chunk(h, second, c); set_prev_free_chunk(h, second, c);
} }
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->free_bytes += chunksz_to_bytes(h, chunk_size(h, c));
#endif
} }
static void free_list_add(struct z_heap *h, chunkid_t c) static void free_list_add(struct z_heap *h, chunkid_t c)
@ -164,6 +172,9 @@ void sys_heap_free(struct sys_heap *heap, void *mem)
mem); mem);
set_chunk_used(h, c, false); set_chunk_used(h, c, false);
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->allocated_bytes -= chunksz_to_bytes(h, chunk_size(h, c));
#endif
free_chunk(h, c); free_chunk(h, c);
} }
@ -251,6 +262,9 @@ void *sys_heap_alloc(struct sys_heap *heap, size_t bytes)
} }
set_chunk_used(h, c, true); set_chunk_used(h, c, true);
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->allocated_bytes += chunksz_to_bytes(h, chunk_size(h, c));
#endif
return chunk_mem(h, c); return chunk_mem(h, c);
} }
@ -318,6 +332,9 @@ void *sys_heap_aligned_alloc(struct sys_heap *heap, size_t align, size_t bytes)
} }
set_chunk_used(h, c, true); set_chunk_used(h, c, true);
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->allocated_bytes += chunksz_to_bytes(h, chunk_size(h, c));
#endif
return mem; return mem;
} }
@ -353,6 +370,10 @@ void *sys_heap_aligned_realloc(struct sys_heap *heap, void *ptr,
return ptr; return ptr;
} else if (chunk_size(h, c) > chunks_need) { } else if (chunk_size(h, c) > chunks_need) {
/* Shrink in place, split off and free unused suffix */ /* Shrink in place, split off and free unused suffix */
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->allocated_bytes -=
(chunk_size(h, c) - chunks_need) * CHUNK_UNIT;
#endif
split_chunks(h, c, c + chunks_need); split_chunks(h, c, c + chunks_need);
set_chunk_used(h, c, true); set_chunk_used(h, c, true);
free_chunk(h, c + chunks_need); free_chunk(h, c + chunks_need);
@ -362,6 +383,10 @@ void *sys_heap_aligned_realloc(struct sys_heap *heap, void *ptr,
/* Expand: split the right chunk and append */ /* Expand: split the right chunk and append */
chunkid_t split_size = chunks_need - chunk_size(h, c); chunkid_t split_size = chunks_need - chunk_size(h, c);
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->allocated_bytes += split_size * CHUNK_UNIT;
#endif
free_list_remove(h, rc); free_list_remove(h, rc);
if (split_size < chunk_size(h, rc)) { if (split_size < chunk_size(h, rc)) {
@ -415,6 +440,11 @@ void sys_heap_init(struct sys_heap *heap, void *mem, size_t bytes)
h->end_chunk = heap_sz; h->end_chunk = heap_sz;
h->avail_buckets = 0; h->avail_buckets = 0;
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
h->free_bytes = 0;
h->allocated_bytes = 0;
#endif
int nb_buckets = bucket_idx(h, heap_sz) + 1; int nb_buckets = bucket_idx(h, heap_sz) + 1;
chunksz_t chunk0_size = chunksz(sizeof(struct z_heap) + chunksz_t chunk0_size = chunksz(sizeof(struct z_heap) +
nb_buckets * sizeof(struct z_heap_bucket)); nb_buckets * sizeof(struct z_heap_bucket));

View file

@ -69,6 +69,10 @@ struct z_heap {
chunkid_t chunk0_hdr[2]; chunkid_t chunk0_hdr[2];
chunkid_t end_chunk; chunkid_t end_chunk;
uint32_t avail_buckets; uint32_t avail_buckets;
#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS
size_t free_bytes;
size_t allocated_bytes;
#endif
struct z_heap_bucket buckets[0]; struct z_heap_bucket buckets[0];
}; };