improved malloc
This commit is contained in:
parent
e5c428e6cf
commit
fd35ff3df7
|
@ -1,8 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
void heap_init();
|
||||
|
||||
void* malloc();
|
||||
void* malloc(size_t size);
|
||||
void free(void* ptr);
|
|
@ -30,7 +30,7 @@ char* ultoa(unsigned long number, char* string, int base)
|
|||
return string;
|
||||
}
|
||||
|
||||
char* buffer = (char*)malloc();
|
||||
char* buffer = (char*)malloc(1024);
|
||||
char* temp = buffer;
|
||||
|
||||
int i = 0;
|
||||
|
|
86
src/memory.c
86
src/memory.c
|
@ -1,14 +1,20 @@
|
|||
#include "memory.h"
|
||||
|
||||
#include "stdint.h"
|
||||
#include "io.h"
|
||||
#include "convert.h"
|
||||
|
||||
struct FreeBlock
|
||||
{
|
||||
size_t size;
|
||||
struct FreeBlock* next;
|
||||
};
|
||||
|
||||
struct Block
|
||||
{
|
||||
size_t size;
|
||||
void* data;
|
||||
};
|
||||
|
||||
#define HEAP_BASE ((void*)0x40000000)
|
||||
#define BLOCK_SIZE 4096
|
||||
#define MAGIC_NUMBER 0xDEADBEEF
|
||||
|
@ -17,54 +23,60 @@ static struct FreeBlock* head = (struct FreeBlock*)HEAP_BASE;
|
|||
|
||||
void heap_init()
|
||||
{
|
||||
head->next = NULL;
|
||||
head->next = head + sizeof(struct FreeBlock);
|
||||
head->size = 0;
|
||||
|
||||
head->next->next = NULL;
|
||||
head->next->size = -1;
|
||||
}
|
||||
|
||||
void* malloc()
|
||||
struct FreeBlock* find_free_block(struct FreeBlock** previous, size_t min_size)
|
||||
{
|
||||
void* block = (void*)head;
|
||||
|
||||
if(head->next == NULL)
|
||||
struct FreeBlock* block = head;
|
||||
while(block && min_size < block->size)
|
||||
{
|
||||
head += BLOCK_SIZE;
|
||||
head->next = NULL;
|
||||
*previous = block;
|
||||
block = block->next;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
size_t physicalSize = size + sizeof(size_t);
|
||||
struct Block* allocation = NULL;
|
||||
|
||||
struct FreeBlock* previous = head;
|
||||
struct FreeBlock* block = find_free_block(&previous, physicalSize);
|
||||
|
||||
allocation = (struct Block*)block;
|
||||
allocation->size = size;
|
||||
|
||||
if(block->size == physicalSize)
|
||||
{
|
||||
previous->next = block->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
head = head->next;
|
||||
struct FreeBlock* shrunkBlock = block + physicalSize;
|
||||
shrunkBlock->next = block->next;
|
||||
shrunkBlock->size = shrunkBlock->next - shrunkBlock;
|
||||
|
||||
previous->next = shrunkBlock;
|
||||
}
|
||||
|
||||
*(uint32_t*)block = MAGIC_NUMBER;
|
||||
return block + sizeof(uint32_t);
|
||||
return &(allocation->data);
|
||||
}
|
||||
|
||||
void free(void* ptr)
|
||||
{
|
||||
void* blockStart = ptr - sizeof(uint32_t);
|
||||
if(*(uint32_t*)blockStart != MAGIC_NUMBER)
|
||||
return;
|
||||
struct FreeBlock* block = (struct FreeBlock*)((size_t*)ptr - 1);
|
||||
|
||||
struct FreeBlock* previous = head;
|
||||
while(previous && (void*)previous->next < ptr)
|
||||
previous = previous->next;
|
||||
|
||||
if((struct FreeBlock*)blockStart < head)
|
||||
{
|
||||
struct FreeBlock* nextBlock = head->next;
|
||||
head = blockStart;
|
||||
head->next = nextBlock;
|
||||
return;
|
||||
}
|
||||
|
||||
struct FreeBlock* block = head;
|
||||
|
||||
while(block)
|
||||
{
|
||||
if(block < (struct FreeBlock*)blockStart && (struct FreeBlock*)blockStart < block->next)
|
||||
{
|
||||
struct FreeBlock* newBlock = (struct FreeBlock*)blockStart;
|
||||
newBlock->next = block->next;
|
||||
block->next = newBlock;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block = block->next;
|
||||
}
|
||||
previous->next = block;
|
||||
block->next = previous;
|
||||
}
|
Loading…
Reference in a new issue