#pragma once #include #include #include #include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN 1 #include #else #include #include #include #include #include #include #include #include #endif typedef enum TimeUnit { TIME_UNIT_NANOSECONDS, TIME_UNIT_MICROSECONDS, TIME_UNIT_MILLISECONDS, TIME_UNIT_SECONDS, } TimeUnit; ENUM(ProcessTerminationKind, u8, PROCESS_TERMINATION_UNKNOWN, PROCESS_TERMINATION_EXIT, PROCESS_TERMINATION_SIGNAL, PROCESS_TERMINATION_STOP, ); STRUCT(RunCommandResult) { u32 termination_code; ProcessTerminationKind termination_kind; u8 reserved[3]; }; typedef enum ChildProcessStreamPolicy { CHILD_PROCESS_STREAM_INHERIT, CHILD_PROCESS_STREAM_PIPE, CHILD_PROCESS_STREAM_IGNORE, } ChildProcessStreamPolicy; STRUCT(ChildProcessStream) { u8* buffer; u32* length; u32 capacity; ChildProcessStreamPolicy policy; }; STRUCT(RunCommandOptions) { ChildProcessStream stdout_stream; ChildProcessStream stderr_stream; FileDescriptor null_file_descriptor; u64 use_null_file_descriptor:1; u64 debug:1; u64 reserved:62; }; STRUCT(Timestamp) { u128 value; }; STRUCT(OSFileOpenFlags) { u32 truncate:1; u32 executable:1; u32 write:1; u32 read:1; u32 create:1; u32 directory:1; }; STRUCT(OSFilePermissions) { u8 readable:1; u8 writable:1; u8 executable:1; }; STRUCT(OSReserveProtectionFlags) { u32 read:1; u32 write:1; u32 execute:1; u32 reserved:29; }; STRUCT(OSReserveMapFlags) { u32 priv:1; u32 anon:1; u32 populate:1; u32 noreserve:1; u32 reserved:29; }; STRUCT(Arena) { u64 reserved_size; u64 position; u64 os_position; u64 granularity; u8 reserved[4 * 8]; }; STRUCT(FileWriteOptions) { String path; String content; u64 executable:1; }; #ifndef __APPLE__ #define MY_PAGE_SIZE KB(4) #else #define MY_PAGE_SIZE KB(16) #endif global_variable const u64 page_size = MY_PAGE_SIZE; global_variable u64 minimum_granularity = MY_PAGE_SIZE; // global_variable u64 middle_granularity = MB(2); global_variable u64 default_size = GB(4); fn void vprint(const char* format, va_list args); fn void print(const char* format, ...); fn RunCommandResult run_command(Arena* arena, CStringSlice arguments, char* envp[], RunCommandOptions options); fn String file_read(Arena* arena, String path); fn void file_write(FileWriteOptions options); fn String path_dir(String string); fn String path_base(String string); fn String path_no_extension(String string); fn Arena* arena_initialize(u64 reserved_size, u64 granularity, u64 initial_size); fn Arena* arena_initialize_default(u64 initial_size); fn void arena_clear(Arena* arena); fn String arena_join_string(Arena* arena, Slice(String) pieces); fn u8* arena_allocate_bytes(Arena* arena, u64 size, u64 alignment); fn void arena_reset(Arena* arena); #define arena_allocate(arena, T, count) (T*)(arena_allocate_bytes(arena, sizeof(T) * count, alignof(T))) #define arena_allocate_slice(arena, T, count) (Slice(T)){ .pointer = arena_allocate(arena, T, count), .length = count } fn u8* os_reserve(u64 base, u64 size, OSReserveProtectionFlags protection, OSReserveMapFlags map); fn void os_commit(void* address, u64 size); fn u8 os_file_descriptor_is_valid(FileDescriptor fd); fn FileDescriptor os_file_open(String path, OSFileOpenFlags flags, OSFilePermissions permissions); fn void os_file_close(FileDescriptor fd); fn u64 os_file_get_size(FileDescriptor fd); fn void os_file_write(FileDescriptor fd, String content); fn FileDescriptor os_stdout_get(); fn void os_directory_make(String path); BB_NORETURN BB_COLD fn void os_exit(u32 exit_code); fn void calibrate_cpu_timer(); fn void print_string(String string); fn Timestamp os_timestamp(); fn f64 os_resolve_timestamps(Timestamp start, Timestamp end, TimeUnit time_unit); fn u8 os_is_being_debugged(); #if _WIN32 typedef void* HANDLE; fn HANDLE os_windows_get_module_handle(); #endif #if _WIN32 #define EXECUTABLE_EXTENSION ".exe" #else #define EXECUTABLE_EXTENSION "" #endif STRUCT(OSLibrary) { void* handle; }; typedef void* OSSymbol; fn OSLibrary os_library_load(const char* library_name); fn OSSymbol os_symbol_load(OSLibrary library, const char* symbol_name);