Memory API

This commit is contained in:
flysand7 2023-07-28 21:49:56 +11:00
parent 9119be8e24
commit 3abf5e3f7f
9 changed files with 155 additions and 0 deletions

32
include/cia-mem.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
void *cia_ptr_alignf(void *ptr, u64 alignment);
void *cia_ptr_alignb(void *ptr, u64 alignment);
struct Cia_Allocator typedef Cia_Allocator;
struct Cia_Allocator {
void *ctx;
void *(*alloc)(void *ctx, u64 size);
void *(*alloc_a)(void *ctx, u64 size, u64 alignment);
void (*free)(void *ctx, void *ptr);
void (*free_all)(void *ctx, void *ptr);
void *(*realloc)(void *ctx, void *ptr, u64 new_size);
};
Cia_Allocator cia_allocator_null();
Cia_Allocator cia_allocator_pages();
struct Cia_Arena typedef Cia_Arena;
struct Cia_Arena {
Cia_Allocator allocator;
u64 buffer_size;
u64 used;
u8* buffer;
};
void cia_arena_create(Cia_Arena *arena, Cia_Allocator backing_allocator, u64 max_size);
void *cia_arena_alloc(Cia_Arena *arena, u64 size);
void *cia_arena_alloc_aligned(Cia_Arena *arena, u64 size, u64 align);
void cia_arena_free_all(Cia_Arena *arena);
void cia_arena_destroy(Cia_Arena *arena);

View File

@ -5,6 +5,7 @@
#define _RT_STATUS_OK 0 // No errors #define _RT_STATUS_OK 0 // No errors
#define _RT_ERROR_NOT_IMPLEMENTED -1 // Function not implemented #define _RT_ERROR_NOT_IMPLEMENTED -1 // Function not implemented
#define _RT_ERROR_BAD_PARAM -2 // One of the function parameters was wrong #define _RT_ERROR_BAD_PARAM -2 // One of the function parameters was wrong
#define _RT_ERROR_GENERIC -3 // Just any random error
// File API errors // File API errors
#define _RT_STATUS_FILE_ACCESS 1 // No access to the file #define _RT_STATUS_FILE_ACCESS 1 // No access to the file
@ -69,3 +70,9 @@ struct _RT_File {
static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written); static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written);
static _RT_Status _rt_file_close(_RT_File *file); static _RT_Status _rt_file_close(_RT_File *file);
#endif #endif
// Memory API
#if _RT_API_MEMORY == 1
static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 min_size, void **out_addr);
static _RT_Status _rt_mem_free(void *ptr);
#endif

View File

@ -0,0 +1,37 @@
Cia_Allocator cia_allocator_null() {
Cia_Allocator allocator = {
.ctx = NULL,
.alloc = NULL,
.alloc_a = NULL,
.free = NULL,
.free_all = NULL,
.realloc = NULL
};
return allocator;
}
static void *page_alloc(void *ctx, u64 size) {
void *addr;
_RT_Status status = _rt_mem_alloc(NULL, size, &addr);
if(status != _RT_STATUS_OK) {
return NULL;
}
return addr;
}
static void page_free(void *ptr) {
_rt_mem_free(ptr);
}
Cia_Allocator cia_allocator_pages() {
Cia_Allocator allocator = {
.ctx = NULL,
.alloc = page_alloc,
.alloc_a = NULL,
.free = page_free,
.free_all = NULL,
.realloc = NULL,
};
return allocator;
}

35
src/impl/cia-mem/arena.c Normal file
View File

@ -0,0 +1,35 @@
void cia_arena_create(Cia_Arena *arena, Cia_Allocator backing_allocator, u64 buffer_size) {
arena->allocator = backing_allocator;
arena->buffer_size = buffer_size;
arena->used = 0;
arena->buffer = arena->allocator.alloc(arena->allocator.ctx, buffer_size);
}
void *cia_arena_alloc(Cia_Arena *arena, u64 size) {
if(arena->used + size > arena->buffer_size) {
return NULL;
}
void *ptr = &arena->buffer[arena->used];
arena->used += arena->buffer_size;
return ptr;
}
void *cia_arena_alloc_aligned(Cia_Arena *arena, u64 size, u64 align) {
void *buffer_end = &arena->buffer[arena->buffer_size];
void *region_ptr = cia_ptr_alignf(&arena->buffer[arena->used], align);
void *region_end = (void *)((u64)region_ptr + size);
if(region_end > buffer_end) {
return NULL;
}
arena->used = (u64)region_ptr - (u64)arena->buffer;
return region_ptr;
}
void cia_arena_free_all(Cia_Arena *arena) {
arena->used = 0;
}
void cia_arena_destroy(Cia_Arena *arena) {
arena->allocator.free(arena->allocator.ctx, arena->buffer);
}

12
src/impl/cia-mem/util.c Normal file
View File

@ -0,0 +1,12 @@
void *cia_ptr_alignf(void *ptr, u64 alignment) {
u64 addr = (u64)ptr;
u64 aligned = (addr + alignment - 1) & ~(alignment - 1);
return (void *)aligned;
}
void *cia_ptr_alignb(void *ptr, u64 alignment) {
u64 addr = (u64)ptr;
u64 aligned = addr & ~(alignment - 1);
return (void *)aligned;
}

View File

@ -24,6 +24,7 @@
includes: [ includes: [
"stdlib.h", "stdlib.h",
"stdio.h", "stdio.h",
"cia-mem.h",
], ],
platforms: [ platforms: [
@ -53,6 +54,18 @@ platforms: [
], ],
apis: [ apis: [
{
name: "cia_memory",
path: "impl/cia-mem",
includes: [
"util.c",
"allocator.c",
"arena.c",
],
reqs: [
"rt_api_memory"
]
},
{ {
name: "stdlib_program", name: "stdlib_program",
path: "impl/stdlib-program", path: "impl/stdlib-program",

View File

@ -7,3 +7,4 @@
rt_api_file: true, rt_api_file: true,
rt_api_program: true, rt_api_program: true,
rt_api_shell: false, rt_api_shell: false,
rt_api_memory: false,

View File

@ -74,3 +74,20 @@ static _RT_Status _rt_file_close(_RT_File *file) {
__builtin_unreachable(); __builtin_unreachable();
} }
static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 min_size, void **out_addr) {
void *addr = VirtualAlloc(optional_desired_addr, min_size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
*out_addr = addr;
if(addr == NULL) {
return _RT_ERROR_GENERIC;
}
return _RT_STATUS_OK;
}
static _RT_Status _rt_mem_free(void *addr) {
BOOL ok = VirtualFree(addr, 0, MEM_RELEASE);
if(!ok) {
return _RT_ERROR_GENERIC;
}
return _RT_STATUS_OK;
}

View File

@ -6,3 +6,4 @@
rt_api_file: true, rt_api_file: true,
rt_api_program: true, rt_api_program: true,
rt_api_shell: false, rt_api_shell: false,
rt_api_memory: true,