diff --git a/src/base/base_arena.c b/src/base/base_arena.c new file mode 100644 index 0000000..51ff95f --- /dev/null +++ b/src/base/base_arena.c @@ -0,0 +1,56 @@ +internal *arena_alloc_(ArenaParams *params) { + u64 reserve_size = params->reserve_size; + u64 commit_size = params->reserve_size; + if (params->flags & ArenaFlag_LargePages) { + reserve_size = AlignPow2(reserve_size, os_get_system_info()->large_page_size); + commit_size = AlignPow2(commit_size, os_get_system_info()->large_page_size); + } else { + reserve_size = AlignPow2(reserve_size, os_get_system_info()->page_size); + commit_size = AlignPow2(commit_size, os_get_system_info()->page_size); + } + + // reserve/commit initial block + void *base = params->optional_backing_buffer; + if (base == 0) { + if (params->flags & ArenaFlag_LargePages) { + base = os_reserve_large(reserve_size); + os_commit_large(base, commit_size); + } else { + base = os_reserve(reserve_size); + os_commit(base, commit_size); + } + } + +// panic on failure +#if OS_FEATURE_GRAPHICAL + if (base == 0) { + os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure.")); + os_abort(1); + } +#endif + + Arena *arena = (Arena *)base; + arena->current = arena; // Current arena in the chain + arena->flags = params->flags; + arena->commit_size = (u32)params->commit_size; + arena->reserve_size = params->reserve_size; + arena->base_position 0; + arena->position = ARENA_HEADER_SIZE; + arena->commit = commit_size; + arena->reserve = reserve_size; + return arena; +} + +internal void arena_release(Arena *arena) { + for (Arena *n = arena->current; *l_previous = 0; n != 0; n = l_previous) { + l_previous = n->previous; + os_release(n, n->reserve); + } +} + +// @nocheckin +internal void *arena_push(Arena *arena, u64 size, u64 align) { + Arena *current = arena->current; + u64 position_pre = AlignPow2(current->position); + u64 position_past = position_pre + size; +} diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h new file mode 100644 index 0000000..59939e6 --- /dev/null +++ b/src/os/core/os_core.h @@ -0,0 +1,42 @@ +#ifndef OS_CORE_H +#define OS_CORE_H + +// System Information +typedef struct OS_SystemInfo OS_SystemInfo; +struct OS_SystemInfo { + u32 logical_processor_count; + u64 page_size; + u64 large_page_size; + u64 allocation_granularity; // NOTE(tijani): ??? What does this mean? + String8 machine_name; +}; + +// Process Information +typedef struct OS_ProcessInfo OS_ProcessInfo; +struct OS_ProcessInfo { + u32 process_id; + String8 binary_path; + String8 initial_path; + String8 user_program_data_path; + String8List module_load_paths; + String8List environment; +}; + +// %os_hooks(implemented per-os) System and process info +internal OS_SystemInfo *os_get_system_info(void); +internal OS_ProcessInfo *os_get_process_info(void); +internal String8 os_get_current_path(Arena *arena); + +// %os_hooks(implemented per-os) Memory allocation + +// NOTE(tijani): For normal page size +internal b32 os_commit(void *ptr, u64 size); +internal void *os_reserve(u64 size); +internal void os_decommit(void *ptr, u64 size); +internal void os_release(void *ptr, u64 size); + +// NOTE(tijani): For large page size +internal void *os_reserve_large(u64 size); +internal b32 os_commit_large(void *ptr, u64 size); + +#endif // OS_CORE_H diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c new file mode 100644 index 0000000..8413760 --- /dev/null +++ b/src/os/core/win32/os_core_win32.c @@ -0,0 +1,37 @@ +// %os_hooks(implemented per-os) System and process info +internal OS_SystemInfo *os_get_system_info(void) { return &os_w32_state.system_info; } + +internal OS_ProcessInfo *os_get_process_info(void) { return &os_w32_state.process_info; } + +internal String8 os_get_current_path(Arena *arena) {} + +// %os_hooks(implemented per-os) Memory allocation + +// NOTE(tijani): For normal page size +internal b32 os_commit(void *ptr, u64 size) { + b32 l_memory = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0); + return l_memory; +} + +internal void *os_reserve(u64 size) { + void *l_memory = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); + return l_memory; +} + +internal void os_decommit(void *ptr, u64 size) { VirtualFree(ptr, size, MEM_DECOMMIT); } + +internal void os_release(void *ptr, u64 size) { + // NOTE(tijani): size must be 0 on windows hence it will fail. + VirtualFree(ptr, size, MEM_RELEASE); +} + +// NOTE(tijani): For large page size +internal void *os_reserve_large(u64 size) { + void *l_memory = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES); + return l_memory; +} + +// NOTE(tijani): From my understanding, on windows you cannot +// commit large pages as this has to be done during reservation. +// see `os_reserve_large` and WIN32 docs on large page support. +internal b32 os_commit_large(void *ptr, u64 size) { return -1; } diff --git a/src/os/core/win32/os_core_win32.h b/src/os/core/win32/os_core_win32.h new file mode 100644 index 0000000..5690a11 --- /dev/null +++ b/src/os/core/win32/os_core_win32.h @@ -0,0 +1,20 @@ +#ifndef OS_CORE_WIN32_H +#define OS_CORE_WIN32_H + +#define WIN32_LEAN_AND_MEAN + +// Application State +typedef struct OS_W32_State OS_W32_State; +struct OS_W32_State { + Arena *arena; + + // System information + OS_SystemInfo system_info; + OS_ProcessInfo process_info; + u64 microsecond_resolution; +}; + +// Globals +global OS_W32_State os_w32_state = {0}; + +#endif // OS_CORE_WIN32_H