111 lines
2.6 KiB
Plaintext
111 lines
2.6 KiB
Plaintext
fn main() -> u32 {
|
|
|
|
let x: u32 = 0;
|
|
let y: u32 = &x;
|
|
|
|
let alloc: u32 = arena_create(512);
|
|
let ptr1: u32 = arena_alloc(alloc, 32);
|
|
let ptr2: u32 = arena_alloc(alloc, 32);
|
|
|
|
print_hex(alloc);
|
|
print_newline();
|
|
print_hex(ptr1);
|
|
print_newline();
|
|
print_hex(ptr2);
|
|
print_newline();
|
|
printnum(*ptr2);
|
|
print_newline();
|
|
*ptr2 = 42;
|
|
|
|
print_hex(ptr2);
|
|
print_newline();
|
|
printnum(*ptr2);
|
|
print_newline();
|
|
println("end");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Arena Allocator
|
|
// Supports multiple arenas that can be destroyed independently
|
|
// Much more practical than a simple bump allocator
|
|
|
|
// Global heap management
|
|
static heap_start: u32 = 0x30000;
|
|
static heap_end: u32 = 0x40000;
|
|
static heap_current: u32 = 0x30000;
|
|
|
|
// Arena structure (stored at the start of each arena):
|
|
// [0-3]: start_address (u32)
|
|
// [4-7]: current_position (u32)
|
|
// [8-11]: end_address (u32)
|
|
// Total header size: 12 bytes
|
|
|
|
// Create a new arena with given size
|
|
// Returns pointer to arena handle (or 0 if failed)
|
|
fn arena_create(size: u32) -> u32 {
|
|
let total_size: u32 = size + 12;
|
|
let arena_ptr: u32 = heap_current;
|
|
let new_current: u32 = arena_ptr + total_size;
|
|
|
|
// Check if we have space
|
|
if new_current > heap_end {
|
|
return 0;
|
|
}
|
|
|
|
// Calculate arena data region
|
|
let data_start: u32 = arena_ptr + 12;
|
|
let data_end: u32 = arena_ptr + total_size;
|
|
|
|
// Initialize arena header
|
|
// Note: In real implementation, you'd use pointer writes here
|
|
// For now, using placeholder comments:
|
|
*arena_ptr = data_start; // start_address
|
|
*(arena_ptr + 4) = data_start; // current_position
|
|
*(arena_ptr + 8) = data_end; // end_address
|
|
|
|
heap_current = new_current;
|
|
|
|
return arena_ptr;
|
|
}
|
|
|
|
// Allocate from an arena
|
|
// Returns pointer to allocated memory (or 0 if failed)
|
|
fn arena_alloc(arena: u32, size: u32) -> u32 {
|
|
// Read current position from arena
|
|
let current: u32 = *(arena + 4);
|
|
let end: u32 = *(arena + 8);
|
|
|
|
let new_current: u32 = current + size;
|
|
|
|
// Check if arena has space
|
|
if new_current > end {
|
|
return 0;
|
|
}
|
|
|
|
// Update current position in arena
|
|
*(arena + 4) = new_current;
|
|
|
|
return current;
|
|
}
|
|
|
|
// Destroy an arena (in bump allocator, this is a no-op)
|
|
// In a real allocator, you'd mark the memory as free
|
|
fn arena_destroy(arena: u32) {
|
|
// In a true allocator, mark memory as reusable
|
|
// For bump allocator, we can't reclaim memory
|
|
// unless we destroy ALL arenas and reset
|
|
return 0;
|
|
}
|
|
|
|
// Reset entire heap (destroys ALL arenas)
|
|
fn reset_all() {
|
|
heap_current = heap_start;
|
|
return 0;
|
|
}
|