|
|
|
|
@ -50,6 +50,8 @@ static void init_mutex() {
|
|
|
|
|
|
|
|
|
|
static void* allocated_head = NULL; |
|
|
|
|
static size_t allocated_count = 0; |
|
|
|
|
static size_t allocations_count = 0; |
|
|
|
|
static size_t frees_count = 0; |
|
|
|
|
|
|
|
|
|
static void hex_dump(const void* mem, size_t len) { |
|
|
|
|
const uint8_t* data = (const uint8_t*)mem; |
|
|
|
|
@ -138,6 +140,7 @@ void* u_malloc_impl(uint32_t size, const char* location) {
|
|
|
|
|
*next_ptr = allocated_head; |
|
|
|
|
allocated_head = base; |
|
|
|
|
allocated_count++; |
|
|
|
|
allocations_count++; |
|
|
|
|
UNLOCK(); |
|
|
|
|
return prefix_start + BOUNDARY_CHECK_SIZE + 8; |
|
|
|
|
} |
|
|
|
|
@ -183,6 +186,7 @@ void u_free_impl(void* ptr, const char* location) {
|
|
|
|
|
allocated_head = *(void**)((uint8_t*)curr + NEXT_OFFSET); |
|
|
|
|
} |
|
|
|
|
allocated_count--; |
|
|
|
|
frees_count++; |
|
|
|
|
found = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
@ -205,11 +209,22 @@ char* u_strdup_impl(const char* s, const char* location) {
|
|
|
|
|
return copy; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void u_mem_get_counters(size_t* allocations, size_t* frees, size_t* allocated) { |
|
|
|
|
LOCK(); |
|
|
|
|
if (allocations) *allocations = allocations_count; |
|
|
|
|
if (frees) *frees = frees_count; |
|
|
|
|
if (allocated) *allocated = allocated_count; |
|
|
|
|
UNLOCK(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void u_report_unfreed_blocks(void) { |
|
|
|
|
LOCK(); |
|
|
|
|
size_t count = allocated_count; |
|
|
|
|
void* head = allocated_head; |
|
|
|
|
size_t alloc_count = allocations_count; |
|
|
|
|
size_t free_count = frees_count; |
|
|
|
|
UNLOCK(); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "Memory stats: allocations=%zu, frees=%zu, current=%zu", alloc_count, free_count, count); |
|
|
|
|
if (count == 0) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "No unfreed memory blocks."); |
|
|
|
|
return; |
|
|
|
|
|