commit 392c55fd882f4efabf9cca102e87d3bec883e81a Author: rhuibertsjr Date: Tue Apr 30 20:04:44 2024 +0200 Added: Initial project layout 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.sh b/build.sh new file mode 100644 index 0000000..31e42bf --- /dev/null +++ b/build.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Creating lay-out +cd "$(dirname "$0")" + +mkdir -p build/ + +cd build/ + +# Building flags +CFLAGS="-g -Wall -Wextra -O0 --std=gnu99" +LDFLAGS="-lc -pthread" + +# Building executable... +echo -e "\nBuilding posix-threading-synchronisation research..." + +time gcc -x c $CFLAGS $DEFINES ../src/main.c -o ./gazoo_test_environment $LDFLAGS + +echo "" + +cd .. 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/linux_platform.c b/src/linux_platform.c new file mode 100644 index 0000000..a3a1635 --- /dev/null +++ b/src/linux_platform.c @@ -0,0 +1,32 @@ + +internal void * +platform_memory_reserve(u64 size) +{ + void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + return result; +} + +#define PAGE_SIZE sysconf(_SC_PAGESIZE) + +internal b8 +platform_memory_commit(void *ptr, u64 size) +{ + void *page_aligned_ptr = + (void *)(((uintptr_t)ptr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); + mprotect(page_aligned_ptr, size, PROT_READ|PROT_WRITE); + return 1; + +} + +internal void +platform_memory_decommit(void *ptr, u64 size) +{ + madvise(ptr, size, MADV_DONTNEED); + mprotect(ptr, size, PROT_NONE); +} + +internal void +platform_memory_release(void *ptr, u64 size) +{ + munmap(ptr, size); +} diff --git a/src/linux_platform.h b/src/linux_platform.h new file mode 100644 index 0000000..b6a5ceb --- /dev/null +++ b/src/linux_platform.h @@ -0,0 +1,22 @@ +#ifndef LINUX_PLATFORM_H +#define LINUX_PLATFORM_H + +#include +#include + +#include +#include + +//= rhjr: multi-threading + +#include +#include + +//= 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); + +#endif // LINUX_PLATFORM_H diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..c273634 --- /dev/null +++ b/src/main.c @@ -0,0 +1,22 @@ +#include "base.h" +#include "arena.h" +#include "linux_platform.h" +#include "string.h" + +#include "arena.c" +#include "linux_platform.c" +#include "string.c" + +int +main(void) +{ + Arena *arena = arena_initialize_default(); + + /* lifetime of objects */ + String8 string = str8_lit("Hello world"); + + print_str8(string); + + arena_release(arena); + return 0; +} diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..ca9e06e --- /dev/null +++ b/src/string.c @@ -0,0 +1,20 @@ +internal String8 +str8_initialize(u8 *cstring, u64 length) +{ + String8 result = { cstring, length }; + return result; +} + +internal String8 +str8_range(u8 *first, u8 *opl) { + String8 result = { first, (u64)(opl - first) }; + return result; +} + +internal String8 +str8_from_cstring(u8 *cstring) { + u8 *ptr = cstring; + for (;*ptr != 0; ptr += 1); + String8 result = str8_range(cstring, ptr); + return result; +} diff --git a/src/string.h b/src/string.h new file mode 100644 index 0000000..a336377 --- /dev/null +++ b/src/string.h @@ -0,0 +1,23 @@ +#ifndef STRING_H +#define STRING_H 1 + +typedef struct String8 String8; +struct String8 +{ + u8 *str; + u64 length; +}; + +internal String8 str8_initialize(u8 *cstring, u64 length); +#define str8_lit(cstring) \ + str8_initialize((u8*)(cstring), sizeof(cstring) - 1) + +#define str8_lit_comp(cstring) \ + {(u8*)(cstring), sizeof(cstring) - 1} + +//= rhjr: helper macros + +#define print_str8(str8) \ + printf("%.*s\n", (i32) str8.length, str8.str) + +#endif // STRING_H diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..60b4fc8 --- /dev/null +++ b/start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +cd "$(dirname "$0")" +mkdir -p build/ + +cd build/ + +# Running executable +echo "" + +./gazoo_test_environment + +echo "" + +cd ..