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(-)
@@ -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;
}
@@ -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 */
@@ -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
-------------
@@ -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 */
@@ -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;