diff --git a/src/base/base_arena.h b/src/base/base_arena.h index 3e2df12..2a0c980 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -58,7 +58,7 @@ struct Temp { // creation, destruction internal Arena *arena_alloc_(ArenaParams *params); #define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = MB(64), .commit_size = KB(64), __VA_ARGS__}) -internal void arena_releas(Arena *arena); +internal void arena_release(Arena *arena); // push, pop operations internal void *arena_push(Arena *arena, u64 size_to_push, u64 align); diff --git a/src/base/base_entry_point.c b/src/base/base_entry_point.c new file mode 100644 index 0000000..68d3440 --- /dev/null +++ b/src/base/base_entry_point.c @@ -0,0 +1 @@ +internal void main_thread_entry_point(void) { ThreadNameF("[main thread]"); } diff --git a/src/base/base_entry_point.h b/src/base/base_entry_point.h new file mode 100644 index 0000000..2324531 --- /dev/null +++ b/src/base/base_entry_point.h @@ -0,0 +1,6 @@ +#ifndef BASE_ENTRY_POINT_H +#define BASE_ENTRY_POINT_H + +internal void main_thread_entry_point(void); + +#endif // BASE_ENTRY_POINT_H diff --git a/src/base/base_inc.h b/src/base/base_inc.h index 2a86773..9e776a0 100644 --- a/src/base/base_inc.h +++ b/src/base/base_inc.h @@ -9,7 +9,7 @@ #include "base_arena.h" #include "base_strings.h" #include "base_markup.h" -#include "base_thread_context.h" +#include "base_threading_context.h" // clang-format on #endif // BASE_INC_H diff --git a/src/base/base_strings.c b/src/base/base_strings.c index fbe507b..c4b8d43 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -1,4 +1,4 @@ -String8 str8(u8 *str, u64 size) { +internal String8 str8(u8 *str, u64 size) { String8 result = {str, size}; return (result); } @@ -121,22 +121,39 @@ internal UnicodeDecode utf16_decode(u16 *str, u64 max) { // String Conversion internal String8 str8_from_16(Arena *arena, String16 input) { - u64 cap = in.size * 3; - u8 *str = push_array_no_zero(arena, u8, cap+1); - u16 *ptr = in.str; - u16 *opl = ptr+in.size; - u64 size = 0; + u64 capacity = input.size * 3; + u8 *string = push_array_no_zero(arena, u8, capacity + 1); + u16 *ptr = input.str; + u16 *one_past_last = ptr + input.size; + u64 size = 0; UnicodeDecode consume; - for(;ptr < opl; ptr += consume.inc){ - consume = u16_decode(ptr, opl-ptr); - size += utf8_encode(str + size, consume.codepoint); + for (; ptr < one_past_last; ptr += consume.inc) { + consume = u16_decode(ptr, one_past_last - ptr); + size += utf8_encode(string + size, consume.codepoint); } - str[size] = 0; - arena_pop_off(arena, (cap-size)); - return (str8(str, size)); + + string[size] = 0; + arena_pop_off(arena, (capacity - size)); + return (str8(string, size)); +} + +internal String8 str16_from_8(Arena *arena, String8 input) { + u64 capacity = input.size * 2; + u16 *string = push_array_no_zero(arena, u16, capacity + 1); + u8 *ptr = input.str; + u8 *one_past_last = ptr + input.size; + u64 size = 0; + UnicodeDecode consume; + + for (; ptr < one_past_last; ptr += consume.inc) { + consume = utf8_decode(ptr, one_past_last - ptr); + size += utf16_encode(string + size, consume.codepoint); + } + string[size] = 0; + arena_pop_off(arena, (capacity - size) * 2); + return (str16(string, size)); } -internal String8 str16_from_8(Arena *arena, String8 input) {} // String formatting & copying internal String8 push_str8_copy(Arena *arena, String8 string_to_copy) { diff --git a/src/base/base_threading_context.h b/src/base/base_threading_context.h index 78e47b8..e1b6439 100644 --- a/src/base/base_threading_context.h +++ b/src/base/base_threading_context.h @@ -22,9 +22,9 @@ internal String8 thctx_get_thread_name(void); // NOTE(tijani): Debugging errors within a thread context. internal void thctx_write_srcloc(char *file_name, u64 line_number); internal void thctx_read_srcloc(char **file_name, u64 *line_number); -#define thctx_write_this_srcloc() thctx_write_srcloc(__FILE__, __LINE__); +#define thctx_write_this_srcloc() thctx_write_srcloc(__FILE__, __LINE__); #define scratch_begin(conflicts, count) temp_begin(thctx_get_scratch((conflicts), (count))) -#define scratch_end(scratch) temp_end(scratch) +#define scratch_end(scratch) temp_end(scratch) #endif // BASE_THREAD_CONTEXT_H diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index 9d8ee91..f8f5778 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -1,3 +1,10 @@ +// ATTENTION(tijani): Setting threads description this way because it allows for +// compatibility with older versions of windows where the modern WIN32 +// SetThreadDescription function is not available and use old ways. +// This way it can be done dynamically at runtime without any hiccups. +typedef HRESULT W32_SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription); +global W32_SetThreadDescription *w32_SetThreadDescription_func = 0; + // %os_hooks(implemented per-os) System and process info internal OS_SystemInfo *os_get_system_info(void) { return &os_w32_state.system_info; } @@ -36,3 +43,47 @@ internal void *os_reserve_large(u64 size) { // commit large pages as this has to be done during reservation. // see `os_reserve_large` and WIN32 docs on large page support. internal b32 os_commit_large(void *ptr, u64 size) { return -1; } + +// %os_hooks(implemented per-os) Threads +internal u32 os_thread_id(void) { + u32 id = GetCurrentThreadID(); + return (id); +} + +internal void os_set_thread_name(String8 name) { + Temp scratch = scratch_begin(0, 0); + + // ATTENTION(tijani): modern way of setting thread description + if (w32_SetThreadDescription_func) { + String16 name16 = str16_from_8(scratch.arena, name); + HRESULT = w32_SetThreadDescription_func(GetCurrentThread(), (WCHAR *)name16.str); + } + + // ATTENTION(tijani): setting thread descrption on older windows version + { + String8 name_copy = push_str8_copy(scratch.arena, name); +#pragma pack(push, 8) + typedef struct THREADNAME_INFO THREADNAME_INFO; + struct THREADNAME_INFO { + u32 dwType; // Must be 0x1000. + char *szName; // Pointer to name (in user addr space). + u32 dwThreadID; // Thread ID (-1=caller thread). + u32 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 = os_thread_id(); + 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); +} diff --git a/src/os/core/win32/os_core_win32.h b/src/os/core/win32/os_core_win32.h index 60baa50..e89e6f0 100644 --- a/src/os/core/win32/os_core_win32.h +++ b/src/os/core/win32/os_core_win32.h @@ -2,6 +2,7 @@ #define OS_CORE_WIN32_H #define WIN32_LEAN_AND_MEAN +#include #include // Application State @@ -18,4 +19,8 @@ struct OS_W32_State { // Globals global OS_W32_State os_w32_state = {0}; +// %os_hooks(implemented per-os) Threads +internal u32 os_thread_id(void); +internal void os_set_thread_name(String8 name); + #endif // OS_CORE_WIN32_H