Files
ed 3e064f6443 progress on sanity_tests.c, adding back md_str8_styllize
Eventually a heavy reduction of base & OS should be provided via libgen or done here to reduce the overall surface area of the library for the user.
Base and os were dragged from raddbg and the original metadesk didn't need as many definitions.
2025-02-13 09:53:46 -05:00

210 lines
6.1 KiB
C

#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "base/strings.h"
# include "base/thread_context.h"
# include "os.h"
# include "os_win32_includes.h"
#endif
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: File Iterator Types
typedef struct MD_OS_W32_FileIter MD_OS_W32_FileIter;
struct MD_OS_W32_FileIter
{
HANDLE handle;
WIN32_FIND_DATAW find_data;
MD_B32 is_volume_iter;
MD_String8Array drive_strings;
MD_U64 drive_strings_iter_idx;
};
md_static_assert(sizeof(md_member(MD_OS_FileIter, memory)) >= sizeof(MD_OS_W32_FileIter), file_iter_memory_size);
////////////////////////////////
//~ rjf: Entity Types
typedef enum MD_OS_W32_EntityKind MD_OS_W32_EntityKind;
enum MD_OS_W32_EntityKind
{
MD_OS_W32_EntityKind_Null,
MD_OS_W32_EntityKind_Thread,
MD_OS_W32_EntityKind_Mutex,
MD_OS_W32_EntityKind_RWMutex,
MD_OS_W32_EntityKind_ConditionVariable,
};
typedef struct MD_OS_W32_EntityThread MD_OS_W32_EntityThread;
struct MD_OS_W32_EntityThread
{
MD_OS_ThreadFunctionType* func;
void* ptr;
HANDLE handle;
DWORD tid;
};
typedef struct MD_OS_W32_Entity MD_OS_W32_Entity;
struct MD_OS_W32_Entity
{
MD_OS_W32_Entity* next;
MD_OS_W32_EntityKind kind;
union
{
MD_OS_W32_EntityThread thread;
CRITICAL_SECTION mutex;
SRWLOCK rw_mutex;
CONDITION_VARIABLE cv;
};
};
////////////////////////////////
//~ rjf: State
typedef struct MD_OS_W32_State MD_OS_W32_State;
struct MD_OS_W32_State
{
MD_Arena* arena;
// rjf: info
MD_OS_SystemInfo system_info;
MD_OS_ProcessInfo process_info;
MD_U64 microsecond_resolution;
// rjf: entity storage
CRITICAL_SECTION entity_mutex;
MD_Arena* entity_arena;
MD_OS_W32_Entity* entity_free;
};
////////////////////////////////
//~ rjf: Globals
MD_API extern MD_OS_W32_State md_os_w32_state;
////////////////////////////////
//~ rjf: Time Conversion Helpers
void md_os_w32_date_time_from_system_time(MD_DateTime* out, SYSTEMTIME* in);
void md_os_w32_system_time_from_date_time(SYSTEMTIME* out, MD_DateTime* in);
void md_os_w32_dense_time_from_file_time (MD_DenseTime* out, FILETIME* in);
MD_API MD_U32 md_os_w32_sleep_ms_from_endt_us(MD_U64 endt_us);
inline void
md_os_w32_date_time_from_system_time(MD_DateTime* out, SYSTEMTIME* in)
{
out->year = in->wYear;
out->mon = in->wMonth - 1;
out->wday = in->wDayOfWeek;
out->day = in->wDay;
out->hour = in->wHour;
out->min = in->wMinute;
out->sec = in->wSecond;
out->msec = in->wMilliseconds;
}
inline void
md_os_w32_system_time_from_date_time(SYSTEMTIME* out, MD_DateTime* in)
{
out->wYear = (WORD)(in->year);
out->wMonth = in->mon + 1;
out->wDay = in->day;
out->wHour = in->hour;
out->wMinute = in->min;
out->wSecond = in->sec;
out->wMilliseconds = in->msec;
}
inline void
md_os_w32_dense_time_from_file_time(MD_DenseTime* out, FILETIME* in) {
SYSTEMTIME systime = {0};
MD_DateTime date_time = {0};
FileTimeToSystemTime(in, &systime);
md_os_w32_date_time_from_system_time(&date_time, &systime);
*out = md_dense_time_from_date_time(date_time);
}
////////////////////////////////
//~ rjf: File Info Conversion Helpers
inline MD_FilePropertyFlags
md_os_w32_file_property_flags_from_dwFileAttributes(DWORD dwFileAttributes)
{
MD_FilePropertyFlags flags = 0;
if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
flags |= MD_FilePropertyFlag_IsFolder;
}
return flags;
}
inline void
md_os_w32_file_properties_from_attribute_data(MD_FileProperties* properties, WIN32_FILE_ATTRIBUTE_DATA* attributes) {
properties->size = md_compose_64bit(attributes->nFileSizeHigh, attributes->nFileSizeLow);
md_os_w32_dense_time_from_file_time(&properties->created, &attributes->ftCreationTime);
md_os_w32_dense_time_from_file_time(&properties->modified, &attributes->ftLastWriteTime);
properties->flags = md_os_w32_file_property_flags_from_dwFileAttributes(attributes->dwFileAttributes);
}
////////////////////////////////
//~ rjf: Entity Functions
MD_API MD_OS_W32_Entity* md_os_w32_entity_alloc (MD_OS_W32_EntityKind kind);
MD_API void md_os_w32_entity_release(MD_OS_W32_Entity* entity);
////////////////////////////////
//~ rjf: Thread Entry Point
MD_API DWORD md_os_w32_thread_entry_point(void* ptr);
////////////////////////////////
//~ rjf: @md_os_hooks System/Process Info (Implemented Per-OS)
inline MD_String8
md_os_get_current_path__ainfo(MD_AllocatorInfo ainfo) {
MD_String8 name;
MD_TempArena scratch = md_scratch_begin(ainfo);
{
DWORD length = GetCurrentDirectoryW(0, 0);
MD_U16* memory = md_push_array__no_zero(scratch.arena, MD_U16, length + 1);
length = GetCurrentDirectoryW(length + 1, (WCHAR*)memory);
name = md_str8_from(ainfo, md_str16(memory, length));
}
scratch_end(scratch);
return name;
}
////////////////////////////////
//~ rjf: @md_os_hooks Memory Allocation (Implemented Per-OS)
//- rjf: basic
inline void* md_os_reserve ( MD_U64 size) { void* result = VirtualAlloc( 0, size, MEM_RESERVE, PAGE_READWRITE); return result; }
inline MD_B32 md_os_commit (void* ptr, MD_U64 size) { MD_B32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0); return result; }
inline void md_os_decommit(void* ptr, MD_U64 size) { VirtualFree (ptr, size, MEM_DECOMMIT); }
inline void
md_os_release(void* ptr, MD_U64 size) {
// NOTE(rjf): size not used - not necessary on Windows, but necessary for other OSes.
VirtualFree(ptr, 0, MEM_RELEASE);
}
//- rjf: large pages
inline void*
md_os_reserve_large(MD_U64 size) {
// we commit on reserve because windows
void* result = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_LARGE_PAGES, PAGE_READWRITE);
return result;
}
inline MD_B32 md_os_commit_large(void* ptr, MD_U64 size) { return 1; }
////////////////////////////////
//~ rjf: @md_os_hooks Thread Info (Implemented Per-OS)
inline MD_U32 md_os_tid(void) { DWORD id = GetCurrentThreadId(); return (MD_U32)id; }