Files
Toooba/Tests/isa/CPrograms/malloc_simulation.c
2026-05-01 15:47:18 +01:00

98 lines
2.1 KiB
C

#include <stdint.h>
#include <stddef.h>
#define HEAP_SIZE 0x10000
extern uint8_t __malloc_start;
static uint8_t* heap = &__malloc_start;
typedef struct block {
size_t size;
int free;
struct block* next;
} block;
static block* free_list;
static intptr_t next_virtual = 0x10000000;
intptr_t compute_virtual_base() {
intptr_t v = next_virtual;
next_virtual += 0x1000; // or size
return v;
}
void mem_init() {
free_list = (block*)heap;
free_list->size = HEAP_SIZE - sizeof(block);
free_list->free = 1;
free_list->next = NULL;
}
void* my_malloc(size_t size) {
block* curr = free_list;
while (curr) {
if (curr->free && curr->size >= size) {
if (curr->size > size + sizeof(block)) {
block* newb =
(block*)((uint8_t*)curr + sizeof(block) + size);
newb->size = curr->size - size - sizeof(block);
newb->free = 1;
newb->next = curr->next;
curr->next = newb;
curr->size = size;
}
curr->free = 0;
// TODO: lift off delta to a earlier stage
void* phys = (uint8_t*)curr + sizeof(block);
// compute delta for this allocation
intptr_t delta = compute_virtual_base() - (intptr_t)phys;
// apply hardware instruction assumption:
asm volatile("add_delta %0, %0, %1"
: "+r"(phys)
: "r"(delta));
return phys;
}
curr = curr->next;
}
return NULL;
}
void my_free(void* ptr) {
if (!ptr) return;
// delta is guaranteed 0 → treat pointer as physical
block* b = (block*)((uint8_t*)ptr - sizeof(block));
b->free = 1;
// coalesce adjacent free blocks (pure physical heap logic)
block* curr = free_list;
while (curr && curr->next) {
if (curr->free && curr->next->free) {
curr->size += sizeof(block) + curr->next->size;
curr->next = curr->next->next;
} else {
curr = curr->next;
}
}
}