mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-15 16:42:23 -07:00
fix clang build
This commit is contained in:
@@ -313,7 +313,7 @@ struct E_TypeState
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global read_only E_Member e_member_nil = {E_MemberKind_Null, zero_struct, {0}, {0}, 0, {0}};
|
||||
global read_only E_Member e_member_nil = {E_MemberKind_Null};
|
||||
global read_only E_Type e_type_nil = {E_TypeKind_Null};
|
||||
thread_static E_TypeState *e_type_state = 0;
|
||||
|
||||
|
||||
@@ -150,9 +150,27 @@ os_get_current_path(Arena *arena)
|
||||
{
|
||||
char *cwdir = getcwd(0, 0);
|
||||
String8 string = push_str8_copy(arena, str8_cstring(cwdir));
|
||||
free(cwdir);
|
||||
return string;
|
||||
}
|
||||
|
||||
internal U32
|
||||
os_get_process_start_time_unix(void)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
U64 start_time = 0;
|
||||
pid_t pid = getpid();
|
||||
String8 path = push_str8f(scratch.arena, "/proc/%u", pid);
|
||||
struct stat st;
|
||||
int err = stat((char*)path.str, &st);
|
||||
if(err == 0)
|
||||
{
|
||||
start_time = st.st_mtime;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return (U32)start_time;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
@@ -162,6 +180,10 @@ internal void *
|
||||
os_reserve(U64 size)
|
||||
{
|
||||
void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if(result == MAP_FAILED)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -191,6 +213,10 @@ internal void *
|
||||
os_reserve_large(U64 size)
|
||||
{
|
||||
void *result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0);
|
||||
if(result == MAP_FAILED)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -207,12 +233,7 @@ os_commit_large(void *ptr, U64 size)
|
||||
internal U32
|
||||
os_tid(void)
|
||||
{
|
||||
U32 result = 0;
|
||||
#if defined(SYS_gettid)
|
||||
result = syscall(SYS_gettid);
|
||||
#else
|
||||
result = gettid();
|
||||
#endif
|
||||
U32 result = gettid();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -246,7 +267,7 @@ 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))
|
||||
if(flags & OS_AccessFlag_Read && flags & OS_AccessFlag_Write)
|
||||
{
|
||||
lnx_flags = O_RDWR;
|
||||
}
|
||||
@@ -262,7 +283,11 @@ os_file_open(OS_AccessFlags flags, String8 path)
|
||||
{
|
||||
lnx_flags |= O_APPEND;
|
||||
}
|
||||
int fd = open((char *)path_copy.str, lnx_flags);
|
||||
if(flags & (OS_AccessFlag_Write|OS_AccessFlag_Append))
|
||||
{
|
||||
lnx_flags |= O_CREAT;
|
||||
}
|
||||
int fd = open((char *)path_copy.str, lnx_flags, 0755);
|
||||
OS_Handle handle = {0};
|
||||
if(fd != -1)
|
||||
{
|
||||
@@ -285,16 +310,12 @@ 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);
|
||||
int read_result = pread(fd, (U8 *)out_data + total_num_bytes_read, total_num_bytes_left_to_read, rng.min + total_num_bytes_read);
|
||||
if(read_result >= 0)
|
||||
{
|
||||
total_num_bytes_read += read_result;
|
||||
@@ -313,16 +334,12 @@ 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);
|
||||
int write_result = pwrite(fd, (U8 *)data + total_num_bytes_written, total_num_bytes_left_to_write, rng.min + total_num_bytes_written);
|
||||
if(write_result >= 0)
|
||||
{
|
||||
total_num_bytes_written += write_result;
|
||||
@@ -402,25 +419,23 @@ os_copy_file_path(String8 dst, String8 src)
|
||||
if(!os_handle_match(src_h, os_handle_zero()) &&
|
||||
!os_handle_match(dst_h, os_handle_zero()))
|
||||
{
|
||||
int src_fd = (int)src_h.u64[0];
|
||||
int dst_fd = (int)dst_h.u64[0];
|
||||
FileProperties src_props = os_properties_from_file(src_h);
|
||||
U64 size = src_props.size;
|
||||
U64 total_bytes_copied = 0;
|
||||
U64 bytes_left_to_copy = size;
|
||||
for(;bytes_left_to_copy > 0;)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 buffer_size = Min(bytes_left_to_copy, MB(8));
|
||||
U8 *buffer = push_array_no_zero(scratch.arena, U8, buffer_size);
|
||||
U64 bytes_read = os_file_read(src_h, r1u64(total_bytes_copied, total_bytes_copied+buffer_size), buffer);
|
||||
U64 bytes_written = os_file_write(dst_h, r1u64(total_bytes_copied, total_bytes_copied+bytes_read), buffer);
|
||||
U64 bytes_copied = Min(bytes_read, bytes_written);
|
||||
bytes_left_to_copy -= bytes_copied;
|
||||
total_bytes_copied += bytes_copied;
|
||||
scratch_end(scratch);
|
||||
if(bytes_copied == 0)
|
||||
off_t sendfile_off = total_bytes_copied;
|
||||
int send_result = sendfile(dst_fd, src_fd, &sendfile_off, bytes_left_to_copy);
|
||||
if(send_result <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
U64 bytes_copied = (U64)send_result;
|
||||
bytes_left_to_copy -= bytes_copied;
|
||||
total_bytes_copied += bytes_copied;
|
||||
}
|
||||
}
|
||||
os_file_close(src_h);
|
||||
@@ -428,6 +443,12 @@ os_copy_file_path(String8 dst, String8 src)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_move_file_path(String8 dst, String8 src)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_full_path_from_path(Arena *arena, String8 path)
|
||||
{
|
||||
@@ -455,6 +476,22 @@ os_file_path_exists(String8 path)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_folder_path_exists(String8 path)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 exists = 0;
|
||||
String8 path_copy = push_str8_copy(scratch.arena, path);
|
||||
DIR *handle = opendir((char*)path_copy.str);
|
||||
if(handle)
|
||||
{
|
||||
closedir(handle);
|
||||
exists = 1;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return exists;
|
||||
}
|
||||
|
||||
internal FileProperties
|
||||
os_properties_from_file_path(String8 path)
|
||||
{
|
||||
@@ -497,6 +534,10 @@ os_file_map_view_open(OS_Handle map, OS_AccessFlags flags, Rng1U64 range)
|
||||
if(flags & OS_AccessFlag_Read) { prot_flags |= PROT_READ; }
|
||||
int map_flags = MAP_PRIVATE;
|
||||
void *base = mmap(0, dim_1u64(range), prot_flags, map_flags, fd, range.min);
|
||||
if(base == MAP_FAILED)
|
||||
{
|
||||
base = 0;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
@@ -589,7 +630,7 @@ os_make_directory(String8 path)
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 result = 0;
|
||||
String8 path_copy = push_str8_copy(scratch.arena, path);
|
||||
if(mkdir((char*)path_copy.str, 0777) != -1)
|
||||
if(mkdir((char*)path_copy.str, 0755) != -1)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
@@ -637,6 +678,10 @@ os_shared_memory_view_open(OS_Handle handle, Rng1U64 range)
|
||||
if(os_handle_match(handle, os_handle_zero())){return 0;}
|
||||
int id = (int)handle.u64[0];
|
||||
void *base = mmap(0, dim_1u64(range), PROT_READ|PROT_WRITE, MAP_SHARED, id, range.min);
|
||||
if(base == MAP_FAILED)
|
||||
{
|
||||
base = 0;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
@@ -744,10 +789,7 @@ os_thread_launch(OS_ThreadFunctionType *func, void *ptr, void *params)
|
||||
entity->thread.func = func;
|
||||
entity->thread.ptr = ptr;
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
int pthread_result = pthread_create(&entity->thread.handle, &attr, os_lnx_thread_entry_point, entity);
|
||||
pthread_attr_destroy(&attr);
|
||||
int pthread_result = pthread_create(&entity->thread.handle, 0, os_lnx_thread_entry_point, entity);
|
||||
if(pthread_result == -1)
|
||||
{
|
||||
os_lnx_entity_release(entity);
|
||||
@@ -1025,13 +1067,26 @@ os_condition_variable_broadcast(OS_Handle cv)
|
||||
internal OS_Handle
|
||||
os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name)
|
||||
{
|
||||
NotImplemented;
|
||||
OS_Handle result = {0};
|
||||
if (name.size > 0) {
|
||||
// TODO: we need to allocate shared memory to store sem_t
|
||||
NotImplemented;
|
||||
} else {
|
||||
sem_t *s = mmap(0, sizeof(*s), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
AssertAlways(s != MAP_FAILED);
|
||||
int err = sem_init(s, 0, initial_count);
|
||||
if (err == 0) {
|
||||
result.u64[0] = (U64)s;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_semaphore_release(OS_Handle semaphore)
|
||||
{
|
||||
NotImplemented;
|
||||
int err = munmap((void*)semaphore.u64[0], sizeof(sem_t));
|
||||
AssertAlways(err == 0);
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
@@ -1049,13 +1104,37 @@ os_semaphore_close(OS_Handle semaphore)
|
||||
internal B32
|
||||
os_semaphore_take(OS_Handle semaphore, U64 endt_us)
|
||||
{
|
||||
NotImplemented;
|
||||
AssertAlways(endt_us == max_U64);
|
||||
for (;;) {
|
||||
int err = sem_wait((sem_t*)semaphore.u64[0]);
|
||||
if (err == 0) {
|
||||
break;
|
||||
} else {
|
||||
if (errno == EAGAIN) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
InvalidPath;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_semaphore_drop(OS_Handle semaphore)
|
||||
{
|
||||
NotImplemented;
|
||||
for (;;) {
|
||||
int err = sem_post((sem_t*)semaphore.u64[0]);
|
||||
if (err == 0) {
|
||||
break;
|
||||
} else {
|
||||
if (errno == EAGAIN) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
InvalidPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -1066,7 +1145,7 @@ os_library_open(String8 path)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
char *path_cstr = (char *)push_str8_copy(scratch.arena, path).str;
|
||||
void *so = dlopen(path_cstr, RTLD_LAZY);
|
||||
void *so = dlopen(path_cstr, RTLD_LAZY|RTLD_LOCAL);
|
||||
OS_Handle lib = { (U64)so };
|
||||
scratch_end(scratch);
|
||||
return lib;
|
||||
@@ -1130,14 +1209,11 @@ os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, v
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
internal OS_Guid
|
||||
internal Guid
|
||||
os_make_guid(void)
|
||||
{
|
||||
U8 random_bytes[16] = {0};
|
||||
StaticAssert(sizeof(random_bytes) == sizeof(OS_Guid), os_lnx_guid_size_check);
|
||||
getrandom(random_bytes, sizeof(random_bytes), 0);
|
||||
OS_Guid guid = {0};
|
||||
MemoryCopy(&guid, random_bytes, sizeof(random_bytes));
|
||||
Guid guid = {0};
|
||||
getrandom(guid.v, sizeof(guid.v), 0);
|
||||
guid.data3 &= 0x0fff;
|
||||
guid.data3 |= (4 << 12);
|
||||
guid.data4[0] &= 0x3f;
|
||||
@@ -1256,5 +1332,5 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
//- rjf: call into "real" entry point
|
||||
main_thread_base_entry_point(entry_point, argv, (U64)argc);
|
||||
main_thread_base_entry_point(argc, argv);
|
||||
}
|
||||
|
||||
@@ -8,24 +8,27 @@
|
||||
//~ rjf: Includes
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <features.h>
|
||||
#include <linux/limits.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t gettid(void);
|
||||
int pthread_setname_np(pthread_t thread, const char *name);
|
||||
int pthread_getname_np(pthread_t thread, char *name, size_t size);
|
||||
|
||||
|
||||
@@ -152,22 +152,89 @@ os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: GUID Helpers (Helpers, Implemented Once)
|
||||
//~ rjf: Process Launcher Helpers
|
||||
|
||||
internal String8
|
||||
os_string_from_guid(Arena *arena, OS_Guid guid)
|
||||
internal OS_Handle
|
||||
os_cmd_line_launch(String8 string)
|
||||
{
|
||||
String8 result = push_str8f(arena, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
guid.data1,
|
||||
guid.data2,
|
||||
guid.data3,
|
||||
guid.data4[0],
|
||||
guid.data4[1],
|
||||
guid.data4[2],
|
||||
guid.data4[3],
|
||||
guid.data4[4],
|
||||
guid.data4[5],
|
||||
guid.data4[6],
|
||||
guid.data4[7]);
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U8 split_chars[] = {' '};
|
||||
String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0);
|
||||
OS_Handle handle = {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 = os_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
|
||||
OS_Handle stdout_handle = {0};
|
||||
if(stdout_path.size != 0)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path);
|
||||
os_file_close(file);
|
||||
stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_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
|
||||
OS_ProcessLaunchParams params = {0};
|
||||
params.cmd_line = cmdline;
|
||||
params.path = exe_folder;
|
||||
params.inherit_env = 1;
|
||||
params.stdout_file = stdout_handle;
|
||||
handle = os_process_launch(¶ms);
|
||||
|
||||
// rjf: close stdout handle
|
||||
{
|
||||
if(stdout_path.size != 0)
|
||||
{
|
||||
os_file_close(stdout_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_cmd_line_launchf(char *fmt, ...)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
||||
OS_Handle result = os_cmd_line_launch(string);
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef struct OS_ProcessInfo OS_ProcessInfo;
|
||||
struct OS_ProcessInfo
|
||||
{
|
||||
U32 pid;
|
||||
B32 large_pages_allowed;
|
||||
String8 binary_path;
|
||||
String8 initial_path;
|
||||
String8 user_program_data_path;
|
||||
@@ -37,12 +38,13 @@ struct OS_ProcessInfo
|
||||
typedef U32 OS_AccessFlags;
|
||||
enum
|
||||
{
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
OS_AccessFlag_Inherited = (1<<6),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -78,19 +80,6 @@ struct OS_FileID
|
||||
U64 v[3];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launch Parameters
|
||||
|
||||
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
|
||||
struct OS_ProcessLaunchParams
|
||||
{
|
||||
String8List cmd_line;
|
||||
String8 path;
|
||||
String8List env;
|
||||
B32 inherit_env;
|
||||
B32 consoleless;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type
|
||||
|
||||
@@ -123,17 +112,21 @@ struct OS_HandleArray
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globally Unique IDs
|
||||
//~ rjf: Process Launch Parameters
|
||||
|
||||
typedef struct OS_Guid OS_Guid;
|
||||
struct OS_Guid
|
||||
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
|
||||
struct OS_ProcessLaunchParams
|
||||
{
|
||||
U32 data1;
|
||||
U16 data2;
|
||||
U16 data3;
|
||||
U8 data4[8];
|
||||
String8List cmd_line;
|
||||
String8 path;
|
||||
String8List env;
|
||||
B32 inherit_env;
|
||||
B32 debug_subprocesses;
|
||||
B32 consoleless;
|
||||
OS_Handle stdout_file;
|
||||
OS_Handle stderr_file;
|
||||
OS_Handle stdin_file;
|
||||
};
|
||||
StaticAssert(sizeof(OS_Guid) == 16, os_guid_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Types
|
||||
@@ -165,16 +158,18 @@ internal S64 os_file_id_compare(OS_FileID a, OS_FileID b);
|
||||
internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: GUID Helpers (Helpers, Implemented Once)
|
||||
//~ rjf: Process Launcher Helpers
|
||||
|
||||
internal String8 os_string_from_guid(Arena *arena, OS_Guid guid);
|
||||
internal OS_Handle os_cmd_line_launch(String8 string);
|
||||
internal OS_Handle os_cmd_line_launchf(char *fmt, ...);
|
||||
|
||||
////////////////////////////////
|
||||
//~ 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 String8 os_get_current_path(Arena *arena);
|
||||
internal String8 os_get_current_path(Arena *arena);
|
||||
internal U32 os_get_process_start_time_unix(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
@@ -207,14 +202,18 @@ internal void os_abort(S32 exit_code);
|
||||
internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path);
|
||||
internal void os_file_close(OS_Handle file);
|
||||
internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data);
|
||||
#define os_file_read_struct(f, off, ptr) os_file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr))
|
||||
internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data);
|
||||
internal B32 os_file_set_times(OS_Handle file, DateTime time);
|
||||
internal FileProperties os_properties_from_file(OS_Handle file);
|
||||
internal OS_FileID os_id_from_file(OS_Handle file);
|
||||
internal B32 os_file_reserve_size(OS_Handle file, U64 size);
|
||||
internal B32 os_delete_file_at_path(String8 path);
|
||||
internal B32 os_copy_file_path(String8 dst, String8 src);
|
||||
internal B32 os_move_file_path(String8 dst, String8 src);
|
||||
internal String8 os_full_path_from_path(Arena *arena, String8 path);
|
||||
internal B32 os_file_path_exists(String8 path);
|
||||
internal B32 os_folder_path_exists(String8 path);
|
||||
internal FileProperties os_properties_from_file_path(String8 path);
|
||||
|
||||
//- rjf: file maps
|
||||
@@ -320,7 +319,7 @@ internal void os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *f
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
internal OS_Guid os_make_guid(void);
|
||||
internal Guid os_make_guid(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
|
||||
|
||||
@@ -90,6 +90,18 @@ os_w32_sleep_ms_from_endt_us(U64 endt_us)
|
||||
return sleep_ms;
|
||||
}
|
||||
|
||||
internal U32
|
||||
os_w32_unix_time_from_file_time(FILETIME file_time)
|
||||
{
|
||||
U64 win32_time = ((U64)file_time.dwHighDateTime << 32) | file_time.dwLowDateTime;
|
||||
U64 unix_time64 = ((win32_time - 0x19DB1DED53E8000ULL) / 10000000);
|
||||
|
||||
Assert(unix_time64 <= max_U32);
|
||||
U32 unix_time32 = (U32)unix_time64;
|
||||
|
||||
return unix_time32;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Functions
|
||||
|
||||
@@ -167,6 +179,21 @@ os_get_current_path(Arena *arena)
|
||||
return name;
|
||||
}
|
||||
|
||||
internal U32
|
||||
os_get_process_start_time_unix(void)
|
||||
{
|
||||
HANDLE handle = GetCurrentProcess();
|
||||
FILETIME start_time = {0};
|
||||
FILETIME exit_time;
|
||||
FILETIME kernel_time;
|
||||
FILETIME user_time;
|
||||
if(GetProcessTimes(handle, &start_time, &exit_time, &kernel_time, &user_time))
|
||||
{
|
||||
return os_w32_unix_time_from_file_time(start_time);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
@@ -293,14 +320,19 @@ os_file_open(OS_AccessFlags flags, String8 path)
|
||||
DWORD access_flags = 0;
|
||||
DWORD share_mode = 0;
|
||||
DWORD creation_disposition = OPEN_EXISTING;
|
||||
if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;}
|
||||
if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;}
|
||||
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
|
||||
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
|
||||
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;}
|
||||
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
|
||||
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS;}
|
||||
HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, 0, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), 0, 0};
|
||||
if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;}
|
||||
if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;}
|
||||
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
|
||||
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
|
||||
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE|FILE_SHARE_DELETE;}
|
||||
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
|
||||
if(flags & OS_AccessFlag_Append) {creation_disposition = OPEN_ALWAYS; access_flags |= FILE_APPEND_DATA; }
|
||||
if(flags & OS_AccessFlag_Inherited)
|
||||
{
|
||||
security_attributes.bInheritHandle = 1;
|
||||
}
|
||||
HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, &security_attributes, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if(file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
result.u64[0] = (U64)file;
|
||||
@@ -361,27 +393,29 @@ os_file_write(OS_Handle file, Rng1U64 rng, void *data)
|
||||
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;)
|
||||
U64 total_write_size = dim_1u64(rng);
|
||||
for(;;)
|
||||
{
|
||||
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;
|
||||
void *bytes_src = (U8 *)data + src_off;
|
||||
U64 bytes_left = total_write_size - src_off;
|
||||
DWORD write_size = Min(MB(1), bytes_left);
|
||||
DWORD bytes_written = 0;
|
||||
OVERLAPPED overlapped = {0};
|
||||
overlapped.Offset = (dst_off&0x00000000ffffffffull);
|
||||
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);
|
||||
BOOL success = WriteFile(win_handle, bytes_src, write_size, &bytes_written, &overlapped);
|
||||
if(success == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
src_off += bytes_written;
|
||||
dst_off += bytes_written;
|
||||
total_bytes_written += bytes_written;
|
||||
if(bytes_left == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return total_bytes_written;
|
||||
return src_off;
|
||||
}
|
||||
|
||||
internal B32
|
||||
@@ -435,6 +469,19 @@ os_id_from_file(OS_Handle file)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_file_reserve_size(OS_Handle file, U64 size)
|
||||
{
|
||||
HANDLE handle = (HANDLE)file.u64[0];
|
||||
|
||||
FILE_ALLOCATION_INFO alloc_info = {0};
|
||||
alloc_info.AllocationSize.LowPart = size & max_U32;
|
||||
alloc_info.AllocationSize.HighPart = (size >> 32) & max_U32;
|
||||
|
||||
BOOL is_reserved = SetFileInformationByHandle(handle, FileAllocationInfo, &alloc_info, sizeof(alloc_info));
|
||||
return is_reserved;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_delete_file_at_path(String8 path)
|
||||
{
|
||||
@@ -456,15 +503,33 @@ os_copy_file_path(String8 dst, String8 src)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_move_file_path(String8 dst, String8 src)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String16 dst16 = str16_from_8(scratch.arena, dst);
|
||||
String16 src16 = str16_from_8(scratch.arena, src);
|
||||
B32 result = MoveFileW((WCHAR*)src16.str, (WCHAR*)dst16.str);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_full_path_from_path(Arena *arena, String8 path)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
DWORD buffer_size = MAX_PATH + 1;
|
||||
U16 *buffer = push_array_no_zero(scratch.arena, U16, buffer_size);
|
||||
String16 path16 = str16_from_8(scratch.arena, path);
|
||||
DWORD path16_size = GetFullPathNameW((WCHAR*)path16.str, buffer_size, (WCHAR*)buffer, NULL);
|
||||
String8 full_path = str8_from_16(arena, str16(buffer, path16_size));
|
||||
DWORD buffer_size = Max(MAX_PATH, path.size * 2) + 1;
|
||||
String16 path16 = str16_from_8(scratch.arena, path);
|
||||
WCHAR *buffer = push_array_no_zero(scratch.arena, WCHAR, buffer_size);
|
||||
DWORD path16_size = GetFullPathNameW((WCHAR*)path16.str, buffer_size, buffer, NULL);
|
||||
if(path16_size > buffer_size)
|
||||
{
|
||||
arena_pop(scratch.arena, buffer_size);
|
||||
buffer_size = path16_size + 1;
|
||||
buffer = push_array_no_zero(scratch.arena, WCHAR, buffer_size);
|
||||
path16_size = GetFullPathNameW((WCHAR*)path16.str, buffer_size, buffer, NULL);
|
||||
}
|
||||
String8 full_path = str8_from_16(arena, str16((U16*)buffer, path16_size));
|
||||
scratch_end(scratch);
|
||||
return full_path;
|
||||
}
|
||||
@@ -480,6 +545,17 @@ os_file_path_exists(String8 path)
|
||||
return exists;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_folder_path_exists(String8 path)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
String16 path16 = str16_from_8(scratch.arena, path);
|
||||
DWORD attributes = GetFileAttributesW((WCHAR *)path16.str);
|
||||
B32 exists = (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
scratch_end(scratch);
|
||||
return exists;
|
||||
}
|
||||
|
||||
internal FileProperties
|
||||
os_properties_from_file_path(String8 path)
|
||||
{
|
||||
@@ -495,6 +571,28 @@ os_properties_from_file_path(String8 path)
|
||||
os_w32_dense_time_from_file_time(&props.modified, &find_data.ftLastWriteTime);
|
||||
props.flags = os_w32_file_property_flags_from_dwFileAttributes(find_data.dwFileAttributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
WCHAR buffer[512] = {0};
|
||||
DWORD length = GetLogicalDriveStringsW(sizeof(buffer), buffer);
|
||||
U64 last_slash_pos = 0;
|
||||
for(;last_slash_pos < path.size; last_slash_pos = str8_find_needle(path, last_slash_pos+1, str8_lit("/"), StringMatchFlag_SlashInsensitive));
|
||||
String8 path_trimmed = str8_prefix(path, last_slash_pos);
|
||||
for(U64 off = 0; off < (U64)length;)
|
||||
{
|
||||
String16 next_drive_string_16 = str16_cstring((U16 *)buffer+off);
|
||||
off += next_drive_string_16.size+1;
|
||||
String8 next_drive_string = str8_from_16(scratch.arena, next_drive_string_16);
|
||||
next_drive_string = str8_chop_last_slash(next_drive_string);
|
||||
if(str8_match(path_trimmed, next_drive_string, StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
props.flags |= FilePropertyFlag_IsFolder;
|
||||
break;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
FindClose(handle);
|
||||
scratch_end(scratch);
|
||||
return props;
|
||||
@@ -704,7 +802,12 @@ internal void
|
||||
os_file_iter_end(OS_FileIter *iter)
|
||||
{
|
||||
OS_W32_FileIter *w32_iter = (OS_W32_FileIter*)iter->memory;
|
||||
FindClose(w32_iter->handle);
|
||||
HANDLE zero_handle;
|
||||
MemoryZeroStruct(&zero_handle);
|
||||
if(!MemoryMatchStruct(&zero_handle, &w32_iter->handle))
|
||||
{
|
||||
FindClose(w32_iter->handle);
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: directory creation
|
||||
@@ -805,10 +908,8 @@ os_now_unix(void)
|
||||
{
|
||||
FILETIME file_time;
|
||||
GetSystemTimeAsFileTime(&file_time);
|
||||
U64 win32_time = ((U64)file_time.dwHighDateTime << 32) | file_time.dwLowDateTime;
|
||||
U64 unix_time64 = ((win32_time - 0x19DB1DED53E8000ULL) / 10000000);
|
||||
U32 unix_time32 = (U32)unix_time64;
|
||||
return unix_time32;
|
||||
U32 unix_time = os_w32_unix_time_from_file_time(file_time);
|
||||
return unix_time;
|
||||
}
|
||||
|
||||
internal DateTime
|
||||
@@ -926,9 +1027,31 @@ os_process_launch(OS_ProcessLaunchParams *params)
|
||||
}
|
||||
|
||||
//- rjf: launch
|
||||
BOOL inherit_handles = 0;
|
||||
STARTUPINFOW startup_info = {sizeof(startup_info)};
|
||||
if(!os_handle_match(params->stdout_file, os_handle_zero()))
|
||||
{
|
||||
HANDLE stdout_handle = (HANDLE)params->stdout_file.u64[0];
|
||||
startup_info.hStdOutput = stdout_handle;
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
inherit_handles = 1;
|
||||
}
|
||||
if(!os_handle_match(params->stderr_file, os_handle_zero()))
|
||||
{
|
||||
HANDLE stderr_handle = (HANDLE)params->stderr_file.u64[0];
|
||||
startup_info.hStdError = stderr_handle;
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
inherit_handles = 1;
|
||||
}
|
||||
if(!os_handle_match(params->stdin_file, os_handle_zero()))
|
||||
{
|
||||
HANDLE stdin_handle = (HANDLE)params->stdin_file.u64[0];
|
||||
startup_info.hStdInput = stdin_handle;
|
||||
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||||
inherit_handles = 1;
|
||||
}
|
||||
PROCESS_INFORMATION process_info = {0};
|
||||
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 0, creation_flags, use_null_env_arg ? 0 : (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
|
||||
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, inherit_handles, creation_flags, use_null_env_arg ? 0 : (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
|
||||
{
|
||||
result.u64[0] = (U64)process_info.hProcess;
|
||||
CloseHandle(process_info.hThread);
|
||||
@@ -977,8 +1100,9 @@ os_thread_join(OS_Handle handle, U64 endt_us)
|
||||
if(entity != 0)
|
||||
{
|
||||
wait_result = WaitForSingleObject(entity->thread.handle, sleep_ms);
|
||||
CloseHandle(entity->thread.handle);
|
||||
os_w32_entity_release(entity);
|
||||
}
|
||||
os_w32_entity_release(entity);
|
||||
return (wait_result == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
@@ -986,7 +1110,11 @@ internal void
|
||||
os_thread_detach(OS_Handle thread)
|
||||
{
|
||||
OS_W32_Entity *entity = (OS_W32_Entity*)PtrFromInt(thread.u64[0]);
|
||||
os_w32_entity_release(entity);
|
||||
if(entity != 0)
|
||||
{
|
||||
CloseHandle(entity->thread.handle);
|
||||
os_w32_entity_release(entity);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -1255,10 +1383,10 @@ os_safe_call(OS_ThreadFunctionType *func, OS_ThreadFunctionType *fail_handler, v
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
internal OS_Guid
|
||||
internal Guid
|
||||
os_make_guid(void)
|
||||
{
|
||||
OS_Guid result; MemoryZeroStruct(&result);
|
||||
Guid result; MemoryZeroStruct(&result);
|
||||
UUID uuid;
|
||||
RPC_STATUS rpc_status = UuidCreate(&uuid);
|
||||
if(rpc_status == RPC_S_OK)
|
||||
@@ -1344,8 +1472,12 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
|
||||
HANDLE thread = GetCurrentThread();
|
||||
CONTEXT* context = exception_ptrs->ContextRecord;
|
||||
|
||||
WCHAR module_path[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, module_path, ArrayCount(module_path));
|
||||
PathRemoveFileSpecW(module_path);
|
||||
|
||||
dbg_SymSetOptions(SYMOPT_EXACT_SYMBOLS | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
|
||||
if(dbg_SymInitializeW(process, L"", TRUE))
|
||||
if(dbg_SymInitializeW(process, module_path, TRUE))
|
||||
{
|
||||
// check that raddbg.pdb file is good
|
||||
B32 raddbg_pdb_valid = 0;
|
||||
@@ -1384,7 +1516,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs)
|
||||
frame.AddrStack.Offset = context->Sp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
#else
|
||||
# error Architecture not supported!
|
||||
# error Arch not supported!
|
||||
#endif
|
||||
|
||||
for(U32 idx=0; ;idx++)
|
||||
@@ -1488,129 +1620,60 @@ w32_entry_point_caller(int argc, WCHAR **wargv)
|
||||
{
|
||||
SetUnhandledExceptionFilter(&win32_exception_filter);
|
||||
|
||||
//- rjf: do OS layer initialization
|
||||
//- rjf: dynamically load windows functions which are not guaranteed
|
||||
// in all SDKs
|
||||
{
|
||||
// rjf: dynamically load windows functions which are not guaranteed
|
||||
// in all SDKs
|
||||
HMODULE module = LoadLibraryA("kernel32.dll");
|
||||
w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription");
|
||||
FreeLibrary(module);
|
||||
}
|
||||
|
||||
//- rjf: try to allow large pages if we can
|
||||
B32 large_pages_allowed = 0;
|
||||
{
|
||||
HANDLE token;
|
||||
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
||||
{
|
||||
HMODULE module = LoadLibraryA("kernel32.dll");
|
||||
w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription");
|
||||
FreeLibrary(module);
|
||||
}
|
||||
|
||||
// rjf: try to enable large pages if we can
|
||||
{
|
||||
HANDLE token;
|
||||
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
||||
LUID luid;
|
||||
if(LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid))
|
||||
{
|
||||
LUID luid;
|
||||
if(LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid))
|
||||
{
|
||||
TOKEN_PRIVILEGES priv;
|
||||
priv.PrivilegeCount = 1;
|
||||
priv.Privileges[0].Luid = luid;
|
||||
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0);
|
||||
}
|
||||
CloseHandle(token);
|
||||
TOKEN_PRIVILEGES priv;
|
||||
priv.PrivilegeCount = 1;
|
||||
priv.Privileges[0].Luid = luid;
|
||||
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
large_pages_allowed = !!AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0);
|
||||
}
|
||||
CloseHandle(token);
|
||||
}
|
||||
|
||||
// rjf: get system info
|
||||
SYSTEM_INFO sysinfo = {0};
|
||||
GetSystemInfo(&sysinfo);
|
||||
|
||||
// rjf: set up non-dynamically-alloc'd state
|
||||
//
|
||||
// (we need to set up some basics before this layer can supply
|
||||
// memory allocation primitives)
|
||||
}
|
||||
|
||||
//- rjf: get system info
|
||||
SYSTEM_INFO sysinfo = {0};
|
||||
GetSystemInfo(&sysinfo);
|
||||
|
||||
//- rjf: set up non-dynamically-alloc'd state
|
||||
//
|
||||
// (we need to set up some basics before this layer can supply
|
||||
// memory allocation primitives)
|
||||
{
|
||||
os_w32_state.microsecond_resolution = 1;
|
||||
LARGE_INTEGER large_int_resolution;
|
||||
if(QueryPerformanceFrequency(&large_int_resolution))
|
||||
{
|
||||
os_w32_state.microsecond_resolution = 1;
|
||||
LARGE_INTEGER large_int_resolution;
|
||||
if(QueryPerformanceFrequency(&large_int_resolution))
|
||||
{
|
||||
os_w32_state.microsecond_resolution = large_int_resolution.QuadPart;
|
||||
}
|
||||
os_w32_state.microsecond_resolution = large_int_resolution.QuadPart;
|
||||
}
|
||||
{
|
||||
OS_SystemInfo *info = &os_w32_state.system_info;
|
||||
info->logical_processor_count = (U64)sysinfo.dwNumberOfProcessors;
|
||||
info->page_size = sysinfo.dwPageSize;
|
||||
info->large_page_size = GetLargePageMinimum();
|
||||
info->allocation_granularity = sysinfo.dwAllocationGranularity;
|
||||
}
|
||||
{
|
||||
OS_ProcessInfo *info = &os_w32_state.process_info;
|
||||
info->pid = GetCurrentProcessId();
|
||||
}
|
||||
|
||||
// rjf: set up thread context
|
||||
local_persist TCTX tctx;
|
||||
tctx_init_and_equip(&tctx);
|
||||
|
||||
// rjf: set up dynamically-alloc'd state
|
||||
Arena *arena = arena_alloc();
|
||||
{
|
||||
os_w32_state.arena = arena;
|
||||
{
|
||||
OS_SystemInfo *info = &os_w32_state.system_info;
|
||||
U8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0};
|
||||
DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
if(GetComputerNameA((char*)buffer, &size))
|
||||
{
|
||||
info->machine_name = push_str8_copy(arena, str8(buffer, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
OS_ProcessInfo *info = &os_w32_state.process_info;
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DWORD size = KB(32);
|
||||
U16 *buffer = push_array_no_zero(scratch.arena, U16, size);
|
||||
DWORD length = GetModuleFileNameW(0, (WCHAR*)buffer, size);
|
||||
String8 name8 = str8_from_16(scratch.arena, str16(buffer, length));
|
||||
String8 name_chopped = str8_chop_last_slash(name8);
|
||||
info->binary_path = push_str8_copy(arena, name_chopped);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
info->initial_path = os_get_current_path(arena);
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 size = KB(32);
|
||||
U16 *buffer = push_array_no_zero(scratch.arena, U16, size);
|
||||
if(SUCCEEDED(SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, (WCHAR*)buffer)))
|
||||
{
|
||||
info->user_program_data_path = str8_from_16(arena, str16_cstring(buffer));
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
{
|
||||
WCHAR *this_proc_env = GetEnvironmentStringsW();
|
||||
U64 start_idx = 0;
|
||||
for(U64 idx = 0;; idx += 1)
|
||||
{
|
||||
if(this_proc_env[idx] == 0)
|
||||
{
|
||||
if(start_idx == idx)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx);
|
||||
String8 string = str8_from_16(arena, string16);
|
||||
str8_list_push(arena, &info->environment, string);
|
||||
start_idx = idx+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: set up entity storage
|
||||
InitializeCriticalSection(&os_w32_state.entity_mutex);
|
||||
os_w32_state.entity_arena = arena_alloc();
|
||||
}
|
||||
{
|
||||
OS_SystemInfo *info = &os_w32_state.system_info;
|
||||
info->logical_processor_count = (U64)sysinfo.dwNumberOfProcessors;
|
||||
info->page_size = sysinfo.dwPageSize;
|
||||
info->large_page_size = GetLargePageMinimum();
|
||||
info->allocation_granularity = sysinfo.dwAllocationGranularity;
|
||||
}
|
||||
{
|
||||
OS_ProcessInfo *info = &os_w32_state.process_info;
|
||||
info->large_pages_allowed = large_pages_allowed;
|
||||
info->pid = GetCurrentProcessId();
|
||||
}
|
||||
|
||||
//- rjf: extract arguments
|
||||
@@ -1620,13 +1683,89 @@ w32_entry_point_caller(int argc, WCHAR **wargv)
|
||||
{
|
||||
String16 arg16 = str16_cstring((U16 *)wargv[i]);
|
||||
String8 arg8 = str8_from_16(args_arena, arg16);
|
||||
if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive))
|
||||
if(str8_match(arg8, str8_lit("--quiet"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(arg8, str8_lit("-quiet"), StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
win32_g_is_quiet = 1;
|
||||
}
|
||||
if(str8_match(arg8, str8_lit("--large_pages"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(arg8, str8_lit("-large_pages"), StringMatchFlag_CaseInsensitive))
|
||||
{
|
||||
arena_default_flags = ArenaFlag_LargePages;
|
||||
arena_default_reserve_size = Max(MB(64), os_w32_state.system_info.large_page_size);
|
||||
arena_default_commit_size = arena_default_reserve_size;
|
||||
}
|
||||
argv[i] = (char *)arg8.str;
|
||||
}
|
||||
|
||||
//- rjf: set up thread context
|
||||
local_persist TCTX tctx;
|
||||
tctx_init_and_equip(&tctx);
|
||||
|
||||
//- rjf: set up dynamically-alloc'd state
|
||||
Arena *arena = arena_alloc();
|
||||
{
|
||||
os_w32_state.arena = arena;
|
||||
{
|
||||
OS_SystemInfo *info = &os_w32_state.system_info;
|
||||
U8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = {0};
|
||||
DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
|
||||
if(GetComputerNameA((char*)buffer, &size))
|
||||
{
|
||||
info->machine_name = push_str8_copy(arena, str8(buffer, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
OS_ProcessInfo *info = &os_w32_state.process_info;
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DWORD size = KB(32);
|
||||
U16 *buffer = push_array_no_zero(scratch.arena, U16, size);
|
||||
DWORD length = GetModuleFileNameW(0, (WCHAR*)buffer, size);
|
||||
String8 name8 = str8_from_16(scratch.arena, str16(buffer, length));
|
||||
String8 name_chopped = str8_chop_last_slash(name8);
|
||||
info->binary_path = push_str8_copy(arena, name_chopped);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
info->initial_path = os_get_current_path(arena);
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 size = KB(32);
|
||||
U16 *buffer = push_array_no_zero(scratch.arena, U16, size);
|
||||
if(SUCCEEDED(SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, (WCHAR*)buffer)))
|
||||
{
|
||||
info->user_program_data_path = str8_from_16(arena, str16_cstring(buffer));
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
{
|
||||
WCHAR *this_proc_env = GetEnvironmentStringsW();
|
||||
U64 start_idx = 0;
|
||||
for(U64 idx = 0;; idx += 1)
|
||||
{
|
||||
if(this_proc_env[idx] == 0)
|
||||
{
|
||||
if(start_idx == idx)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
String16 string16 = str16((U16 *)this_proc_env + start_idx, idx - start_idx);
|
||||
String8 string = str8_from_16(arena, string16);
|
||||
str8_list_push(arena, &info->environment, string);
|
||||
start_idx = idx+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: set up entity storage
|
||||
InitializeCriticalSection(&os_w32_state.entity_mutex);
|
||||
os_w32_state.entity_arena = arena_alloc();
|
||||
|
||||
//- rjf: call into "real" entry point
|
||||
main_thread_base_entry_point(argc, argv);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes / Libraries
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
# define OS_FEATURE_GRAPHICAL 0
|
||||
#endif
|
||||
|
||||
#if !defined(OS_GFX_STUB)
|
||||
# define OS_GFX_STUB 0
|
||||
#endif
|
||||
|
||||
#include "metagen/metagen_os/core/metagen_os_core.h"
|
||||
|
||||
#if OS_WINDOWS
|
||||
|
||||
@@ -473,11 +473,11 @@ internal B32
|
||||
os_file_reserve_size(OS_Handle file, U64 size)
|
||||
{
|
||||
HANDLE handle = (HANDLE)file.u64[0];
|
||||
|
||||
|
||||
FILE_ALLOCATION_INFO alloc_info = {0};
|
||||
alloc_info.AllocationSize.LowPart = size & max_U32;
|
||||
alloc_info.AllocationSize.HighPart = (size >> 32) & max_U32;
|
||||
|
||||
|
||||
BOOL is_reserved = SetFileInformationByHandle(handle, FileAllocationInfo, &alloc_info, sizeof(alloc_info));
|
||||
return is_reserved;
|
||||
}
|
||||
|
||||
@@ -4335,6 +4335,9 @@ rd_view_ui(Rng2F32 rect)
|
||||
// rjf: commit edited cell string
|
||||
switch(cell->kind)
|
||||
{
|
||||
case RD_WatchCellKind_ViewUI:
|
||||
case RD_WatchCellKind_CallStackFrame:
|
||||
{}break;
|
||||
case RD_WatchCellKind_Expr:
|
||||
{
|
||||
RD_Cfg *cfg = row_info.group_cfg_child;
|
||||
@@ -10269,7 +10272,7 @@ rd_window_frame(void)
|
||||
}
|
||||
|
||||
// rjf: draw sides
|
||||
if(b->flags & UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight)
|
||||
if(b->flags & (UI_BoxFlag_DrawSideTop|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_DrawSideLeft|UI_BoxFlag_DrawSideRight))
|
||||
{
|
||||
Vec4F32 border_color = ui_color_from_tags_key_name(box->tags_key, str8_lit("border"));
|
||||
Rng2F32 r = b->rect;
|
||||
|
||||
Reference in New Issue
Block a user