Skip to content

Commit d30ba6b

Browse files
committed
Fix malloc internal overhead size calculation for newlib and newlib-nano
1 parent 1950ac6 commit d30ba6b

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

platform/source/mbed_alloc_wrappers.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,44 @@ typedef struct {
5252
static SingletonPtr<PlatformMutex> malloc_stats_mutex;
5353
static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0, 0, 0};
5454

55+
#if defined(TOOLCHAIN_GCC)
56+
57+
typedef struct malloc_internal_overhead {
58+
/* ------------------
59+
* malloc_internal_overhead_t->| size (4 bytes) |
60+
* ------------------
61+
* | Padding for |
62+
* | alignment |
63+
* | holding neg |
64+
* | offset to size |
65+
* ------------------
66+
* mem_ptr->| point to next |
67+
* | free when freed|
68+
* | or data load |
69+
* | when allocated |
70+
* ------------------
71+
*/
72+
/* size of the allocated payload area, including size before
73+
OVERHEAD_OFFSET */
74+
int size;
75+
76+
/* since here, the memory is either the next free block, or data load */
77+
struct malloc_internal_overhead *next;
78+
} malloc_internal_overhead_t;
79+
80+
#define OVERHEAD_OFFSET ((size_t)(&(((struct malloc_internal_overhead *)0)->next)))
81+
82+
static int get_malloc_internal_overhead(void *ptr)
83+
{
84+
malloc_internal_overhead_t *c = (malloc_internal_overhead_t *)((char *)ptr - OVERHEAD_OFFSET);
85+
86+
/* Skip the padding area */
87+
if (c->size < 0) {
88+
c = (malloc_internal_overhead_t *)((char *)c + c->size);
89+
}
90+
return (c->size & ~0x1);
91+
}
92+
#else
5593
typedef struct {
5694
size_t size;
5795
} mbed_heap_overhead_t;
@@ -60,7 +98,7 @@ typedef struct {
6098
#define MALLOC_HEADER_PTR(p) (mbed_heap_overhead_t *)((char *)(p) - MALLOC_HEADER_SIZE)
6199
#define MALLOC_HEAP_TOTAL_SIZE(p) (((p)->size) & (~0x1))
62100
#endif
63-
101+
#endif
64102
void mbed_stats_heap_get(mbed_stats_heap_t *stats)
65103
{
66104
#if MBED_HEAP_STATS_ENABLED
@@ -116,7 +154,7 @@ extern "C" void *malloc_wrapper(struct _reent *r, size_t size, void *caller)
116154
if (heap_stats.current_size > heap_stats.max_size) {
117155
heap_stats.max_size = heap_stats.current_size;
118156
}
119-
heap_stats.overhead_size += MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info)) - size;
157+
heap_stats.overhead_size += get_malloc_internal_overhead((void *)alloc_info) - size;
120158
} else {
121159
heap_stats.alloc_fail_cnt += 1;
122160
}
@@ -191,7 +229,7 @@ extern "C" void free_wrapper(struct _reent *r, void *ptr, void *caller)
191229
alloc_info = ((alloc_info_t *)ptr) - 1;
192230
if (MBED_HEAP_STATS_SIGNATURE == alloc_info->signature) {
193231
size_t user_size = alloc_info->size;
194-
size_t alloc_size = MALLOC_HEAP_TOTAL_SIZE(MALLOC_HEADER_PTR(alloc_info));
232+
size_t alloc_size = get_malloc_internal_overhead((void *)alloc_info);
195233
alloc_info->signature = 0x0;
196234
heap_stats.current_size -= user_size;
197235
heap_stats.alloc_cnt -= 1;

0 commit comments

Comments
 (0)