doing linux at the same time....

This commit is contained in:
ed
2025-02-07 19:46:49 -05:00
parent a4f915d27d
commit ee6a43e136
6 changed files with 378 additions and 428 deletions
+2 -1
View File
@@ -51,7 +51,8 @@
"sstream": "c", "sstream": "c",
"os_win32.h": "c", "os_win32.h": "c",
"windows.h": "c", "windows.h": "c",
"base.h": "c" "base.h": "c",
"os_linux.h": "c"
}, },
"workbench.colorCustomizations": { "workbench.colorCustomizations": {
"activityBar.activeBackground": "#713fb8", "activityBar.activeBackground": "#713fb8",
+129 -288
View File
@@ -1,117 +1,45 @@
#ifdef INTELLISENSE_DIRECTIVES
# include "os_linux.h"
# include "os/os.h"
#endif
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
//////////////////////////////// ////////////////////////////////
//~ rjf: Helpers //~ rjf: Globals
internal DateTime MD_API_C global OS_LNX_State os_lnx_state = {0};
os_lnx_date_time_from_tm(tm in, U32 msec) MD_API_C thread_static OS_LNX_SafeCallChain* os_lnx_safe_call_chain = 0;
{
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();
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Entities //~ rjf: Entities
internal OS_LNX_Entity * OS_LNX_Entity*
os_lnx_entity_alloc(OS_LNX_EntityKind kind) os_lnx_entity_alloc(OS_LNX_EntityKind kind)
{ {
OS_LNX_Entity *entity = 0; OS_LNX_Entity* entity = 0;
DeferLoop(pthread_mutex_lock(&os_lnx_state.entity_mutex), defer_loop(pthread_mutex_lock (&os_lnx_state.entity_mutex), pthread_mutex_unlock(&os_lnx_state.entity_mutex))
pthread_mutex_unlock(&os_lnx_state.entity_mutex)) {
{ entity = os_lnx_state.entity_free;
entity = os_lnx_state.entity_free; if (entity) {
if(entity) sll_stack_pop(os_lnx_state.entity_free);
{ }
SLLStackPop(os_lnx_state.entity_free); else {
} entity = push_array_no_zero(os_lnx_state.entity_arena, OS_LNX_Entity, 1);
else }
{ }
entity = push_array_no_zero(os_lnx_state.entity_arena, OS_LNX_Entity, 1); memory_zero_struct(entity);
} entity->kind = kind;
} return entity;
MemoryZeroStruct(entity);
entity->kind = kind;
return entity;
} }
internal void void
os_lnx_entity_release(OS_LNX_Entity *entity) 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))
DeferLoop(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);
{ }
SLLStackPush(os_lnx_state.entity_free, entity);
}
} }
//////////////////////////////// ////////////////////////////////
@@ -120,119 +48,43 @@ os_lnx_entity_release(OS_LNX_Entity *entity)
internal void * internal void *
os_lnx_thread_entry_point(void *ptr) os_lnx_thread_entry_point(void *ptr)
{ {
OS_LNX_Entity *entity = (OS_LNX_Entity *)ptr; OS_LNX_Entity* entity = (OS_LNX_Entity *)ptr;
OS_ThreadFunctionType *func = entity->thread.func; OS_ThreadFunctionType* func = entity->thread.func;
void *thread_ptr = entity->thread.ptr; void* thread_ptr = entity->thread.ptr;
TCTX tctx_;
tctx_init_and_equip(&tctx_); TCTX tctx_;
func(thread_ptr); tctx_init_and_equip(&tctx_);
tctx_release(); func(thread_ptr);
return 0; tctx_release();
return 0;
} }
//////////////////////////////// ////////////////////////////////
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS) //~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
internal OS_SystemInfo * OS_SystemInfo*
os_get_system_info(void) os_get_system_info(void) {
{ return &os_lnx_state.system_info;
return &os_lnx_state.system_info;
} }
internal OS_ProcessInfo * OS_ProcessInfo*
os_get_process_info(void) os_get_process_info(void) {
{
return &os_lnx_state.process_info; 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) //~ rjf: @os_hooks Thread Info (Implemented Per-OS)
internal U32 void
os_tid(void)
{
U32 result = 0;
#if defined(SYS_gettid)
result = syscall(SYS_gettid);
#else
result = gettid();
#endif
return result;
}
internal void
os_set_thread_name(String8 name) os_set_thread_name(String8 name)
{ {
Temp scratch = scratch_begin(0, 0); TempArena scratch = scratch_begin(0, 0);
String8 name_copy = push_str8_copy(scratch.arena, name); {
pthread_t current_thread = pthread_self(); String8 name_copy = push_str8_copy(scratch.arena, name);
pthread_setname_np(current_thread, (char *)name_copy.str); pthread_t current_thread = pthread_self();
scratch_end(scratch); 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);
} }
//////////////////////////////// ////////////////////////////////
@@ -240,112 +92,101 @@ os_abort(S32 exit_code)
//- rjf: files //- rjf: files
internal OS_Handle OS_Handle
os_file_open(OS_AccessFlags flags, String8 path) os_file_open(OS_AccessFlags flags, String8 path)
{ {
Temp scratch = scratch_begin(0, 0); TempArena scratch = scratch_begin(0, 0);
String8 path_copy = push_str8_copy(scratch.arena, path); {
int lnx_flags = 0; String8 path_copy = push_str8_copy(scratch.arena, path);
if(flags & (OS_AccessFlag_Read|OS_AccessFlag_Write)) int lnx_flags = 0;
{ if (flags & (OS_AccessFlag_Read | OS_AccessFlag_Write)) { lnx_flags = O_RDWR; }
lnx_flags = O_RDWR; else if (flags & OS_AccessFlag_Write) { lnx_flags = O_WRONLY; }
} else if (flags & OS_AccessFlag_Read) { lnx_flags = O_RDONLY; }
else if(flags & OS_AccessFlag_Write) if (flags & OS_AccessFlag_Append) { lnx_flags |= O_APPEND; }
{
lnx_flags = O_WRONLY; int fd = open((char *)path_copy.str, lnx_flags);
} OS_Handle handle = {0};
else if(flags & OS_AccessFlag_Read) if (fd != -1) {
{ handle.u64[0] = fd;
lnx_flags = O_RDONLY; }
} }
if(flags & OS_AccessFlag_Append) scratch_end(scratch);
{ return handle;
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) os_file_close(OS_Handle file)
{ {
if(os_handle_match(file, os_handle_zero())) { return; } if (os_handle_match(file, os_handle_zero())) { return; }
int fd = (int)file.u64[0]; int fd = (int)file.u64[0];
close(fd); close(fd);
} }
internal U64 U64
os_file_read(OS_Handle file, Rng1U64 rng, void *out_data) os_file_read(OS_Handle file, Rng1U64 rng, void* out_data)
{ {
if(os_handle_match(file, os_handle_zero())) { return 0; } if (os_handle_match(file, os_handle_zero())) { return 0; }
int fd = (int)file.u64[0];
if(rng.min != 0) int fd = (int)file.u64[0];
{ if (rng.min != 0) {
lseek(fd, rng.min, SEEK_SET); 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_to_read = dim_1u64(rng);
U64 total_num_bytes_left_to_read = total_num_bytes_to_read; U64 total_num_bytes_read = 0;
for(;total_num_bytes_left_to_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) 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_read += read_result;
total_num_bytes_left_to_read -= read_result; total_num_bytes_left_to_read -= read_result;
} }
else if(errno != EINTR) else if (errno != EINTR) {
{ break;
break; }
} }
} return total_num_bytes_read;
return total_num_bytes_read;
} }
internal U64 U64
os_file_write(OS_Handle file, Rng1U64 rng, void *data) os_file_write(OS_Handle file, Rng1U64 rng, void *data)
{ {
if(os_handle_match(file, os_handle_zero())) { return 0; } if(os_handle_match(file, os_handle_zero())) { return 0; }
int fd = (int)file.u64[0];
if(rng.min != 0) int fd = (int)file.u64[0];
{ if (rng.min != 0) {
lseek(fd, rng.min, SEEK_SET); 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_to_write = dim_1u64(rng);
U64 total_num_bytes_left_to_write = total_num_bytes_to_write; U64 total_num_bytes_written = 0;
for(;total_num_bytes_left_to_write > 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) 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_written += write_result;
total_num_bytes_left_to_write -= write_result; total_num_bytes_left_to_write -= write_result;
} }
else if(errno != EINTR) else if (errno != EINTR) {
{ break;
break; }
} }
} return total_num_bytes_written;
return total_num_bytes_written;
} }
internal B32 B32
os_file_set_times(OS_Handle file, DateTime date_time) os_file_set_times(OS_Handle file, DateTime date_time)
{ {
if(os_handle_match(file, os_handle_zero())) { return 0; } if(os_handle_match(file, os_handle_zero())) { return 0; }
int fd = (int)file.u64[0]; int fd = (int)file.u64[0];
timespec time = os_lnx_timespec_from_date_time(date_time);
timespec times[2] = {time, time}; timespec time = os_lnx_timespec_from_date_time(date_time);
int futimens_result = futimens(fd, times); timespec times[2] = {time, time};
B32 good = (futimens_result != -1); int futimens_result = futimens(fd, times);
return good; B32 good = (futimens_result != -1);
return good;
} }
internal FileProperties internal FileProperties
+165 -56
View File
@@ -28,8 +28,8 @@
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <sys/random.h> #include <sys/random.h>
int pthread_setname_np(pthread_t thread, const char *name); int pthread_setname_np(pthread_t thread, const char* name);
int pthread_getname_np(pthread_t thread, char *name, size_t size); int pthread_getname_np(pthread_t thread, char* name, size_t size);
typedef struct tm tm; typedef struct tm tm;
typedef struct timespec timespec; typedef struct timespec timespec;
@@ -40,9 +40,9 @@ typedef struct timespec timespec;
typedef struct OS_LNX_FileIter OS_LNX_FileIter; typedef struct OS_LNX_FileIter OS_LNX_FileIter;
struct OS_LNX_FileIter struct OS_LNX_FileIter
{ {
DIR* dir; DIR* dir;
struct dirent* dp; struct dirent* dp;
String8 path; String8 path;
}; };
md_assert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check); 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; typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
struct OS_LNX_SafeCallChain struct OS_LNX_SafeCallChain
{ {
OS_LNX_SafeCallChain* next; OS_LNX_SafeCallChain* next;
OS_ThreadFunctionType* fail_handler; OS_ThreadFunctionType* fail_handler;
void *ptr; void *ptr;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Entities //~ 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_Thread,
OS_LNX_EntityKind_Mutex, OS_LNX_EntityKind_Mutex,
OS_LNX_EntityKind_RWMutex, OS_LNX_EntityKind_RWMutex,
OS_LNX_EntityKind_ConditionVariable, OS_LNX_EntityKind_ConditionVariable,
} };
OS_LNX_EntityKind;
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; typedef struct OS_LNX_Entity OS_LNX_Entity;
struct OS_LNX_Entity struct OS_LNX_Entity
{ {
OS_LNX_Entity* next; OS_LNX_Entity* next;
OS_LNX_EntityKind kind; OS_LNX_EntityKind kind;
union union
{ {
struct OS_LNX_EntityThread thread;
{ pthread_mutex_t mutex_handle;
pthread_t handle; pthread_rwlock_t rwmutex_handle;
OS_ThreadFunctionType* func; struct {
void* ptr; pthread_cond_t cond_handle;
} thread; pthread_mutex_t rwlock_mutex_handle;
} cv;
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; typedef struct OS_LNX_State OS_LNX_State;
struct OS_LNX_State struct OS_LNX_State
{ {
Arena* arena; Arena* arena;
OS_SystemInfo system_info; OS_SystemInfo system_info;
OS_ProcessInfo process_info; OS_ProcessInfo process_info;
pthread_mutex_t entity_mutex; pthread_mutex_t entity_mutex;
Arena* entity_arena; Arena* entity_arena;
OS_LNX_Entity* entity_free; 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 //~ rjf: Helpers
internal DateTime os_lnx_date_time_from_tm(tm in, U32 msec); DateTime os_lnx_date_time_from_tm (tm in, U32 msec);
internal tm os_lnx_tm_from_date_time(DateTime dt); tm os_lnx_tm_from_date_time (DateTime dt);
internal timespec os_lnx_timespec_from_date_time( DateTime dt); timespec os_lnx_timespec_from_date_time (DateTime dt);
internal DenseTime os_lnx_dense_time_from_timespec(timespec in); DenseTime os_lnx_dense_time_from_timespec (timespec in);
internal FileProperties os_lnx_file_properties_from_stat(struct stat *s); FileProperties os_lnx_file_properties_from_stat(struct stat* s);
internal void os_lnx_safe_call_sig_handler (int x); void os_lnx_safe_call_sig_handler (int x);
k
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 //~ rjf: Entities
internal OS_LNX_Entity* os_lnx_entity_alloc(OS_LNX_EntityKind kind); MD_API OS_LNX_Entity* os_lnx_entity_alloc (OS_LNX_EntityKind kind);
internal void os_lnx_entity_release(OS_LNX_Entity *entity); MD_API void os_lnx_entity_release(OS_LNX_Entity* entity);
//////////////////////////////// ////////////////////////////////
//~ rjf: Thread Entry Point //~ 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); }
+2 -2
View File
@@ -303,8 +303,8 @@ os_string_from_guid(Arena* arena, OS_Guid guid) {
//////////////////////////////// ////////////////////////////////
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS) //~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
internal OS_SystemInfo *os_get_system_info(void); internal OS_SystemInfo* os_get_system_info(void);
internal OS_ProcessInfo *os_get_process_info(void); internal OS_ProcessInfo* os_get_process_info(void);
internal String8 os_get_current_path(Arena *arena); internal String8 os_get_current_path(Arena *arena);
//////////////////////////////// ////////////////////////////////
+75 -72
View File
@@ -6,7 +6,7 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // 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 //~ 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); typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription);
MD_API_C global W32_SetThreadDescription_Type* w32_SetThreadDescription_func = 0; MD_API_C global W32_SetThreadDescription_Type* w32_SetThreadDescription_func = 0;
////////////////////////////////
//~ rjf: File Info Conversion Helpers
//////////////////////////////// ////////////////////////////////
//~ rjf: Time Conversion Helpers //~ rjf: Time Conversion Helpers
@@ -190,92 +187,98 @@ os_file_open(OS_AccessFlags flags, String8 path)
} }
void void
os_file_close(OS_Handle file) os_file_close(OS_Handle file) {
{
if (os_handle_match(file, os_handle_zero())) { return; } if (os_handle_match(file, os_handle_zero())) { return; }
HANDLE handle = (HANDLE)file.u64[0]; HANDLE handle = (HANDLE)file.u64[0];
BOOL result = CloseHandle(handle); BOOL result = CloseHandle(handle);
(void)result; (void)result;
} }
internal U64 U64
os_file_read(OS_Handle file, Rng1U64 rng, void *out_data) os_file_read(OS_Handle file, Rng1U64 rng, void *out_data)
{ {
if(os_handle_match(file, os_handle_zero())) { return 0; } if (os_handle_match(file, os_handle_zero())) { return 0; }
HANDLE handle = (HANDLE)file.u64[0]; HANDLE handle = (HANDLE)file.u64[0];
// rjf: clamp range by file size // rjf: clamp range by file size
U64 size = 0; U64 size = 0;
GetFileSizeEx(handle, (LARGE_INTEGER *)&size); GetFileSizeEx(handle, (LARGE_INTEGER *)&size);
Rng1U64 rng_clamped = r1u64(ClampTop(rng.min, size), ClampTop(rng.max, size)); Rng1U64 rng_clamped = r1u64(ClampTop(rng.min, size), ClampTop(rng.max, size));
U64 total_read_size = 0; U64 total_read_size = 0;
// rjf: read loop // rjf: read loop
{ {
U64 to_read = dim_1u64(rng_clamped); U64 to_read = dim_1u64(rng_clamped);
for(U64 off = rng.min; total_read_size < to_read;) for(U64 off = rng.min; total_read_size < to_read;)
{ {
U64 amt64 = to_read - total_read_size; U64 amt64 = to_read - total_read_size;
U32 amt32 = u32_from_u64_saturate(amt64); U32 amt32 = u32_from_u64_saturate(amt64);
DWORD read_size = 0; 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; 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;
} }
internal U64 U64
os_file_write(OS_Handle file, Rng1U64 rng, void *data) os_file_write(OS_Handle file, Rng1U64 rng, void *data)
{ {
if(os_handle_match(file, os_handle_zero())) { return 0; } if(os_handle_match(file, os_handle_zero())) { return 0; }
HANDLE win_handle = (HANDLE)file.u64[0]; HANDLE win_handle = (HANDLE)file.u64[0];
U64 src_off = 0;
U64 dst_off = rng.min; U64 src_off = 0;
U64 bytes_to_write_total = rng.max-rng.min; U64 dst_off = rng.min;
U64 total_bytes_written = 0; U64 bytes_to_write_total = rng.max-rng.min;
for(;src_off < bytes_to_write_total;) 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); void* bytes_src = (void*)((U8*)data + src_off);
U32 bytes_to_write_32 = u32_from_u64_saturate(bytes_to_write_64); U64 bytes_to_write_64 = (bytes_to_write_total-src_off);
U32 bytes_written = 0; U32 bytes_to_write_32 = u32_from_u64_saturate(bytes_to_write_64);
OVERLAPPED overlapped = {0}; U32 bytes_written = 0;
overlapped.Offset = (dst_off&0x00000000ffffffffull);
overlapped.OffsetHigh = (dst_off&0xffffffff00000000ull) >> 32; OVERLAPPED overlapped = {0};
BOOL success = WriteFile(win_handle, bytes_src, bytes_to_write_32, (DWORD *)&bytes_written, &overlapped); overlapped.Offset = (dst_off&0x00000000ffffffffull);
if(success == 0) overlapped.OffsetHigh = (dst_off&0xffffffff00000000ull) >> 32;
{
break; BOOL success = WriteFile(win_handle, bytes_src, bytes_to_write_32, (DWORD *)&bytes_written, &overlapped);
} if (success == 0) {
src_off += bytes_written; break;
dst_off += bytes_written; }
total_bytes_written += bytes_written; src_off += bytes_written;
} dst_off += bytes_written;
return total_bytes_written; total_bytes_written += bytes_written;
}
return total_bytes_written;
} }
internal B32 B32
os_file_set_time(OS_Handle file, DateTime time) os_file_set_times(OS_Handle file, DateTime time)
{ {
if(os_handle_match(file, os_handle_zero())) { return 0; } if(os_handle_match(file, os_handle_zero())) { return 0; }
B32 result = 0; B32 result = 0;
HANDLE handle = (HANDLE)file.u64[0]; {
SYSTEMTIME system_time = {0}; HANDLE handle = (HANDLE)file.u64[0];
os_w32_system_time_from_date_time(&system_time, &time); SYSTEMTIME system_time = {0};
FILETIME file_time = {0}; os_w32_system_time_from_date_time(&system_time, &time);
result = (SystemTimeToFileTime(&system_time, &file_time) &&
SetFileTime(handle, &file_time, &file_time, &file_time)); FILETIME file_time = {0};
return result; result = (SystemTimeToFileTime(&system_time, &file_time) && SetFileTime(handle, &file_time, &file_time, &file_time));
}
return result;
} }
internal FileProperties internal FileProperties
+5 -9
View File
@@ -177,15 +177,7 @@ os_w32_dense_time_from_file_time(DenseTime* out, FILETIME* in) {
//~ rjf: Entity Functions //~ rjf: Entity Functions
MD_API OS_W32_Entity* os_w32_entity_alloc (OS_W32_EntityKind kind); MD_API OS_W32_Entity* os_w32_entity_alloc (OS_W32_EntityKind kind);
MD_API void os_w32_entity_release(OS_W32_Entity* entity); 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);
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Thread Entry Point //~ 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); } inline void os_abort(S32 exit_code) { ExitProcess(exit_code); }
////////////////////////////////
//~ rjf: @os_hooks File System (Implemented Per-OS)
//- rjf: files