Skip to content

Add overhead count in heap stats #7917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions TESTS/mbed_platform/stats_heap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ void test_case_malloc_free_size()
TEST_ASSERT_EQUAL_UINT32(stats_start.total_size + ALLOCATION_SIZE_DEFAULT * (i + 1), stats_current.total_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt + 1, stats_current.alloc_cnt);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);

// Library header 0x4-0x8, stats header 0x8 and alignment addition 0x4
TEST_ASSERT_INT_WITHIN(0x8, stats_start.overhead_size + 0xC , stats_current.overhead_size);
// Free memory and assert back to starting size
free(data);
mbed_stats_heap_get(&stats_current);
TEST_ASSERT_EQUAL_UINT32(stats_start.current_size, stats_current.current_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.overhead_size, stats_current.overhead_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt, stats_current.alloc_cnt);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);
}
Expand All @@ -93,10 +95,14 @@ void test_case_allocate_zero()
TEST_ASSERT_EQUAL_UINT32(stats_start.current_size, stats_current.current_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.total_size, stats_current.total_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);

// Library header 0x4-0x8, stats header 0x8 and alignment addition 0x4
if (NULL != data) {
TEST_ASSERT_INT_WITHIN(0x8, stats_start.overhead_size + 0xC , stats_current.overhead_size);
}
// Free memory and assert back to starting size
free(data);
mbed_stats_heap_get(&stats_current);
TEST_ASSERT_EQUAL_UINT32(stats_start.overhead_size, stats_current.overhead_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.current_size, stats_current.current_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt, stats_current.alloc_cnt);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);
Expand All @@ -121,6 +127,7 @@ void test_case_allocate_fail()
TEST_ASSERT_EQUAL_UINT32(stats_start.total_size, stats_current.total_size);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt, stats_current.alloc_cnt);
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt + i + 1, stats_current.alloc_fail_cnt);
TEST_ASSERT_EQUAL_UINT32(stats_start.overhead_size, stats_current.overhead_size);
}
}

Expand Down
28 changes: 22 additions & 6 deletions platform/mbed_alloc_wrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ typedef struct {

#ifdef MBED_HEAP_STATS_ENABLED
static SingletonPtr<PlatformMutex> malloc_stats_mutex;
static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0};
static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0, 0, 0};

typedef struct {
size_t size;
}mbed_heap_overhead_t;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this apply to all allocators or just one particular library? dlmalloc based?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not apply to all allocators. But tested with dlmalloc and all three tool chains

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which from Mbed OS point of view is "all"

Thanks..


#define MALLOC_HEADER_SIZE (sizeof(mbed_heap_overhead_t))
#define MALLOC_HEADER_PTR(p) (mbed_heap_overhead_t *)((char *)(p) - MALLOC_HEADER_SIZE)
#define MALLOC_HEAP_TOTAL_SIZE(p) (((p)->size) & (~0x1))
#endif

void mbed_stats_heap_get(mbed_stats_heap_t *stats)
Expand All @@ -71,7 +79,6 @@ void mbed_stats_heap_get(mbed_stats_heap_t *stats)

#if defined(TOOLCHAIN_GCC)


extern "C" {
void *__real__malloc_r(struct _reent *r, size_t size);
void *__real__memalign_r(struct _reent *r, size_t alignment, size_t bytes);
Expand Down Expand Up @@ -106,6 +113,7 @@ extern "C" void *malloc_wrapper(struct _reent *r, size_t size, void *caller)
if (heap_stats.current_size > heap_stats.max_size) {
heap_stats.max_size = heap_stats.current_size;
}
heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size;
} else {
heap_stats.alloc_fail_cnt += 1;
}
Expand Down Expand Up @@ -178,10 +186,14 @@ extern "C" void free_wrapper(struct _reent *r, void *ptr, void *caller)
alloc_info_t *alloc_info = NULL;
if (ptr != NULL) {
alloc_info = ((alloc_info_t *)ptr) - 1;
heap_stats.current_size -= alloc_info->size;
size_t user_size = alloc_info->size;
size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info));
heap_stats.current_size -= user_size;
heap_stats.alloc_cnt -= 1;
heap_stats.overhead_size -= (alloc_size - user_size);
}
__real__free_r(r, (void *)alloc_info);

malloc_stats_mutex->unlock();
#else // #ifdef MBED_HEAP_STATS_ENABLED
__real__free_r(r, ptr);
Expand Down Expand Up @@ -260,7 +272,6 @@ extern "C" {
void free_wrapper(void *ptr, void *caller);
}


extern "C" void *SUB_MALLOC(size_t size)
{
return malloc_wrapper(size, MBED_CALLER_ADDR());
Expand All @@ -284,6 +295,7 @@ extern "C" void *malloc_wrapper(size_t size, void *caller)
if (heap_stats.current_size > heap_stats.max_size) {
heap_stats.max_size = heap_stats.current_size;
}
heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size;
} else {
heap_stats.alloc_fail_cnt += 1;
}
Expand Down Expand Up @@ -322,7 +334,7 @@ extern "C" void *SUB_REALLOC(void *ptr, size_t size)

// If the new buffer has been allocated copy the data to it
// and free the old buffer
if (new_ptr != NULL) {
if ((new_ptr != NULL) && (ptr != NULL)) {
uint32_t copy_size = (old_size < size) ? old_size : size;
memcpy(new_ptr, (void *)ptr, copy_size);
free(ptr);
Expand Down Expand Up @@ -374,10 +386,14 @@ extern "C" void free_wrapper(void *ptr, void *caller)
alloc_info_t *alloc_info = NULL;
if (ptr != NULL) {
alloc_info = ((alloc_info_t *)ptr) - 1;
heap_stats.current_size -= alloc_info->size;
size_t user_size = alloc_info->size;
size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info));
heap_stats.current_size -= user_size;
heap_stats.alloc_cnt -= 1;
heap_stats.overhead_size -= (alloc_size - user_size);
}
SUPER_FREE((void *)alloc_info);

malloc_stats_mutex->unlock();
#else // #ifdef MBED_HEAP_STATS_ENABLED
SUPER_FREE(ptr);
Expand Down
1 change: 1 addition & 0 deletions platform/mbed_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ typedef struct {
uint32_t reserved_size; /**< Current number of bytes allocated for the heap. */
uint32_t alloc_cnt; /**< Current number of allocations. */
uint32_t alloc_fail_cnt; /**< Number of failed allocations. */
uint32_t overhead_size; /**< Overhead added to heap for stats. */
} mbed_stats_heap_t;

/**
Expand Down