Files
Juliet/Juliet/win32/core/win32_core.c
T
2026-10-20 23:15:56 -04:00

205 lines
5.5 KiB
C

typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription);
#define W32_KERNEL32_EXT_X_LIST X(SetThreadDescription)
#define X(x) global W32_##x##_Type* w32_##x##_func;
W32_KERNEL32_EXT_X_LIST
#undef X
// =============================================================================
// Time functions
internal uint64 now_time_us()
{
uint64 result = 0;
LARGE_INTEGER large_int_counter;
if (QueryPerformanceCounter(&large_int_counter))
{
result = (large_int_counter.QuadPart * Million(1)) / w32_state.microsecond_resolution;
}
return result;
}
// =============================================================================
// System
internal SystemInfo* get_system_info()
{
return &w32_state.system_info;
}
// =============================================================================
// Thread Info
internal uint32 tid()
{
DWORD id = GetCurrentThreadId();
return (uint32)id;
}
internal void set_platform_thread_name(String8 name)
{
TempArena scratch = scratch_begin(0, 0);
// Win10 and +
if (w32_SetThreadDescription_func)
{
String16 name16 = str16_from_8(scratch.arena, name);
HRESULT hr = w32_SetThreadDescription_func(GetCurrentThread(), (WCHAR*)name16.str);
}
// Old way by raising exception
{
String8 name_copy = str8_copy(scratch.arena, name);
#pragma pack(push, 8)
typedef struct THREADNAME_INFO THREADNAME_INFO;
struct THREADNAME_INFO
{
uint32 dwType; // Must be 0x1000.
char* szName; // Pointer to name (in user addr space).
uint32 dwThreadID; // Thread ID (-1=caller thread).
uint32 dwFlags; // Reserved for future use, must be zero.
};
#pragma pack(pop)
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = (char*)name_copy.str;
info.dwThreadID = tid();
info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable : 6320 6322)
__try
{
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(void*), (const ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
#pragma warning(pop)
}
scratch_end(scratch);
}
// =============================================================================
// Memory
internal void* reserve_memory(uint64 size)
{
void* result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
return result;
}
internal bool32 commit_memory(void* ptr, uint64 size)
{
bool32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0);
return result;
}
internal void* reserve_memory_large(uint64 size)
{
// Windows do not allow commiting large pages
void* result = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
return result;
}
internal bool32 commit_memory_large(void* ptr, uint64 size)
{
(void)ptr;
(void)size;
return 1;
}
internal void decommit_memory(void* ptr, uint64 size)
{
VirtualFree(ptr, size, MEM_DECOMMIT);
}
internal void release_memory(void* ptr, uint64 size)
{
(void)size; // Unused on windows
VirtualFree(ptr, 0, MEM_RELEASE);
}
// =============================================================================
// Aborting
internal void abort_self(uint64 exit_code)
{
ExitProcess((int)exit_code);
}
// =============================================================================
// Entry points
internal void w32_entry_point(int argc, WCHAR** wargv)
{
// Dynamically load some windows function that are not guaranteed in all sdk
{
#define X(x) w32_##x##_func = (void*)GetProcAddress(module, Stringify(x));
HMODULE module;
module = LoadLibraryA("kernek32.dll");
W32_KERNEL32_EXT_X_LIST
FreeLibrary(module);
#undef X
}
SYSTEM_INFO sys_info = { 0 };
GetSystemInfo(&sys_info);
{
w32_state.microsecond_resolution = 1;
LARGE_INTEGER large_int_resolution;
if (QueryPerformanceCounter(&large_int_resolution))
{
w32_state.microsecond_resolution = large_int_resolution.QuadPart;
}
}
SystemInfo* info = &w32_state.system_info;
info->page_size = sys_info.dwPageSize;
info->large_page_size = GetLargePageMinimum();
Arena* args_arena = arena_alloc(.reserve_size = MB(1), .commit_size = KB(32));
char** argv = push_array(args_arena, char*, argc);
for (int i = 0; i < argc; ++i)
{
String16 arg16 = str16_cstring((uint16*)wargv[i]);
String8 arg8 = str8_from_16(args_arena, arg16);
argv[i] = (char*)arg8.str;
}
// Thread context
TCTX* tctx = tctx_alloc();
tctx_select(tctx);
// setup w32 state
Arena* arena = arena_alloc();
{
w32_state.arena = arena;
{
SystemInfo* info = &w32_state.system_info;
DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
uint8 buffer[MAX_COMPUTERNAME_LENGTH + 1] = { 0 };
if (GetComputerNameA((char*)buffer, &size))
{
info->machine_name = str8_copy(arena, str8(buffer, size));
}
}
}
main_thread_core_entry_point(argc, argv);
tctx_release(tctx);
}
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
(void)hInstance;
(void)hPrevInstance;
(void)lpCmdLine;
(void)nShowCmd;
w32_entry_point(__argc, __wargv);
return 0;
}