Compare commits

..

4 commits

3 changed files with 93 additions and 20 deletions

View file

@ -12,11 +12,18 @@ struct mb_header
typedef struct mb_header mb_header; typedef struct mb_header mb_header;
#define MB_HEADER_SIZE sizeof(mb_header)
static mb_header* root = NULL; static mb_header* root = NULL;
static mb_header* nomad = NULL; static mb_header* nomad = NULL;
#define AXL_ALIGNMENT 8
static inline u32 axl_align(u32 size)
{
return (size + (AXL_ALIGNMENT - 1)) & ~(AXL_ALIGNMENT - 1);
}
#define MB_HEADER_SIZE axl_align(sizeof(mb_header))
void* axl_memset(void* ptr, i8 c, u32 n) void* axl_memset(void* ptr, i8 c, u32 n)
{ {
if(ptr) if(ptr)
@ -46,7 +53,12 @@ void axl_init(void)
} }
} }
mb_header* axl_find_mb(u32 req_size) static inline mb_header* axl_get_mb_header(void* ptr)
{
return (mb_header*)((u8*)ptr - MB_HEADER_SIZE);
}
static mb_header* axl_find_mb(u32 req_size)
{ {
mb_header* block = nomad ? nomad : root; mb_header* block = nomad ? nomad : root;
mb_header* start = block; mb_header* start = block;
@ -76,28 +88,42 @@ mb_header* axl_find_mb(u32 req_size)
return NULL; return NULL;
} }
void axl_split_mb(mb_header* block, u32 size) static b8 axl_split_mb(mb_header* block, u32 size)
{ {
if(block->size > size + MB_HEADER_SIZE) if(block->size > size)
{ {
mb_header* new_block = (mb_header*)((u8*)block + MB_HEADER_SIZE + size); if(block->size - size >= MB_HEADER_SIZE + AXL_ALIGNMENT)
new_block->size = block->size - size - MB_HEADER_SIZE;
new_block->is_free = true;
new_block->next = block->next;
new_block->prev = block;
if(new_block->next)
{ {
new_block->next->prev = new_block; mb_header* new_block = (mb_header*)((u8*)block + MB_HEADER_SIZE + size);
} new_block->size = block->size - size - MB_HEADER_SIZE;
new_block->is_free = true;
new_block->next = block->next;
new_block->prev = block;
block->size = size; if(new_block->next)
block->next = new_block; {
new_block->next->prev = new_block;
}
block->size = size;
block->next = new_block;
return true;
}
} }
return false;
} }
void* axl_malloc(u32 size) void* axl_malloc(u32 size)
{ {
if(size == 0)
{
return NULL;
}
size = axl_align(size);
if(size > AXL_HEAP_SIZE - MB_HEADER_SIZE) if(size > AXL_HEAP_SIZE - MB_HEADER_SIZE)
{ {
return NULL; return NULL;
@ -122,6 +148,52 @@ void* axl_malloc(u32 size)
return (void*)((u8*)free_block + MB_HEADER_SIZE); return (void*)((u8*)free_block + MB_HEADER_SIZE);
} }
void* axl_memcpy(void* dst, const void* src, u32 count)
{
for(u32 i = 0; i < count; i++)
{
*((u8*)dst + i) = *((u8*)src + i);
}
return dst;
}
void* axl_realloc(void* ptr, u32 size)
{
if(size == 0)
{
axl_free(ptr);
return NULL;
}
size = axl_align(size);
if(!ptr)
{
return axl_malloc(size);
}
mb_header* old = axl_get_mb_header(ptr);
if(axl_split_mb(old, size))
{
return ptr;
}
void* new = axl_malloc(size);
if(!new)
{
return NULL;
}
size = size < old->size ? size : old->size;
axl_memcpy(new, ptr, size);
axl_free(ptr);
return new;
}
void axl_free(void* ptr) void axl_free(void* ptr)
{ {
if(!ptr) if(!ptr)
@ -129,7 +201,7 @@ void axl_free(void* ptr)
return; return;
} }
mb_header* block = (mb_header*)((u8*)ptr - MB_HEADER_SIZE); mb_header* block = axl_get_mb_header(ptr);
mb_header* next_block = block->next; mb_header* next_block = block->next;
mb_header* prev_block = block->prev; mb_header* prev_block = block->prev;
block->is_free = true; block->is_free = true;

View file

@ -9,6 +9,7 @@
void axl_init(void); void axl_init(void);
void* axl_malloc(u32 size); void* axl_malloc(u32 size);
void* axl_realloc(void* ptr, u32 size);
void* axl_memset(void* ptr, i8 c, u32 n); void* axl_memset(void* ptr, i8 c, u32 n);
void axl_free(void* ptr); void axl_free(void* ptr);

View file

@ -1,11 +1,11 @@
CC = clang CC = clang
CFLAGS = -Wall -Wextra -Werror -pedantic -std=c11 -nostdlib -static -Oz -ffreestanding CFLAGS = -Wall -Wextra -Werror -pedantic -std=c11 -nostdlib -static -Oz -ffreestanding
LDFLAGS = -Wl,/SUBSYSTEM:CONSOLE,/ENTRY:_start -fuse-ld=lld LDFLAGS = -Wl,/SUBSYSTEM:CONSOLE,/ENTRY:_start -fuse-ld=lld
LIBS = -lkernel32 -luser32 LIBS = -lkernel32
SOURCES = main.c axl_memory.c SOURCES = main.c axl_memory.c
TARGET = prog.exe TARGET = prog.exe
all: $(TARGET) all: clean $(TARGET)
$(TARGET): $(SOURCES) $(TARGET): $(SOURCES)
$(CC) $(CFLAGS) $(SOURCES) -o $(TARGET) $(LDFLAGS) $(LIBS) $(CC) $(CFLAGS) $(SOURCES) -o $(TARGET) $(LDFLAGS) $(LIBS)