From: Simon Glass <simon.glass@canonical.com> Add counters to track the number of calls to malloc(), free(), and realloc(). These are displayed by the 'malloc info' command and accessible via malloc_get_info(). Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- cmd/malloc.c | 7 +++++-- common/dlmalloc.c | 18 ++++++++++++++++++ doc/usage/cmd/malloc.rst | 12 ++++++++---- include/malloc.h | 6 ++++++ test/cmd/malloc.c | 4 ++++ 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/cmd/malloc.c b/cmd/malloc.c index cb2fa34155b..3750a16158b 100644 --- a/cmd/malloc.c +++ b/cmd/malloc.c @@ -21,8 +21,11 @@ static int do_malloc_info(struct cmd_tbl *cmdtp, int flag, int argc, if (ret) return CMD_RET_FAILURE; - printf("total bytes = %s\n", format_size(buf, info.total_bytes)); - printf("in use bytes = %s\n", format_size(buf, info.in_use_bytes)); + printf("total bytes = %s\n", format_size(buf, info.total_bytes)); + printf("in use bytes = %s\n", format_size(buf, info.in_use_bytes)); + printf("malloc count = %lu\n", info.malloc_count); + printf("free count = %lu\n", info.free_count); + printf("realloc count = %lu\n", info.realloc_count); return 0; } diff --git a/common/dlmalloc.c b/common/dlmalloc.c index b0845e6ea7c..b8de42cc47e 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -646,6 +646,12 @@ ulong mem_malloc_start; ulong mem_malloc_end; ulong mem_malloc_brk; +#ifndef NO_MALLOC_STATS +static ulong malloc_count; +static ulong free_count; +static ulong realloc_count; +#endif /* !NO_MALLOC_STATS */ + #endif /* __UBOOT__ */ #ifndef SMALLCHUNKS_AS_FUNCS @@ -3699,6 +3705,9 @@ int malloc_get_info(struct malloc_info *info) info->total_bytes = mem_malloc_end - mem_malloc_start; info->in_use_bytes = mi.uordblks; + info->malloc_count = malloc_count; + info->free_count = free_count; + info->realloc_count = realloc_count; return 0; } @@ -4926,6 +4935,9 @@ void* dlmalloc_impl(size_t bytes) { if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) return malloc_simple(bytes); #endif +#if !NO_MALLOC_STATS + malloc_count++; +#endif /* Return NULL if not initialized yet */ if (!mem_malloc_start && !mem_malloc_end) @@ -5092,6 +5104,9 @@ void* dlmalloc_impl(size_t bytes) { STATIC_IF_MCHECK void dlfree_impl(void* mem) { #ifdef __UBOOT__ +#if !NO_MALLOC_STATS + free_count++; +#endif #if CONFIG_IS_ENABLED(SYS_MALLOC_F) /* free() is a no-op - all the memory will be freed on relocation */ if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { @@ -5662,6 +5677,9 @@ static void internal_inspect_all(mstate m, STATIC_IF_MCHECK void* dlrealloc_impl(void* oldmem, size_t bytes) { #ifdef __UBOOT__ +#if !NO_MALLOC_STATS + realloc_count++; +#endif #if CONFIG_IS_ENABLED(SYS_MALLOC_F) if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { /* This is harder to support and should not be needed */ diff --git a/doc/usage/cmd/malloc.rst b/doc/usage/cmd/malloc.rst index d21aa6c1421..7b08b358258 100644 --- a/doc/usage/cmd/malloc.rst +++ b/doc/usage/cmd/malloc.rst @@ -19,8 +19,9 @@ Description The malloc command shows information about the malloc heap. info - Shows memory-allocation statistics, including the total heap size and the - amount currently in use. + Shows memory-allocation statistics, including the total heap size, the + amount currently in use, and call counts for malloc(), free(), and + realloc(). The total heap size is set by ``CONFIG_SYS_MALLOC_LEN``. @@ -30,8 +31,11 @@ Example :: => malloc info - total bytes = 96 MiB - in use bytes = 700.9 KiB + total bytes = 96 MiB + in use bytes = 700.9 KiB + malloc count = 1234 + free count = 567 + realloc count = 89 Configuration ------------- diff --git a/include/malloc.h b/include/malloc.h index 7e276d444ab..0d8a2a43f2a 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -675,10 +675,16 @@ void mspace_inspect_all(mspace msp, * * @total_bytes: Total bytes available in the heap * @in_use_bytes: Current bytes allocated (in use by application) + * @malloc_count: Number of calls to malloc() + * @free_count: Number of calls to free() + * @realloc_count: Number of calls to realloc() */ struct malloc_info { ulong total_bytes; ulong in_use_bytes; + ulong malloc_count; + ulong free_count; + ulong realloc_count; }; /* Memory pool boundaries */ diff --git a/test/cmd/malloc.c b/test/cmd/malloc.c index 6cd52b68900..f9d41a36cad 100644 --- a/test/cmd/malloc.c +++ b/test/cmd/malloc.c @@ -19,10 +19,14 @@ static int cmd_test_malloc_info(struct unit_test_state *uts) ut_assertok(malloc_get_info(&info)); ut_assert(info.total_bytes >= CONFIG_SYS_MALLOC_LEN); ut_assert(info.in_use_bytes < info.total_bytes); + ut_assert(info.malloc_count > 0); ut_assertok(run_command("malloc info", 0)); ut_assert_nextlinen("total bytes = "); ut_assert_nextlinen("in use bytes = "); + ut_assert_nextlinen("malloc count = "); + ut_assert_nextlinen("free count = "); + ut_assert_nextlinen("realloc count = "); ut_assert_console_end(); return 0; -- 2.43.0