eliminate os_core, move into base; eliminate regs, move into arch abstraction layer, define x64 regs in x64 layer; move win32 backend for os core (now base) functionality to top-level win32 layer

This commit is contained in:
Ryan Fleury committed 2026-05-08 15:21:21 -07:00
1 parent 24c858171f
commit aea4a4ff9d
148 files changed
+7942 -5268

No files matched your search

+14 -14
View File
@@ -19,24 +19,24 @@ arena_alloc_(ArenaParams *params)
// rjf: round up reserve/commit sizes
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);
reserve_size = AlignPow2(reserve_size, get_system_info()->large_page_size);
commit_size = AlignPow2(commit_size, 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_size = AlignPow2(reserve_size, get_system_info()->page_size);
commit_size = AlignPow2(commit_size, get_system_info()->page_size);
}
if(params->flags & ArenaFlag_LargePages)
{
base = os_reserve_large(reserve_size);
os_commit_large(base, commit_size);
base = reserve_memory_large(reserve_size);
commit_memory_large(base, commit_size);
}
else
{
base = os_reserve(reserve_size);
os_commit(base, commit_size);
base = reserve_memory(reserve_size);
commit_memory(base, commit_size);
}
AsanPoisonMemoryRegion(base, commit_size);
// TODO(rjf): we need to reintroduce this later when we have the ability to remove annotations...
@@ -52,7 +52,7 @@ arena_alloc_(ArenaParams *params)
if(Unlikely(base == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
abort_self(1);
}
#endif
@@ -90,7 +90,7 @@ arena_release(Arena *arena)
for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
{
prev = n->prev;
os_release(n, n->res);
release_memory(n, n->res);
}
}
@@ -179,11 +179,11 @@ arena_push(Arena *arena, U64 size, U64 align, B32 zero)
U8 *cmt_ptr = (U8 *)current + current->cmt;
if(current->flags & ArenaFlag_LargePages)
{
os_commit_large(cmt_ptr, cmt_size);
commit_memory_large(cmt_ptr, cmt_size);
}
else
{
os_commit(cmt_ptr, cmt_size);
commit_memory(cmt_ptr, cmt_size);
}
AsanPoisonMemoryRegion(cmt_ptr, cmt_size);
current->cmt = cmt_pst_clamped;
@@ -213,7 +213,7 @@ arena_push(Arena *arena, U64 size, U64 align, B32 zero)
if(Unlikely(result == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
abort_self(1);
}
#endif
@@ -246,7 +246,7 @@ arena_pop_to(Arena *arena, U64 pos)
for(Arena *prev = 0; current->base_pos >= big_pos; current = prev)
{
prev = current->prev;
os_release(current, current->res);
release_memory(current, current->res);
}
#endif
arena->current = current;
+45
View File
@@ -471,6 +471,8 @@ union U128
U16 u16[8];
U32 u32[4];
U64 u64[2];
F32 f32[4];
F64 f64[2];
};
typedef union U256 U256;
union U256
@@ -480,6 +482,8 @@ union U256
U32 u32[8];
U64 u64[4];
U128 u128[2];
F32 f32[8];
F64 f64[4];
};
typedef union U512 U512;
union U512
@@ -490,8 +494,19 @@ union U512
U64 u64[8];
U128 u128[4];
U256 u256[2];
F32 f32[16];
F64 f64[8];
};
#pragma pack(push, 1)
typedef struct U80 U80;
struct U80
{
U64 int1_frac63;
U16 sign1_exp15;
};
#pragma pack(pop)
////////////////////////////////
//~ rjf: Basic Type Structures
@@ -653,6 +668,21 @@ Compiler;
# define Compiler_CURRENT Compiler_Null
#endif
////////////////////////////////
//~ rjf: Access Flags
typedef U32 AccessFlags;
enum
{
AccessFlag_Read = (1<<0),
AccessFlag_Write = (1<<1),
AccessFlag_Execute = (1<<2),
AccessFlag_Append = (1<<3),
AccessFlag_ShareRead = (1<<4),
AccessFlag_ShareWrite = (1<<5),
AccessFlag_Inherited = (1<<6),
};
////////////////////////////////
//~ rjf: Text 2D Coordinates & Ranges
@@ -1044,6 +1074,21 @@ internal DateTime date_time_from_dense_time(DenseTime time);
internal DateTime date_time_from_micro_seconds(U64 time);
internal DateTime date_time_from_unix_time(U64 unix_time);
////////////////////////////////
//~ rjf: @per_os_impl Platform Time Functions
internal U64 now_time_us(void);
internal U32 now_time_unix(void);
internal DateTime now_time_universal(void);
internal DateTime universal_from_local_time(DateTime *dt);
internal DateTime local_from_universal_time(DateTime *dt);
internal void sleep_ms(U32 ms);
////////////////////////////////
//~ rjf: @per_os_impl Platform GUID Functions
internal Guid make_guid(void);
////////////////////////////////
//~ rjf: Non-Fancy Ring Buffer Reads/Writes
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+20
View File
@@ -0,0 +1,20 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_DYNAMIC_LIBARIES_H
#define BASE_DYNAMIC_LIBARIES_H
typedef struct Library Library;
struct Library
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: @per_os_impl Dynamically-Loaded Libraries
internal Library library_open(String8 path);
internal void library_close(Library lib);
internal VoidProc *library_load_proc(Library lib, String8 name);
#endif // BASE_DYNAMIC_LIBARIES_H
+5 -2
View File
@@ -11,6 +11,9 @@ global B32 async_loop_again_high_priority = 0;
global B32 global_async_exit = 0;
thread_static B32 is_async_thread = 0;
// NOTE(rjf): defined by target
internal void entry_point(CmdLine *cmdline);
internal void
main_thread_base_entry_point(int arguments_count, char **arguments)
{
@@ -100,7 +103,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
#if defined(DBG_ENGINE_CORE_H)
num_main_threads += 1;
#endif
U64 num_async_threads = os_get_system_info()->logical_processor_count;
U64 num_async_threads = get_system_info()->logical_processor_count;
U64 num_main_threads_clamped = Min(num_async_threads, num_main_threads);
num_async_threads -= num_main_threads_clamped;
String8 num_async_threads_string = cmd_line_string(&cmdline, str8_lit("async_thread_count"));
@@ -192,7 +195,7 @@ async_thread_entry_point(void *params)
{
if(!ins_atomic_u32_eval(&async_loop_again))
{
MutexScope(async_tick_start_mutex) cond_var_wait(async_tick_start_cond_var, async_tick_start_mutex, os_now_microseconds()+1000000);
MutexScope(async_tick_start_mutex) cond_var_wait(async_tick_start_cond_var, async_tick_start_mutex, now_time_us()+1000000);
}
ins_atomic_u32_eval_assign(&async_loop_again, 0);
ins_atomic_u32_eval_assign(&async_loop_again_high_priority, 0);
+169
View File
@@ -0,0 +1,169 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Handle Type Functions
internal File
file_zero(void)
{
File f = {0};
return f;
}
internal B32
file_match(File a, File b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
////////////////////////////////
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
internal String8
data_from_file_path(Arena *arena, String8 path)
{
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, path);
FileProperties props = properties_from_file(file);
String8 data = string_from_file_range(arena, file, r1u64(0, props.size));
file_close(file);
return data;
}
internal B32
write_data_to_file_path(String8 path, String8 data)
{
B32 good = 0;
File file = file_open(AccessFlag_Write, path);
if(!file_match(file, file_zero()))
{
U64 bytes_written = file_write(file, r1u64(0, data.size), data.str);
good = (bytes_written == data.size);
file_close(file);
}
return good;
}
internal B32
write_data_list_to_file_path(String8 path, String8List list)
{
B32 good = 0;
File file = file_open(AccessFlag_Write, path);
if(!file_match(file, file_zero()))
{
Temp scratch = scratch_begin(0, 0);
U64 write_buffer_size = KB(64);
U8 *write_buffer = push_array_no_zero(scratch.arena, U8, write_buffer_size);
U64 write_buffer_write_pos = 0;
U64 write_buffer_read_pos = 0;
U64 file_off = 0;
{
for(String8Node *n = list.first; n != 0; n = n->next)
{
for(U64 n_off = 0; n_off < n->string.size;)
{
U64 write_buffer_unconsumed_size = (write_buffer_write_pos - write_buffer_read_pos);
U64 write_buffer_available_size = (write_buffer_size - write_buffer_unconsumed_size);
if(write_buffer_available_size == 0)
{
U64 file_write_size = file_write(file, r1u64(file_off, file_off+write_buffer_size), write_buffer);
if(file_write_size != write_buffer_size)
{
goto dbl_break;
}
file_off += write_buffer_size;
write_buffer_read_pos += write_buffer_size;
}
else
{
U64 bytes_to_copy = Min(write_buffer_available_size, n->string.size - n_off);
write_buffer_write_pos += ring_write(write_buffer, write_buffer_size, write_buffer_write_pos, n->string.str + n_off, bytes_to_copy);
n_off += bytes_to_copy;
}
}
}
if(write_buffer_write_pos > write_buffer_read_pos)
{
U64 file_write_size = file_write(file, r1u64(file_off, file_off + (write_buffer_write_pos-write_buffer_read_pos)), write_buffer);
file_off += file_write_size;
}
}
dbl_break:;
good = (file_off == list.total_size);
file_close(file);
scratch_end(scratch);
}
return good;
}
internal B32
append_data_to_file_path(String8 path, String8 data)
{
B32 good = 0;
if(data.size != 0)
{
File file = file_open(AccessFlag_Write|AccessFlag_Append, path);
if(!file_match(file, file_zero()))
{
U64 pos = properties_from_file(file).size;
U64 bytes_written = file_write(file, r1u64(pos, pos+data.size), data.str);
good = (bytes_written == data.size);
file_close(file);
}
}
return good;
}
internal FileID
id_from_file_path(String8 path)
{
File file = file_open(AccessFlag_Read|AccessFlag_ShareRead, path);
FileID id = id_from_file(file);
file_close(file);
return id;
}
internal S64
file_id_compare(FileID a, FileID b)
{
S64 cmp = MemoryCompare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v));
return cmp;
}
internal String8
string_from_file_range(Arena *arena, File file, Rng1U64 range)
{
U64 pre_pos = arena_pos(arena);
String8 result;
result.size = dim_1u64(range);
result.str = push_array_no_zero(arena, U8, result.size);
U64 actual_read_size = file_read(file, range, result.str);
if(actual_read_size < result.size)
{
arena_pop_to(arena, pre_pos + actual_read_size);
result.size = actual_read_size;
}
return result;
}
internal String8
file_read_cstring(Arena *arena, File file, U64 off)
{
Temp scratch = scratch_begin(&arena, 1);
String8List block_list = {0};
for(U64 cursor = off, stride = 256;; cursor += stride)
{
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
U64 read_size = file_read(file, r1u64(cursor, cursor + stride), raw_block);
String8 block = str8_cstring_capped(raw_block, raw_block+read_size);
str8_list_push(scratch.arena, &block_list, block);
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
{
break;
}
}
String8 result = str8_list_join(arena, &block_list, 0);
scratch_end(scratch);
return result;
}
+102
View File
@@ -0,0 +1,102 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_FILES_H
#define BASE_FILES_H
typedef U32 FileIterFlags;
enum
{
FileIterFlag_SkipFolders = (1 << 0),
FileIterFlag_SkipFiles = (1 << 1),
FileIterFlag_SkipHiddenFiles = (1 << 2),
FileIterFlag_Done = (1 << 31),
};
typedef struct FileIter FileIter;
struct FileIter
{
FileIterFlags flags;
U8 memory[800];
};
typedef struct FileInfo FileInfo;
struct FileInfo
{
String8 name;
FileProperties props;
};
// nick: on-disk file identifier
typedef struct FileID FileID;
struct FileID
{
U64 v[3];
};
typedef struct File File;
struct File
{
U64 u64[1];
};
typedef struct FileMap FileMap;
struct FileMap
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: Handle Type Functions
internal File file_zero(void);
internal B32 file_match(File a, File b);
////////////////////////////////
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
internal String8 data_from_file_path(Arena *arena, String8 path);
internal B32 write_data_to_file_path(String8 path, String8 data);
internal B32 write_data_list_to_file_path(String8 path, String8List list);
internal B32 append_data_to_file_path(String8 path, String8 data);
internal FileID id_from_file_path(String8 path);
internal S64 file_id_compare(FileID a, FileID b);
internal String8 string_from_file_range(Arena *arena, File file, Rng1U64 range);
internal String8 file_read_cstring(Arena *arena, File file, U64 off);
////////////////////////////////
//~ rjf: @per_os_impl File System (Implemented Per-OS)
//- rjf: files
internal File file_open(AccessFlags flags, String8 path);
internal void file_close(File file);
internal U64 file_read(File file, Rng1U64 rng, void *out_data);
#define file_read_struct(f, off, ptr) file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr))
internal U64 file_write(File file, Rng1U64 rng, void *data);
internal B32 file_set_times(File file, DateTime time);
internal FileProperties properties_from_file(File file);
internal FileID id_from_file(File file);
internal B32 file_reserve_size(File file, U64 size);
internal B32 delete_file_at_path(String8 path);
internal B32 copy_file_path(String8 dst, String8 src);
internal B32 move_file_path(String8 dst, String8 src);
internal String8 full_path_from_path(Arena *arena, String8 path);
internal B32 file_path_exists(String8 path);
internal B32 folder_path_exists(String8 path);
internal FileProperties properties_from_file_path(String8 path);
//- rjf: file maps
internal FileMap file_map_open(AccessFlags flags, File file);
internal void file_map_close(FileMap map);
internal void * file_map_view_open(FileMap map, AccessFlags flags, Rng1U64 range);
internal void file_map_view_close(FileMap map, void *ptr, Rng1U64 range);
//- rjf: directory iteration
internal FileIter *file_iter_begin(Arena *arena, String8 path, FileIterFlags flags);
internal B32 file_iter_next(Arena *arena, FileIter *iter, FileInfo *info_out);
internal void file_iter_end(FileIter *iter);
//- rjf: directory creation
internal B32 make_directory(String8 path);
#endif // BASE_FILES_H
+14
View File
@@ -9,14 +9,28 @@
#include "base_core.c"
#include "base_profile.c"
#include "base_memory.c"
#include "base_arena.c"
#include "base_math.c"
#include "base_strings.c"
#include "base_hash.c"
#include "base_system.c"
#include "base_threads.c"
#include "base_thread_context.c"
#include "base_files.c"
#include "base_shared_memory.c"
#include "base_processes.c"
#include "base_dynamic_libraries.c"
#include "base_command_line.c"
#include "base_markup.c"
#include "base_meta.c"
#include "base_log.c"
#include "base_entry_point.c"
#if OS_WINDOWS
# include "win32/base/win32_base.c"
#elif OS_LINUX
# include "linux/base/linux_base.c"
#else
# error Operating system backend not found for base layer.
#endif
+14
View File
@@ -11,16 +11,30 @@
#include "base_core.h"
#include "base_profile.h"
#include "base_memory.h"
#include "base_arena.h"
#include "base_math.h"
#include "base_strings.h"
#include "base_hash.h"
#include "base_system.h"
#include "base_threads.h"
#include "base_thread_context.h"
#include "base_files.h"
#include "base_shared_memory.h"
#include "base_processes.h"
#include "base_dynamic_libraries.h"
#include "base_command_line.h"
#include "base_markup.h"
#include "base_meta.h"
#include "base_log.h"
#include "base_entry_point.h"
#if OS_WINDOWS
# include "win32/base/win32_base.h"
#elif OS_LINUX
# include "linux/base/linux_base.h"
#else
# error Operating system backend not found for base layer.
#endif
#endif // BASE_INC_H
-19
View File
@@ -1,21 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal void
set_thread_name(String8 string)
{
ProfThreadName("%.*s", str8_varg(string));
os_set_thread_name(string);
}
internal void
set_thread_namef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
set_thread_name(string);
va_end(args);
scratch_end(scratch);
}
-2
View File
@@ -15,8 +15,6 @@
# define LAYER_COLOR 0x404040ff
#endif
internal void set_thread_name(String8 string);
internal void set_thread_namef(char *fmt, ...);
#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__), raddbg_thread_color_u32(LAYER_COLOR))
#endif // BASE_MARKUP_H
+20
View File
@@ -407,6 +407,26 @@ transpose_4x4f32(Mat4x4F32 mat)
////////////////////////////////
//~ rjf: Range Ops
internal Rng1U8 rng_1u8(U8 min, U8 max) {Rng1U8 r = {min, max}; if(r.min > r.max) { Swap(U8, r.min, r.max); } return r;}
internal Rng1U8 shift_1u8(Rng1U8 r, U8 x) {r.min += x; r.max += x; return r;}
internal Rng1U8 pad_1u8(Rng1U8 r, U8 x) {r.min -= x; r.max += x; return r;}
internal U8 center_1u8(Rng1U8 r) {U8 c = (r.min+r.max)/2; return c;}
internal B32 contains_1u8(Rng1U8 r, U8 x) {B32 c = (r.min <= x && x < r.max); return c;}
internal U8 dim_1u8(Rng1U8 r) {U8 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;}
internal Rng1U8 union_1u8(Rng1U8 a, Rng1U8 b) {Rng1U8 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;}
internal Rng1U8 intersect_1u8(Rng1U8 a, Rng1U8 b) {Rng1U8 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;}
internal U8 clamp_1u8(Rng1U8 r, U8 v) {v = Clamp(r.min, v, r.max); return v;}
internal Rng1U16 rng_1u16(U16 min, U16 max) {Rng1U16 r = {min, max}; if(r.min > r.max) { Swap(U16, r.min, r.max); } return r;}
internal Rng1U16 shift_1u16(Rng1U16 r, U16 x) {r.min += x; r.max += x; return r;}
internal Rng1U16 pad_1u16(Rng1U16 r, U16 x) {r.min -= x; r.max += x; return r;}
internal U16 center_1u16(Rng1U16 r) {U16 c = (r.min+r.max)/2; return c;}
internal B32 contains_1u16(Rng1U16 r, U16 x) {B32 c = (r.min <= x && x < r.max); return c;}
internal U16 dim_1u16(Rng1U16 r) {U16 c = ((r.max > r.min) ? (r.max - r.min) : 0); return c;}
internal Rng1U16 union_1u16(Rng1U16 a, Rng1U16 b) {Rng1U16 c = {Min(a.min, b.min), Max(a.max, b.max)}; return c;}
internal Rng1U16 intersect_1u16(Rng1U16 a, Rng1U16 b) {Rng1U16 c = {Max(a.min, b.min), Min(a.max, b.max)}; return c;}
internal U16 clamp_1u16(Rng1U16 r, U16 v) {v = Clamp(r.min, v, r.max); return v;}
internal Rng1U32 rng_1u32(U32 min, U32 max) {Rng1U32 r = {min, max}; if(r.min > r.max) { Swap(U32, r.min, r.max); } return r;}
internal Rng1U32 shift_1u32(Rng1U32 r, U32 x) {r.min += x; r.max += x; return r;}
internal Rng1U32 pad_1u32(Rng1U32 r, U32 x) {r.min -= x; r.max += x; return r;}
+44
View File
@@ -177,6 +177,28 @@ struct Mat4x4F32
//- rjf: 1-range
typedef union Rng1U8 Rng1U8;
union Rng1U8
{
struct
{
U8 min;
U8 max;
};
U8 v[2];
};
typedef union Rng1U16 Rng1U16;
union Rng1U16
{
struct
{
U16 min;
U16 max;
};
U16 v[2];
};
typedef union Rng1U32 Rng1U32;
union Rng1U32
{
@@ -546,6 +568,28 @@ internal Mat4x4F32 transpose_4x4f32(Mat4x4F32 mat);
////////////////////////////////
//~ rjf: Range Ops
#define r1u8(min, max) rng_1u8((min), (max))
internal Rng1U8 rng_1u8(U8 min, U8 max);
internal Rng1U8 shift_1u8(Rng1U8 r, U8 x);
internal Rng1U8 pad_1u8(Rng1U8 r, U8 x);
internal U8 center_1u8(Rng1U8 r);
internal B32 contains_1u8(Rng1U8 r, U8 x);
internal U8 dim_1u8(Rng1U8 r);
internal Rng1U8 union_1u8(Rng1U8 a, Rng1U8 b);
internal Rng1U8 intersect_1u8(Rng1U8 a, Rng1U8 b);
internal U8 clamp_1u8(Rng1U8 r, U8 v);
#define r1u16(min, max) rng_1u16((min), (max))
internal Rng1U16 rng_1u16(U16 min, U16 max);
internal Rng1U16 shift_1u16(Rng1U16 r, U16 x);
internal Rng1U16 pad_1u16(Rng1U16 r, U16 x);
internal U16 center_1u16(Rng1U16 r);
internal B32 contains_1u16(Rng1U16 r, U16 x);
internal U16 dim_1u16(Rng1U16 r);
internal Rng1U16 union_1u16(Rng1U16 a, Rng1U16 b);
internal Rng1U16 intersect_1u16(Rng1U16 a, Rng1U16 b);
internal U16 clamp_1u16(Rng1U16 r, U16 v);
#define r1u32(min, max) rng_1u32((min), (max))
internal Rng1U32 rng_1u32(U32 min, U32 max);
internal Rng1U32 shift_1u32(Rng1U32 r, U32 x);
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+26
View File
@@ -0,0 +1,26 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_MEMORY_H
#define BASE_MEMORY_H
typedef struct SharedMemory SharedMemory;
struct SharedMemory
{
U64 u64[1];
};
////////////////////////////////
//~ rjf: @per_os_impl Platform Memory Allocation
//- rjf: basic
internal void *reserve_memory(U64 size);
internal B32 commit_memory(void *ptr, U64 size);
internal void decommit_memory(void *ptr, U64 size);
internal void release_memory(void *ptr, U64 size);
//- rjf: large pages
internal void *reserve_memory_large(U64 size);
internal B32 commit_memory_large(void *ptr, U64 size);
#endif // BASE_MEMORY_H
+115
View File
@@ -0,0 +1,115 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Handle Type Functions
internal Process
process_zero(void)
{
Process p = {0};
return p;
}
internal B32
process_match(Process a, Process b)
{
B32 result = MemoryMatchStruct(&a, &b);
return result;
}
internal void
process_list_push(Arena *arena, ProcessList *list, Process p)
{
ProcessNode *n = push_array(arena, ProcessNode, 1);
SLLQueuePush(list->first, list->last, n);
n->v = p;
list->count += 1;
}
////////////////////////////////
//~ rjf: Process Launcher Helpers
internal Process
launch_cmd_line(String8 string)
{
Temp scratch = scratch_begin(0, 0);
U8 split_chars[] = {' '};
String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0);
Process process = {0};
if(parts.node_count != 0)
{
// rjf: unpack exe part
String8 exe = parts.first->string;
String8 exe_folder = str8_chop_last_slash(exe);
if(exe_folder.size == 0)
{
exe_folder = get_current_path(scratch.arena);
}
// rjf: find stdout delimiter
String8Node *stdout_delimiter_n = 0;
for(String8Node *n = parts.first; n != 0; n = n->next)
{
if(str8_match(n->string, str8_lit(">"), 0))
{
stdout_delimiter_n = n;
break;
}
}
// rjf: read stdout path
String8 stdout_path = {0};
if(stdout_delimiter_n && stdout_delimiter_n->next)
{
stdout_path = stdout_delimiter_n->next->string;
}
// rjf: open stdout handle
File stdout_handle = {0};
if(stdout_path.size != 0)
{
File file = file_open(AccessFlag_Write|AccessFlag_Read, stdout_path);
file_close(file);
stdout_handle = file_open(AccessFlag_Write|AccessFlag_Append|AccessFlag_ShareRead|AccessFlag_ShareWrite|AccessFlag_Inherited, stdout_path);
}
// rjf: form command line
String8List cmdline = {0};
for(String8Node *n = parts.first; n != stdout_delimiter_n && n != 0; n = n->next)
{
str8_list_push(scratch.arena, &cmdline, n->string);
}
// rjf: launch
ProcessLaunchParams params = {0};
params.cmd_line = cmdline;
params.path = exe_folder;
params.inherit_env = 1;
params.stdout_file = stdout_handle;
process = process_launch(&params);
// rjf: close stdout handle
{
if(stdout_path.size != 0)
{
file_close(stdout_handle);
}
}
}
scratch_end(scratch);
return process;
}
internal Process
launch_cmd_linef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = str8fv(scratch.arena, fmt, args);
Process result = launch_cmd_line(string);
va_end(args);
scratch_end(scratch);
return result;
}
+87
View File
@@ -0,0 +1,87 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_PROCESSES_H
#define BASE_PROCESSES_H
typedef struct ProcessInfo ProcessInfo;
struct ProcessInfo
{
U32 pid;
B32 large_pages_allowed;
String8 binary_path;
String8 initial_path;
String8 user_program_data_path;
String8List module_load_paths;
String8List environment;
};
typedef struct Process Process;
struct Process
{
U64 u64[1];
};
typedef struct ProcessNode ProcessNode;
struct ProcessNode
{
ProcessNode *next;
Process v;
};
typedef struct ProcessList ProcessList;
struct ProcessList
{
ProcessNode *first;
ProcessNode *last;
U64 count;
};
typedef struct ProcessLaunchParams ProcessLaunchParams;
struct ProcessLaunchParams
{
String8List cmd_line;
String8 path;
String8List env;
B32 inherit_env;
B32 debug_subprocesses;
B32 consoleless;
File stdout_file;
File stderr_file;
File stdin_file;
};
////////////////////////////////
//~ rjf: Handle Type Functions
internal Process process_zero(void);
internal B32 process_match(Process a, Process b);
internal void process_list_push(Arena *arena, ProcessList *list, Process p);
////////////////////////////////
//~ rjf: Process Launcher Helpers
internal Process launch_cmd_line(String8 string);
internal Process launch_cmd_linef(char *fmt, ...);
////////////////////////////////
//~ rjf: @per_os_impl Aborting
internal void abort_self(S32 exit_code);
////////////////////////////////
//~ rjf: @per_os_impl Process Info
internal ProcessInfo *get_process_info(void);
internal String8 get_current_path(Arena *arena);
internal U32 get_process_start_time_unix(void);
////////////////////////////////
//~ rjf: @per_os_impl Child Processes
internal Process process_launch(ProcessLaunchParams *params);
internal B32 process_join(Process process, U64 endt_us, U64 *exit_code_out);
internal void process_detach(Process process);
internal B32 process_kill(Process process);
#endif // BASE_PROCESSES_H
+1 -1
View File
@@ -24,7 +24,7 @@ spall_begin(char *fmt, ...)
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
spall_buffer_begin_ex(&spall_profile, &spall_buffer, string.str, string.size, os_now_microseconds(), spall_tid, spall_pid);
spall_buffer_begin_ex(&spall_profile, &spall_buffer, string.str, string.size, now_time_us(), spall_tid, spall_pid);
va_end(args);
scratch_end(scratch);
}
+1 -1
View File
@@ -79,7 +79,7 @@ thread_static U32 spall_pid = 0;
internal inline void spall_begin(char *fmt, ...);
# define ProfBegin(...) (spall_capturing ? (spall_begin(__VA_ARGS__), 0) : 0)
# define ProfBeginDynamic(...) (spall_capturing ? (spall_begin(__VA_ARGS__), 0) : 0)
# define ProfEnd(...) (spall_capturing ? (spall_buffer_end_ex(&spall_profile, &spall_buffer, os_now_microseconds(), spall_tid, spall_pid)), 0 : 0)
# define ProfEnd(...) (spall_capturing ? (spall_buffer_end_ex(&spall_profile, &spall_buffer, now_time_us(), spall_tid, spall_pid)), 0 : 0)
# define ProfTick(...)
# define ProfIsCapturing(...) (!!spall_capturing)
# define ProfBeginCapture(...) (spall_capturing = 1)
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+16
View File
@@ -0,0 +1,16 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_SHARED_MEMORY_H
#define BASE_SHARED_MEMORY_H
////////////////////////////////
//~ rjf: @os_hooks Shared Memory
internal SharedMemory shared_memory_alloc(U64 size, String8 name);
internal SharedMemory shared_memory_open(String8 name);
internal void shared_memory_close(SharedMemory handle);
internal void * shared_memory_view_open(SharedMemory handle, Rng1U64 range);
internal void shared_memory_view_close(SharedMemory handle, void *ptr, Rng1U64 range);
#endif // BASE_SHARED_MEMORY_H
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+22
View File
@@ -0,0 +1,22 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_SYSTEM_H
#define BASE_SYSTEM_H
typedef struct SystemInfo SystemInfo;
struct SystemInfo
{
U32 logical_processor_count;
U64 page_size;
U64 large_page_size;
U64 allocation_granularity;
String8 machine_name;
};
////////////////////////////////
//~ rjf: @per_os_impl System Info
internal SystemInfo *get_system_info(void);
#endif // BASE_SYSTEM_H
+4 -4
View File
@@ -108,7 +108,7 @@ tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_sr
}
// rjf: all cases: barrier
os_barrier_wait(tctx->lane_ctx.barrier);
barrier_wait(tctx->lane_ctx.barrier);
// rjf: doing broadcast -> copy from broadcast memory on destination lanes
if(broadcast_ptr != 0 && lane_idx() != broadcast_src_lane_idx)
@@ -119,7 +119,7 @@ tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_sr
// rjf: doing broadcast -> barrier on all lanes
if(broadcast_ptr != 0)
{
os_barrier_wait(tctx->lane_ctx.barrier);
barrier_wait(tctx->lane_ctx.barrier);
}
ProfEnd();
@@ -202,7 +202,7 @@ internal void
access_touch(Access *access, AccessPt *pt, CondVar cv)
{
ins_atomic_u64_inc_eval(&pt->access_refcount);
ins_atomic_u64_eval_assign(&pt->last_time_touched_us, os_now_microseconds());
ins_atomic_u64_eval_assign(&pt->last_time_touched_us, now_time_us());
ins_atomic_u64_eval_assign(&pt->last_update_idx_touched, update_tick_idx());
Touch *touch = tctx_thread_local->free_touch;
if(touch != 0)
@@ -228,7 +228,7 @@ access_pt_is_expired_(AccessPt *pt, AccessPtExpireParams *params)
U64 last_time_touched_us = ins_atomic_u64_eval(&pt->last_time_touched_us);
U64 last_update_idx_touched = ins_atomic_u64_eval(&pt->last_update_idx_touched);
B32 result = (access_refcount == 0 &&
last_time_touched_us + params->time <= os_now_microseconds() &&
last_time_touched_us + params->time <= now_time_us() &&
last_update_idx_touched + params->update_idxs <= update_tick_idx());
return result;
}
+23 -65
View File
@@ -1,70 +1,6 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Thread Functions
internal Thread
thread_launch(ThreadEntryPointFunctionType *f, void *p)
{
Thread thread = os_thread_launch(f, p);
return thread;
}
internal B32
thread_join(Thread thread, U64 endt_us)
{
B32 result = os_thread_join(thread, endt_us);
return result;
}
internal void
thread_detach(Thread thread)
{
os_thread_detach(thread);
}
////////////////////////////////
//~ rjf: Synchronization Primitive Functions
//- rjf: recursive mutexes
internal Mutex mutex_alloc(void) {return os_mutex_alloc();}
internal void mutex_release(Mutex mutex) {os_mutex_release(mutex);}
internal void mutex_take(Mutex mutex) {os_mutex_take(mutex);}
internal void mutex_drop(Mutex mutex) {os_mutex_drop(mutex);}
//- rjf: reader/writer mutexes
internal RWMutex rw_mutex_alloc(void) {return os_rw_mutex_alloc();}
internal void rw_mutex_release(RWMutex mutex) {os_rw_mutex_release(mutex);}
internal void rw_mutex_take(RWMutex mutex, B32 write_mode) {os_rw_mutex_take(mutex, write_mode);}
internal void rw_mutex_drop(RWMutex mutex, B32 write_mode) {os_rw_mutex_drop(mutex, write_mode);}
//- rjf: condition variables
internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();}
internal void cond_var_release(CondVar cv) {os_cond_var_release(cv);}
internal B32 cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us) {return os_cond_var_wait(cv, mutex, endt_us);}
internal B32 cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us) {return os_cond_var_wait_rw(cv, mutex_rw, write_mode, endt_us);}
internal void cond_var_signal(CondVar cv) {os_cond_var_signal(cv);}
internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);}
//- rjf: cross-process semaphores
internal Semaphore semaphore_alloc(U32 initial_count, U32 max_count, String8 name) {return os_semaphore_alloc(initial_count, max_count, name);}
internal void semaphore_release(Semaphore semaphore) {os_semaphore_release(semaphore);}
internal Semaphore semaphore_open(String8 name) {return os_semaphore_open(name);}
internal void semaphore_close(Semaphore semaphore) {os_semaphore_close(semaphore);}
internal B32 semaphore_take(Semaphore semaphore, U64 endt_us) {return os_semaphore_take(semaphore, endt_us);}
internal void semaphore_drop(Semaphore semaphore) {os_semaphore_drop(semaphore);}
//- rjf: barriers
internal Barrier barrier_alloc(U64 count) {return os_barrier_alloc(count);}
internal void barrier_release(Barrier barrier) {os_barrier_release(barrier);}
internal void barrier_wait(Barrier barrier) {os_barrier_wait(barrier);}
////////////////////////////////
//~ rjf: Table Stripe Functions
@@ -72,7 +8,7 @@ internal StripeArray
stripe_array_alloc(Arena *arena)
{
StripeArray array = {0};
array.count = os_get_system_info()->logical_processor_count;
array.count = get_system_info()->logical_processor_count;
array.v = push_array(arena, Stripe, array.count);
for EachIndex(idx, array.count)
{
@@ -100,3 +36,25 @@ stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx)
Stripe *stripe = &stripes->v[slot_idx%stripes->count];
return stripe;
}
////////////////////////////////
//~ rjf: Thread Info Helpers
internal void
set_thread_name(String8 string)
{
ProfThreadName("%.*s", str8_varg(string));
set_platform_thread_name(string);
}
internal void
set_thread_namef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
set_thread_name(string);
va_end(args);
scratch_end(scratch);
}
+23 -6
View File
@@ -67,14 +67,33 @@ struct StripeArray
};
////////////////////////////////
//~ rjf: Thread Functions
//~ rjf: Table Stripe Functions
internal StripeArray stripe_array_alloc(Arena *arena);
internal void stripe_array_release(StripeArray *stripes);
internal Stripe *stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx);
////////////////////////////////
//~ rjf: Thread Info Helpers
internal void set_thread_name(String8 string);
internal void set_thread_namef(char *fmt, ...);
////////////////////////////////
//~ rjf: @per_os_impl Current Thread Info
internal U32 tid(void);
internal void set_platform_thread_name(String8 name);
////////////////////////////////
//~ rjf: @per_os_impl Thread Functions
internal Thread thread_launch(ThreadEntryPointFunctionType *f, void *p);
internal B32 thread_join(Thread thread, U64 endt_us);
internal void thread_detach(Thread thread);
////////////////////////////////
//~ rjf: Synchronization Primitive Functions
//~ rjf: @per_os_impl Synchronization Primitive Functions
//- rjf: recursive mutexes
internal Mutex mutex_alloc(void);
@@ -124,10 +143,8 @@ internal void barrier_wait(Barrier barrier);
#define MutexScopeRWPromote(mutex) DeferLoop((rw_mutex_drop_r(mutex), rw_mutex_take_w(mutex)), (rw_mutex_drop_w(mutex), rw_mutex_take_r(mutex)))
////////////////////////////////
//~ rjf: Table Stripe Functions
//~ rjf: @per_os_impl Safe Calls
internal StripeArray stripe_array_alloc(Arena *arena);
internal void stripe_array_release(StripeArray *stripes);
internal Stripe *stripe_from_slot_idx(StripeArray *stripes, U64 slot_idx);
internal void safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr);
#endif // BASE_THREADS_H