94 lines
2.4 KiB
C
94 lines
2.4 KiB
C
#include "heap4_common.h"
|
|
|
|
#define HEAP_BYTES 192U
|
|
#define MIN_SPLIT_SIZE ((size_t)(sizeof(HeapBlock) * 2U))
|
|
|
|
static uint8_t heap_area[HEAP_BYTES + HEAP4_ALIGNMENT];
|
|
static HeapBlock start;
|
|
static HeapBlock *end_marker;
|
|
|
|
volatile size_t g_allocated_size;
|
|
volatile size_t g_split_free_size;
|
|
volatile int g_free_nodes;
|
|
|
|
static void heap_init_one_block(void)
|
|
{
|
|
uintptr_t aligned;
|
|
HeapBlock *first;
|
|
|
|
aligned = heap4_align_address((uintptr_t)&heap_area[0]);
|
|
first = (HeapBlock *)aligned;
|
|
end_marker = (HeapBlock *)(aligned + 176U);
|
|
end_marker->next = 0;
|
|
end_marker->size = 0U;
|
|
first->next = end_marker;
|
|
first->size = (uint8_t *)end_marker - (uint8_t *)first;
|
|
start.next = first;
|
|
start.size = 0U;
|
|
}
|
|
|
|
static void *heap_malloc_split(size_t wanted)
|
|
{
|
|
HeapBlock *previous;
|
|
HeapBlock *block;
|
|
HeapBlock *remainder;
|
|
size_t total;
|
|
size_t original;
|
|
|
|
total = heap4_align_up(wanted + sizeof(HeapBlock));
|
|
previous = &start;
|
|
block = start.next;
|
|
|
|
while (block != end_marker) {
|
|
if (block->size >= total) {
|
|
original = block->size;
|
|
if (original - total > MIN_SPLIT_SIZE) {
|
|
remainder = (HeapBlock *)((uint8_t *)block + total);
|
|
remainder->size = original - total;
|
|
remainder->next = block->next;
|
|
previous->next = remainder;
|
|
block->size = total;
|
|
} else {
|
|
previous->next = block->next;
|
|
}
|
|
block->next = 0;
|
|
block->size = heap4_mark_allocated(block->size);
|
|
return (uint8_t *)block + sizeof(HeapBlock);
|
|
}
|
|
previous = block;
|
|
block = block->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int count_free_nodes(void)
|
|
{
|
|
HeapBlock *block;
|
|
int count;
|
|
|
|
count = 0;
|
|
for (block = start.next; block != end_marker; block = block->next)
|
|
count++;
|
|
return count;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
void *p;
|
|
HeapBlock *allocated;
|
|
|
|
heap_init_one_block();
|
|
p = heap_malloc_split(32U);
|
|
allocated = (HeapBlock *)((uint8_t *)p - sizeof(HeapBlock));
|
|
|
|
g_allocated_size = heap4_clear_allocated(allocated->size);
|
|
g_split_free_size = start.next->size;
|
|
g_free_nodes = count_free_nodes();
|
|
|
|
TRACE_PRINTF("allocated=%u split=%u nodes=%d\n",
|
|
(unsigned)g_allocated_size, (unsigned)g_split_free_size,
|
|
g_free_nodes);
|
|
return 0;
|
|
}
|