From 98ee2b701f825b73cb44c35a9ec4c930b9057f56 Mon Sep 17 00:00:00 2001 From: rhuibertsjr Date: Sat, 27 Apr 2024 11:03:30 +0200 Subject: [PATCH] Added: project layout --- .gitignore | 1 + build.bat | 13 +++++++ docs/CHANGELOG | 3 ++ src/arena.c | 91 ++++++++++++++++++++++++++++++++++++++++++++ src/arena.h | 40 +++++++++++++++++++ src/base.h | 49 ++++++++++++++++++++++++ src/main.c | 17 +++++++++ src/win32_platform.c | 35 +++++++++++++++++ src/win32_platform.h | 17 +++++++++ start.bat | 9 +++++ 10 files changed, 275 insertions(+) create mode 100644 .gitignore create mode 100644 build.bat create mode 100644 docs/CHANGELOG create mode 100644 src/arena.c create mode 100644 src/arena.h create mode 100644 src/base.h create mode 100644 src/main.c create mode 100644 src/win32_platform.c create mode 100644 src/win32_platform.h create mode 100644 start.bat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..ebf9b4b --- /dev/null +++ b/build.bat @@ -0,0 +1,13 @@ +@echo off +setlocal +pushd "%~dp0" + +if not exist ".\build" mkdir ".\build" + +pushd .\build + +set link= user32.lib + +cl /Zi /W4 ..\src\main.c /Feapp.exe /Od /nologo /link %link% + +popd .\build diff --git a/docs/CHANGELOG b/docs/CHANGELOG new file mode 100644 index 0000000..17a3ffe --- /dev/null +++ b/docs/CHANGELOG @@ -0,0 +1,3 @@ +27-04-2024 René Huiberts + + Added: project layout diff --git a/src/arena.c b/src/arena.c new file mode 100644 index 0000000..edc7a29 --- /dev/null +++ b/src/arena.c @@ -0,0 +1,91 @@ +internal Arena * +arena_initialize(u64 size, b8 growable) +{ + Arena *result = 0; + void *backing_buffer = platform_memory_reserve(size); + + if (backing_buffer != NULL) + { + platform_memory_commit(backing_buffer, ARENA_INITIAL_COMMIT_SIZE); + + result = (Arena*) backing_buffer; + result->backing_buffer = backing_buffer; + result->current = result; + + // rhjr: immutable arena header + result->base_pos = + memory_align_power_of_two(sizeof(Arena), ARENA_DEFAULT_ALIGNMENT); + result->offset = result->base_pos; + + result->growable = growable; + result->size = size; + } + + // rhjr: arenas should be instantiated early on in the programs lifetime, that + // is why this assertion will also be used in production. + ASSERT(result != 0); + return result; +} + +internal Arena * +arena_initialize_default() +{ + Arena *result = arena_initialize(ARENA_DEFAULT_RESERVE_SIZE, 1); + return result; +} + +internal void * +arena_allocate(Arena *arena, u64 size) +{ + Arena *current = arena->current; + u64 pos_mem = + memory_align_power_of_two(current->offset, ARENA_DEFAULT_ALIGNMENT); + u64 pos_new = current->offset + size; + + if (current->size < pos_new && current->growable) + { + Arena *new_memory_bock; + + if (size > ARENA_DEFAULT_RESERVE_SIZE) + { + // rhjr: TODO add support for allocations larger then a single page, in a + // single allocation call. + ASSERT(0); + } + else + { + new_memory_bock = arena_initialize_default(); + + if (new_memory_bock) + { + sll_stack_push(arena->current, new_memory_bock, prev); + + current = new_memory_bock; + + pos_mem = + memory_align_power_of_two(current->offset, ARENA_DEFAULT_ALIGNMENT); + pos_new = current->offset + size; + } + + } + + } + + void *memory = (void*)((u64) current->backing_buffer + pos_mem); + arena->offset = pos_new; + + platform_memory_commit(memory, size); + memset(memory, 0, size); + + return memory; +} + +internal void +arena_release(Arena *arena) +{ + for (Arena *node = arena->current, *prev = 0; node != 0; node = prev) + { + prev = node->prev; + platform_memory_release(node, node->size); + } +} diff --git a/src/arena.h b/src/arena.h new file mode 100644 index 0000000..d09a304 --- /dev/null +++ b/src/arena.h @@ -0,0 +1,40 @@ +#ifndef ARENA_H +#define ARENA_H + +#define ARENA_INITIAL_COMMIT_SIZE sizeof(struct Arena) +#define ARENA_DEFAULT_ALIGNMENT 8 + +#ifndef ARENA_DEFAULT_RESERVE_SIZE +# define ARENA_DEFAULT_RESERVE_SIZE KB(4) +#endif // ARENA_DEFAULT_RESERVE_SIZE + +typedef struct Arena Arena; +struct Arena { + struct Arena *current; + struct Arena *prev; + u64 *backing_buffer; + u64 base_pos; + u64 offset; + u64 size; + b8 growable; +}; + +STATIC_ASSERT(ARENA_INITIAL_COMMIT_SIZE <= ARENA_DEFAULT_RESERVE_SIZE, + arena_default_allocation_size); + +//= rhjr: arenas + +internal Arena * arena_initialize(u64 size, b8 growable); +internal Arena * arena_initialize_default(); + +internal void * arena_allocate(Arena *arena, u64 size); + +#define arena_push_array(arena, type, count) \ + (type*) arena_allocate((arena), sizeof(type) * (count)) + +#define arena_push(arena, type) \ + (type*) arena_allocate((arena), sizeof(type)) + +internal void arena_release(Arena *arena); + +#endif // ARENA_H diff --git a/src/base.h b/src/base.h new file mode 100644 index 0000000..4956525 --- /dev/null +++ b/src/base.h @@ -0,0 +1,49 @@ +#ifndef BASE_H +#define BASE_H + +#include +#include +#include +#include + +#define internal static + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef uint8_t b8; +typedef uint8_t b16; +typedef uint8_t b32; +typedef uint8_t b64; + +#define KB(b) ((b) << 10) +#define MB(b) ((b) << 20) + +#define Glue_(A,B) A##B +#define Glue(A,B) Glue_(A,B) + +#define STATEMENT(S) do{ S } while(0) +#define ASSERT(c) STATEMENT( if (!(c)){ (*(volatile int*)0 = 0); } ) +#define STATIC_ASSERT(c,l) typedef u8 Glue(l,__LINE__) [(c)?1:-1] + +//= rhjr: linkedlist helpers + +#define sll_stack_push(f,n,next) ((n)->next=(f), (f)=(n)) + +//= rhjr: memory helpers + +#define memory_align_power_of_two(x,b) (((x) + (b) - 1)&(~((b) - 1))) + +#define memory_zero(s,z) memset((s), 0, (z)) +#define memory_zero_struct(s) memory_zero((s), sizeof(*(s))) + +#define memory_copy(dst, src, length) memmove((dst), (src), (length)) + +#endif // BASE_H diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..fb91a63 --- /dev/null +++ b/src/main.c @@ -0,0 +1,17 @@ +#include "base.h" +#include "arena.h" +#include "win32_platform.h" + +#include "arena.c" +#include "win32_platform.c" + +int +main(void) +{ + Arena *arena = arena_initialize_default(); + + /* lifetime of objects */ + + arena_release(arena); + return 0; +} diff --git a/src/win32_platform.c b/src/win32_platform.c new file mode 100644 index 0000000..117ab34 --- /dev/null +++ b/src/win32_platform.c @@ -0,0 +1,35 @@ + +internal void * +platform_memory_reserve(u64 size) +{ + void *result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); + return result; +} + +internal b8 +platform_memory_commit(void *ptr, u64 size) +{ + b32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0); + return result; +} + +internal void +platform_memory_decommit(void *ptr, u64 size) +{ + VirtualFree(ptr, size, MEM_DECOMMIT); +}; + +internal void +platform_memory_release(void *ptr, u64 size) +{ + (void) size; + VirtualFree(ptr, 0, MEM_RELEASE); +} + +internal u64 +platform_get_page_size(void) +{ + SYSTEM_INFO sysinfo = {0}; + GetSystemInfo(&sysinfo); + return sysinfo.dwPageSize; +} diff --git a/src/win32_platform.h b/src/win32_platform.h new file mode 100644 index 0000000..63e279a --- /dev/null +++ b/src/win32_platform.h @@ -0,0 +1,17 @@ +#ifndef WIN32_PLATFORM_H +#define WIN32_PLATFORM_H + +#undef internal +#include +#define internal static + +//= rhjr: platform memory management + +internal void * platform_memory_reserve(u64 size); +internal b8 platform_memory_commit(void *ptr, u64 size); +internal void platform_memory_decommit(void *ptr, u64 size); +internal void platform_memory_release(void *ptr, u64 size); + +internal u64 platform_get_page_size(void); + +#endif // WIN32_PLATFORM_H diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..0585435 --- /dev/null +++ b/start.bat @@ -0,0 +1,9 @@ +@echo off +setlocal +pushd "%~dp0" + +pushd build + +.\app.exe + +popd