From ee6a43e136322776bd10e66502dad633fc83d47a Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 7 Feb 2025 19:46:49 -0500 Subject: [PATCH] doing linux at the same time.... --- .vscode/settings.json | 3 +- code/os/linux/os_linux.c | 417 ++++++++++++--------------------------- code/os/linux/os_linux.h | 221 +++++++++++++++------ code/os/os.h | 4 +- code/os/win32/os_win32.c | 147 +++++++------- code/os/win32/os_win32.h | 14 +- 6 files changed, 378 insertions(+), 428 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2fba9f1..15d3e03 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -51,7 +51,8 @@ "sstream": "c", "os_win32.h": "c", "windows.h": "c", - "base.h": "c" + "base.h": "c", + "os_linux.h": "c" }, "workbench.colorCustomizations": { "activityBar.activeBackground": "#713fb8", diff --git a/code/os/linux/os_linux.c b/code/os/linux/os_linux.c index 9a30f6e..afdc0e0 100644 --- a/code/os/linux/os_linux.c +++ b/code/os/linux/os_linux.c @@ -1,117 +1,45 @@ +#ifdef INTELLISENSE_DIRECTIVES +# include "os_linux.h" +# include "os/os.h" +#endif + // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) //////////////////////////////// -//~ rjf: Helpers +//~ rjf: Globals -internal DateTime -os_lnx_date_time_from_tm(tm in, U32 msec) -{ - DateTime dt = {0}; - dt.sec = in.tm_sec; - dt.min = in.tm_min; - dt.hour = in.tm_hour; - dt.day = in.tm_mday-1; - dt.mon = in.tm_mon; - dt.year = in.tm_year+1900; - dt.msec = msec; - return dt; -} - -internal tm -os_lnx_tm_from_date_time(DateTime dt) -{ - tm result = {0}; - result.tm_sec = dt.sec; - result.tm_min = dt.min; - result.tm_hour= dt.hour; - result.tm_mday= dt.day+1; - result.tm_mon = dt.mon; - result.tm_year= dt.year-1900; - return result; -} - -internal timespec -os_lnx_timespec_from_date_time(DateTime dt) -{ - tm tm_val = os_lnx_tm_from_date_time(dt); - time_t seconds = timegm(&tm_val); - timespec result = {0}; - result.tv_sec = seconds; - return result; -} - -internal DenseTime -os_lnx_dense_time_from_timespec(timespec in) -{ - DenseTime result = 0; - { - struct tm tm_time = {0}; - gmtime_r(&in.tv_sec, &tm_time); - DateTime date_time = os_lnx_date_time_from_tm(tm_time, in.tv_nsec/Million(1)); - result = dense_time_from_date_time(date_time); - } - return result; -} - -internal FileProperties -os_lnx_file_properties_from_stat(struct stat *s) -{ - FileProperties props = {0}; - props.size = s->st_size; - props.created = os_lnx_dense_time_from_timespec(s->st_ctim); - props.modified = os_lnx_dense_time_from_timespec(s->st_mtim); - if(s->st_mode & S_IFDIR) - { - props.flags |= FilePropertyFlag_IsFolder; - } - return props; -} - -internal void -os_lnx_safe_call_sig_handler(int x) -{ - OS_LNX_SafeCallChain *chain = os_lnx_safe_call_chain; - if(chain != 0 && chain->fail_handler != 0) - { - chain->fail_handler(chain->ptr); - } - abort(); -} +MD_API_C global OS_LNX_State os_lnx_state = {0}; +MD_API_C thread_static OS_LNX_SafeCallChain* os_lnx_safe_call_chain = 0; //////////////////////////////// //~ rjf: Entities -internal OS_LNX_Entity * +OS_LNX_Entity* os_lnx_entity_alloc(OS_LNX_EntityKind kind) { - OS_LNX_Entity *entity = 0; - DeferLoop(pthread_mutex_lock(&os_lnx_state.entity_mutex), - pthread_mutex_unlock(&os_lnx_state.entity_mutex)) - { - entity = os_lnx_state.entity_free; - if(entity) - { - SLLStackPop(os_lnx_state.entity_free); - } - else - { - entity = push_array_no_zero(os_lnx_state.entity_arena, OS_LNX_Entity, 1); - } - } - MemoryZeroStruct(entity); - entity->kind = kind; - return entity; + OS_LNX_Entity* entity = 0; + defer_loop(pthread_mutex_lock (&os_lnx_state.entity_mutex), pthread_mutex_unlock(&os_lnx_state.entity_mutex)) + { + entity = os_lnx_state.entity_free; + if (entity) { + sll_stack_pop(os_lnx_state.entity_free); + } + else { + entity = push_array_no_zero(os_lnx_state.entity_arena, OS_LNX_Entity, 1); + } + } + memory_zero_struct(entity); + entity->kind = kind; + return entity; } -internal void -os_lnx_entity_release(OS_LNX_Entity *entity) -{ - DeferLoop(pthread_mutex_lock(&os_lnx_state.entity_mutex), - pthread_mutex_unlock(&os_lnx_state.entity_mutex)) - { - SLLStackPush(os_lnx_state.entity_free, entity); - } +void +os_lnx_entity_release(OS_LNX_Entity *entity) { + defer_loop(pthread_mutex_lock(&os_lnx_state.entity_mutex), pthread_mutex_unlock(&os_lnx_state.entity_mutex)) + { + sll_stack_push(os_lnx_state.entity_free, entity); + } } //////////////////////////////// @@ -120,119 +48,43 @@ os_lnx_entity_release(OS_LNX_Entity *entity) internal void * os_lnx_thread_entry_point(void *ptr) { - OS_LNX_Entity *entity = (OS_LNX_Entity *)ptr; - OS_ThreadFunctionType *func = entity->thread.func; - void *thread_ptr = entity->thread.ptr; - TCTX tctx_; - tctx_init_and_equip(&tctx_); - func(thread_ptr); - tctx_release(); - return 0; + OS_LNX_Entity* entity = (OS_LNX_Entity *)ptr; + OS_ThreadFunctionType* func = entity->thread.func; + void* thread_ptr = entity->thread.ptr; + + TCTX tctx_; + tctx_init_and_equip(&tctx_); + func(thread_ptr); + tctx_release(); + return 0; } //////////////////////////////// //~ rjf: @os_hooks System/Process Info (Implemented Per-OS) -internal OS_SystemInfo * -os_get_system_info(void) -{ - return &os_lnx_state.system_info; +OS_SystemInfo* +os_get_system_info(void) { + return &os_lnx_state.system_info; } -internal OS_ProcessInfo * -os_get_process_info(void) -{ +OS_ProcessInfo* +os_get_process_info(void) { return &os_lnx_state.process_info; } -internal String8 -os_get_current_path(Arena *arena) -{ - char *cwdir = getcwd(0, 0); - String8 string = push_str8_copy(arena, str8_cstring(cwdir)); - return string; -} - -//////////////////////////////// -//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS) - -//- rjf: basic - -internal void * -os_reserve(U64 size) -{ - void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - return result; -} - -internal B32 -os_commit(void *ptr, U64 size) -{ - mprotect(ptr, size, PROT_READ|PROT_WRITE); - return 1; -} - -internal void -os_decommit(void *ptr, U64 size) -{ - madvise(ptr, size, MADV_DONTNEED); - mprotect(ptr, size, PROT_NONE); -} - -internal void -os_release(void *ptr, U64 size) -{ - munmap(ptr, size); -} - -//- rjf: large pages - -internal void * -os_reserve_large(U64 size) -{ - void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0); - return result; -} - -internal B32 -os_commit_large(void *ptr, U64 size) -{ - mprotect(ptr, size, PROT_READ|PROT_WRITE); - return 1; -} - //////////////////////////////// //~ rjf: @os_hooks Thread Info (Implemented Per-OS) -internal U32 -os_tid(void) -{ - U32 result = 0; -#if defined(SYS_gettid) - result = syscall(SYS_gettid); -#else - result = gettid(); -#endif - return result; -} - -internal void +void os_set_thread_name(String8 name) { - Temp scratch = scratch_begin(0, 0); - String8 name_copy = push_str8_copy(scratch.arena, name); - pthread_t current_thread = pthread_self(); - pthread_setname_np(current_thread, (char *)name_copy.str); - scratch_end(scratch); -} - -//////////////////////////////// -//~ rjf: @os_hooks Aborting (Implemented Per-OS) - -internal void -os_abort(S32 exit_code) -{ - exit(exit_code); + TempArena scratch = scratch_begin(0, 0); + { + String8 name_copy = push_str8_copy(scratch.arena, name); + pthread_t current_thread = pthread_self(); + pthread_setname_np(current_thread, (char *)name_copy.str); + } + scratch_end(scratch); } //////////////////////////////// @@ -240,112 +92,101 @@ os_abort(S32 exit_code) //- rjf: files -internal OS_Handle +OS_Handle os_file_open(OS_AccessFlags flags, String8 path) { - Temp scratch = scratch_begin(0, 0); - String8 path_copy = push_str8_copy(scratch.arena, path); - int lnx_flags = 0; - if(flags & (OS_AccessFlag_Read|OS_AccessFlag_Write)) - { - lnx_flags = O_RDWR; - } - else if(flags & OS_AccessFlag_Write) - { - lnx_flags = O_WRONLY; - } - else if(flags & OS_AccessFlag_Read) - { - lnx_flags = O_RDONLY; - } - if(flags & OS_AccessFlag_Append) - { - lnx_flags |= O_APPEND; - } - int fd = open((char *)path_copy.str, lnx_flags); - OS_Handle handle = {0}; - if(fd != -1) - { - handle.u64[0] = fd; - } - scratch_end(scratch); - return handle; + TempArena scratch = scratch_begin(0, 0); + { + String8 path_copy = push_str8_copy(scratch.arena, path); + int lnx_flags = 0; + if (flags & (OS_AccessFlag_Read | OS_AccessFlag_Write)) { lnx_flags = O_RDWR; } + else if (flags & OS_AccessFlag_Write) { lnx_flags = O_WRONLY; } + else if (flags & OS_AccessFlag_Read) { lnx_flags = O_RDONLY; } + if (flags & OS_AccessFlag_Append) { lnx_flags |= O_APPEND; } + + int fd = open((char *)path_copy.str, lnx_flags); + OS_Handle handle = {0}; + if (fd != -1) { + handle.u64[0] = fd; + } + } + scratch_end(scratch); + return handle; } -internal void +void os_file_close(OS_Handle file) { - if(os_handle_match(file, os_handle_zero())) { return; } - int fd = (int)file.u64[0]; - close(fd); + if (os_handle_match(file, os_handle_zero())) { return; } + int fd = (int)file.u64[0]; + close(fd); } -internal U64 -os_file_read(OS_Handle file, Rng1U64 rng, void *out_data) +U64 +os_file_read(OS_Handle file, Rng1U64 rng, void* out_data) { - if(os_handle_match(file, os_handle_zero())) { return 0; } - int fd = (int)file.u64[0]; - if(rng.min != 0) - { - lseek(fd, rng.min, SEEK_SET); - } - U64 total_num_bytes_to_read = dim_1u64(rng); - U64 total_num_bytes_read = 0; - U64 total_num_bytes_left_to_read = total_num_bytes_to_read; - for(;total_num_bytes_left_to_read > 0;) - { - int read_result = read(fd, (U8 *)out_data + total_num_bytes_read, total_num_bytes_left_to_read); - if(read_result >= 0) - { - total_num_bytes_read += read_result; - total_num_bytes_left_to_read -= read_result; - } - else if(errno != EINTR) - { - break; - } - } - return total_num_bytes_read; + if (os_handle_match(file, os_handle_zero())) { return 0; } + + int fd = (int)file.u64[0]; + if (rng.min != 0) { + lseek(fd, rng.min, SEEK_SET); + } + + U64 total_num_bytes_to_read = dim_1u64(rng); + U64 total_num_bytes_read = 0; + U64 total_num_bytes_left_to_read = total_num_bytes_to_read; + for (;total_num_bytes_left_to_read > 0;) +{ + int read_result = read(fd, (U8 *)out_data + total_num_bytes_read, total_num_bytes_left_to_read); + if (read_result >= 0) { + total_num_bytes_read += read_result; + total_num_bytes_left_to_read -= read_result; + } + else if (errno != EINTR) { + break; + } + } + return total_num_bytes_read; } -internal U64 +U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data) { - if(os_handle_match(file, os_handle_zero())) { return 0; } - int fd = (int)file.u64[0]; - if(rng.min != 0) - { - lseek(fd, rng.min, SEEK_SET); - } - U64 total_num_bytes_to_write = dim_1u64(rng); - U64 total_num_bytes_written = 0; - U64 total_num_bytes_left_to_write = total_num_bytes_to_write; - for(;total_num_bytes_left_to_write > 0;) - { - int write_result = write(fd, (U8 *)data + total_num_bytes_written, total_num_bytes_left_to_write); - if(write_result >= 0) - { - total_num_bytes_written += write_result; - total_num_bytes_left_to_write -= write_result; - } - else if(errno != EINTR) - { - break; - } - } - return total_num_bytes_written; + if(os_handle_match(file, os_handle_zero())) { return 0; } + + int fd = (int)file.u64[0]; + if (rng.min != 0) { + lseek(fd, rng.min, SEEK_SET); + } + + U64 total_num_bytes_to_write = dim_1u64(rng); + U64 total_num_bytes_written = 0; + U64 total_num_bytes_left_to_write = total_num_bytes_to_write; + for (;total_num_bytes_left_to_write > 0;) + { + int write_result = write(fd, (U8*)data + total_num_bytes_written, total_num_bytes_left_to_write); + if (write_result >= 0) { + total_num_bytes_written += write_result; + total_num_bytes_left_to_write -= write_result; + } + else if (errno != EINTR) { + break; + } + } + return total_num_bytes_written; } -internal B32 +B32 os_file_set_times(OS_Handle file, DateTime date_time) { - if(os_handle_match(file, os_handle_zero())) { return 0; } - int fd = (int)file.u64[0]; - timespec time = os_lnx_timespec_from_date_time(date_time); - timespec times[2] = {time, time}; - int futimens_result = futimens(fd, times); - B32 good = (futimens_result != -1); - return good; + if(os_handle_match(file, os_handle_zero())) { return 0; } + int fd = (int)file.u64[0]; + + timespec time = os_lnx_timespec_from_date_time(date_time); + timespec times[2] = {time, time}; + int futimens_result = futimens(fd, times); + B32 good = (futimens_result != -1); + return good; } internal FileProperties diff --git a/code/os/linux/os_linux.h b/code/os/linux/os_linux.h index e2f0076..991ca74 100644 --- a/code/os/linux/os_linux.h +++ b/code/os/linux/os_linux.h @@ -28,8 +28,8 @@ #include #include -int pthread_setname_np(pthread_t thread, const char *name); -int pthread_getname_np(pthread_t thread, char *name, size_t size); +int pthread_setname_np(pthread_t thread, const char* name); +int pthread_getname_np(pthread_t thread, char* name, size_t size); typedef struct tm tm; typedef struct timespec timespec; @@ -40,9 +40,9 @@ typedef struct timespec timespec; typedef struct OS_LNX_FileIter OS_LNX_FileIter; struct OS_LNX_FileIter { - DIR* dir; - struct dirent* dp; - String8 path; + DIR* dir; + struct dirent* dp; + String8 path; }; md_assert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check); @@ -52,46 +52,46 @@ md_assert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain; struct OS_LNX_SafeCallChain { - OS_LNX_SafeCallChain* next; - OS_ThreadFunctionType* fail_handler; - void *ptr; + OS_LNX_SafeCallChain* next; + OS_ThreadFunctionType* fail_handler; + void *ptr; }; //////////////////////////////// //~ rjf: Entities -typedef enum OS_LNX_EntityKind +typedef enum OS_LNX_EntityKind OS_LNX_EntityKind +enum OS_LNX_EntityKind { - OS_LNX_EntityKind_Thread, - OS_LNX_EntityKind_Mutex, - OS_LNX_EntityKind_RWMutex, - OS_LNX_EntityKind_ConditionVariable, -} -OS_LNX_EntityKind; + OS_LNX_EntityKind_Thread, + OS_LNX_EntityKind_Mutex, + OS_LNX_EntityKind_RWMutex, + OS_LNX_EntityKind_ConditionVariable, +}; + +typedef struct OS_LNX_EntityThread OS_LNX_EntityThread; +struct OS_LNX_EntityThread +{ + pthread_t handle; + OS_ThreadFunctionType* func; + void* ptr; +}; typedef struct OS_LNX_Entity OS_LNX_Entity; struct OS_LNX_Entity { - OS_LNX_Entity* next; - OS_LNX_EntityKind kind; - union - { - struct - { - pthread_t handle; - OS_ThreadFunctionType* func; - void* ptr; - } thread; - - pthread_mutex_t mutex_handle; - pthread_rwlock_t rwmutex_handle; - - struct - { - pthread_cond_t cond_handle; - pthread_mutex_t rwlock_mutex_handle; - } cv; - }; + OS_LNX_Entity* next; + OS_LNX_EntityKind kind; + union + { + OS_LNX_EntityThread thread; + pthread_mutex_t mutex_handle; + pthread_rwlock_t rwmutex_handle; + struct { + pthread_cond_t cond_handle; + pthread_mutex_t rwlock_mutex_handle; + } cv; + }; }; //////////////////////////////// @@ -100,37 +100,146 @@ struct OS_LNX_Entity typedef struct OS_LNX_State OS_LNX_State; struct OS_LNX_State { - Arena* arena; - OS_SystemInfo system_info; - OS_ProcessInfo process_info; - pthread_mutex_t entity_mutex; - Arena* entity_arena; - OS_LNX_Entity* entity_free; + Arena* arena; + OS_SystemInfo system_info; + OS_ProcessInfo process_info; + pthread_mutex_t entity_mutex; + Arena* entity_arena; + OS_LNX_Entity* entity_free; }; -k -//////////////////////////////// -//~ rjf: Globals -global OS_LNX_State os_lnx_state = {0}; -thread_static OS_LNX_SafeCallChain *os_lnx_safe_call_chain = 0; //////////////////////////////// //~ rjf: Helpers -internal DateTime os_lnx_date_time_from_tm(tm in, U32 msec); -internal tm os_lnx_tm_from_date_time(DateTime dt); -internal timespec os_lnx_timespec_from_date_time( DateTime dt); -internal DenseTime os_lnx_dense_time_from_timespec(timespec in); -internal FileProperties os_lnx_file_properties_from_stat(struct stat *s); -internal void os_lnx_safe_call_sig_handler (int x); -k +DateTime os_lnx_date_time_from_tm (tm in, U32 msec); +tm os_lnx_tm_from_date_time (DateTime dt); +timespec os_lnx_timespec_from_date_time (DateTime dt); +DenseTime os_lnx_dense_time_from_timespec (timespec in); +FileProperties os_lnx_file_properties_from_stat(struct stat* s); +void os_lnx_safe_call_sig_handler (int x); + +inline DateTime +os_lnx_date_time_from_tm(tm in, U32 msec) { + DateTime dt = {0}; + dt.sec = in.tm_sec; + dt.min = in.tm_min; + dt.hour = in.tm_hour; + + dt.day = in.tm_mday-1; + dt.mon = in.tm_mon; + dt.year = in.tm_year+1900; + dt.msec = msec; + return dt; +} + +inline tm +os_lnx_tm_from_date_time(DateTime dt) { + tm result = {0}; + result.tm_sec = dt.sec; + result.tm_min = dt.min; + result.tm_hour= dt.hour; + + result.tm_mday= dt.day+1; + result.tm_mon = dt.mon; + result.tm_year= dt.year-1900; + return result; +} + +inline timespec +os_lnx_timespec_from_date_time(DateTime dt) { + tm tm_val = os_lnx_tm_from_date_time(dt); + time_t seconds = timegm(&tm_val); + timespec result = {0}; + result.tv_sec = seconds; + return result; +} + +inline DenseTime +os_lnx_dense_time_from_timespec(timespec in) { + DenseTime result = 0; { + struct tm tm_time = {0}; + gmtime_r(&in.tv_sec, &tm_time); + DateTime date_time = os_lnx_date_time_from_tm(tm_time, in.tv_nsec/Million(1)); + result = dense_time_from_date_time(date_time); + } + return result; +} + +inline FileProperties +os_lnx_file_properties_from_stat(struct stat* s) { + FileProperties props = {0}; + props.size = s->st_size; + props.created = os_lnx_dense_time_from_timespec(s->st_ctim); + props.modified = os_lnx_dense_time_from_timespec(s->st_mtim); + if (s->st_mode & S_IFDIR) { + props.flags |= FilePropertyFlag_IsFolder; + } + return props; +} + +inline void +os_lnx_safe_call_sig_handler(int x) { + OS_LNX_SafeCallChain* chain = os_lnx_safe_call_chain; + if (chain != 0 && chain->fail_handler != 0) { + chain->fail_handler(chain->ptr); + } + abort(); +} + //////////////////////////////// //~ rjf: Entities -internal OS_LNX_Entity* os_lnx_entity_alloc(OS_LNX_EntityKind kind); -internal void os_lnx_entity_release(OS_LNX_Entity *entity); +MD_API OS_LNX_Entity* os_lnx_entity_alloc (OS_LNX_EntityKind kind); +MD_API void os_lnx_entity_release(OS_LNX_Entity* entity); //////////////////////////////// //~ rjf: Thread Entry Point -internal void *os_lnx_thread_entry_point(void *ptr); +void* os_lnx_thread_entry_point(void* ptr); + +//////////////////////////////// +//~ rjf: @os_hooks System/Process Info (Implemented Per-OS) + +String8 +os_get_current_path(Arena* arena) { + char* cwdir = getcwd(0, 0); + String8 string = push_str8_copy(arena, str8_cstring(cwdir)); + return string; +} + +//////////////////////////////// +//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS) + +//- rjf: basic + +inline void* os_reserve ( U64 size) { void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return result; } +inline B32 os_commit (void *ptr, U64 size) { mprotect(ptr, size, PROT_READ | PROT_WRITE); return 1; } +inline void os_decommit(void *ptr, U64 size) { madvise(ptr, size, MADV_DONTNEED); mprotect(ptr, size, PROT_NONE); } +inline void os_release (void *ptr, U64 size) { munmap(ptr, size); } + +//- rjf: large pages + +inline void* os_reserve_large( U64 size) { void* result = mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); return result; } +inline B32 os_commit_large (void *ptr, U64 size) { mprotect(ptr, size, PROT_READ | PROT_WRITE); return 1; } + +//////////////////////////////// +//~ rjf: @os_hooks Thread Info (Implemented Per-OS) + +inline U32 +os_tid(void) { + U32 result = 0; +#if defined(SYS_gettid) + result = syscall(SYS_gettid); +#else + result = gettid(); +#endif + return result; +} + +//////////////////////////////// +//~ rjf: @os_hooks Aborting (Implemented Per-OS) + +inline void os_abort(S32 exit_code) { exit(exit_code); } + + diff --git a/code/os/os.h b/code/os/os.h index 03fc26b..c37cc2a 100644 --- a/code/os/os.h +++ b/code/os/os.h @@ -303,8 +303,8 @@ os_string_from_guid(Arena* arena, OS_Guid guid) { //////////////////////////////// //~ rjf: @os_hooks System/Process Info (Implemented Per-OS) -internal OS_SystemInfo *os_get_system_info(void); -internal OS_ProcessInfo *os_get_process_info(void); +internal OS_SystemInfo* os_get_system_info(void); +internal OS_ProcessInfo* os_get_process_info(void); internal String8 os_get_current_path(Arena *arena); //////////////////////////////// diff --git a/code/os/win32/os_win32.c b/code/os/win32/os_win32.c index 90ff7e7..4f40e5e 100644 --- a/code/os/win32/os_win32.c +++ b/code/os/win32/os_win32.c @@ -6,7 +6,7 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -MD_API global OS_W32_State os_w32_state = {0}; +MD_API_C global OS_W32_State os_w32_state = {0}; //////////////////////////////// //~ rjf: Modern Windows SDK Functions @@ -16,9 +16,6 @@ MD_API global OS_W32_State os_w32_state = {0}; typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription); MD_API_C global W32_SetThreadDescription_Type* w32_SetThreadDescription_func = 0; -//////////////////////////////// -//~ rjf: File Info Conversion Helpers - //////////////////////////////// //~ rjf: Time Conversion Helpers @@ -190,92 +187,98 @@ os_file_open(OS_AccessFlags flags, String8 path) } void -os_file_close(OS_Handle file) -{ +os_file_close(OS_Handle file) { if (os_handle_match(file, os_handle_zero())) { return; } HANDLE handle = (HANDLE)file.u64[0]; BOOL result = CloseHandle(handle); (void)result; } -internal U64 +U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data) { - if(os_handle_match(file, os_handle_zero())) { return 0; } - HANDLE handle = (HANDLE)file.u64[0]; + if (os_handle_match(file, os_handle_zero())) { return 0; } + HANDLE handle = (HANDLE)file.u64[0]; - // rjf: clamp range by file size - U64 size = 0; - GetFileSizeEx(handle, (LARGE_INTEGER *)&size); - Rng1U64 rng_clamped = r1u64(ClampTop(rng.min, size), ClampTop(rng.max, size)); - U64 total_read_size = 0; + // rjf: clamp range by file size + U64 size = 0; + GetFileSizeEx(handle, (LARGE_INTEGER *)&size); + Rng1U64 rng_clamped = r1u64(ClampTop(rng.min, size), ClampTop(rng.max, size)); + U64 total_read_size = 0; - // rjf: read loop - { - U64 to_read = dim_1u64(rng_clamped); - for(U64 off = rng.min; total_read_size < to_read;) - { - U64 amt64 = to_read - total_read_size; - U32 amt32 = u32_from_u64_saturate(amt64); - DWORD read_size = 0; - OVERLAPPED overlapped = {0}; - overlapped.Offset = (off&0x00000000ffffffffull); - overlapped.OffsetHigh = (off&0xffffffff00000000ull) >> 32; - ReadFile(handle, (U8 *)out_data + total_read_size, amt32, &read_size, &overlapped); - off += read_size; - total_read_size += read_size; - if(read_size != amt32) - { - break; - } - } - } + // rjf: read loop + { + U64 to_read = dim_1u64(rng_clamped); + for(U64 off = rng.min; total_read_size < to_read;) + { + U64 amt64 = to_read - total_read_size; + U32 amt32 = u32_from_u64_saturate(amt64); + DWORD read_size = 0; + + OVERLAPPED overlapped = {0}; + overlapped.Offset = (off&0x00000000ffffffffull); + overlapped.OffsetHigh = (off&0xffffffff00000000ull) >> 32; + + ReadFile(handle, (U8 *)out_data + total_read_size, amt32, &read_size, &overlapped); + + off += read_size; + total_read_size += read_size; + if (read_size != amt32) { + break; + } + } + } - return total_read_size; + return total_read_size; } -internal U64 +U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data) { - if(os_handle_match(file, os_handle_zero())) { return 0; } - HANDLE win_handle = (HANDLE)file.u64[0]; - U64 src_off = 0; - U64 dst_off = rng.min; - U64 bytes_to_write_total = rng.max-rng.min; - U64 total_bytes_written = 0; - for(;src_off < bytes_to_write_total;) - { - void *bytes_src = (void *)((U8 *)data + src_off); - U64 bytes_to_write_64 = (bytes_to_write_total-src_off); - U32 bytes_to_write_32 = u32_from_u64_saturate(bytes_to_write_64); - U32 bytes_written = 0; - OVERLAPPED overlapped = {0}; - overlapped.Offset = (dst_off&0x00000000ffffffffull); - overlapped.OffsetHigh = (dst_off&0xffffffff00000000ull) >> 32; - BOOL success = WriteFile(win_handle, bytes_src, bytes_to_write_32, (DWORD *)&bytes_written, &overlapped); - if(success == 0) - { - break; - } - src_off += bytes_written; - dst_off += bytes_written; - total_bytes_written += bytes_written; - } - return total_bytes_written; + if(os_handle_match(file, os_handle_zero())) { return 0; } + HANDLE win_handle = (HANDLE)file.u64[0]; + + U64 src_off = 0; + U64 dst_off = rng.min; + U64 bytes_to_write_total = rng.max-rng.min; + U64 total_bytes_written = 0; + for (;src_off < bytes_to_write_total;) + { + void* bytes_src = (void*)((U8*)data + src_off); + U64 bytes_to_write_64 = (bytes_to_write_total-src_off); + U32 bytes_to_write_32 = u32_from_u64_saturate(bytes_to_write_64); + U32 bytes_written = 0; + + OVERLAPPED overlapped = {0}; + overlapped.Offset = (dst_off&0x00000000ffffffffull); + overlapped.OffsetHigh = (dst_off&0xffffffff00000000ull) >> 32; + + BOOL success = WriteFile(win_handle, bytes_src, bytes_to_write_32, (DWORD *)&bytes_written, &overlapped); + if (success == 0) { + break; + } + src_off += bytes_written; + dst_off += bytes_written; + total_bytes_written += bytes_written; + } + + return total_bytes_written; } -internal B32 -os_file_set_time(OS_Handle file, DateTime time) +B32 +os_file_set_times(OS_Handle file, DateTime time) { - if(os_handle_match(file, os_handle_zero())) { return 0; } - B32 result = 0; - HANDLE handle = (HANDLE)file.u64[0]; - SYSTEMTIME system_time = {0}; - os_w32_system_time_from_date_time(&system_time, &time); - FILETIME file_time = {0}; - result = (SystemTimeToFileTime(&system_time, &file_time) && - SetFileTime(handle, &file_time, &file_time, &file_time)); - return result; + if(os_handle_match(file, os_handle_zero())) { return 0; } + B32 result = 0; + { + HANDLE handle = (HANDLE)file.u64[0]; + SYSTEMTIME system_time = {0}; + os_w32_system_time_from_date_time(&system_time, &time); + + FILETIME file_time = {0}; + result = (SystemTimeToFileTime(&system_time, &file_time) && SetFileTime(handle, &file_time, &file_time, &file_time)); + } + return result; } internal FileProperties diff --git a/code/os/win32/os_win32.h b/code/os/win32/os_win32.h index f966cbf..229649c 100644 --- a/code/os/win32/os_win32.h +++ b/code/os/win32/os_win32.h @@ -177,15 +177,7 @@ os_w32_dense_time_from_file_time(DenseTime* out, FILETIME* in) { //~ rjf: Entity Functions MD_API OS_W32_Entity* os_w32_entity_alloc (OS_W32_EntityKind kind); -MD_API void os_w32_entity_release(OS_W32_Entity* entity); - -inline void -os_w32_entity_release(OS_W32_Entity *entity) { - entity->kind = OS_W32_EntityKind_Null; - EnterCriticalSection(&os_w32_state.entity_mutex); - sll_stack_push(os_w32_state.entity_free, entity); - LeaveCriticalSection(&os_w32_state.entity_mutex); -} +MD_API void os_w32_entity_release(OS_W32_Entity* entity); //////////////////////////////// //~ rjf: Thread Entry Point @@ -245,4 +237,8 @@ inline U32 os_tid(void) { DWORD id = GetCurrentThreadId(); return (U32)id; } inline void os_abort(S32 exit_code) { ExitProcess(exit_code); } +//////////////////////////////// +//~ rjf: @os_hooks File System (Implemented Per-OS) + +//- rjf: files