From 070fb5427a8627cd90e0892816b0e4d276f01585 Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 14 Jul 2025 18:16:44 -0500 Subject: [PATCH] formatting --- src/sys.h | 390 +++++++++++------------- src/sys_win32.c | 771 +++++++++++++++++++++--------------------------- src/user.c | 8 +- 3 files changed, 521 insertions(+), 648 deletions(-) diff --git a/src/sys.h b/src/sys.h index 6573e02c..19944b47 100644 --- a/src/sys.h +++ b/src/sys.h @@ -3,29 +3,6 @@ struct snc_counter; -/* ========================== * - * Exit - * ========================== */ - - -#define SYS_EXIT_FUNC(name) void name(void) -typedef SYS_EXIT_FUNC(sys_exit_func); - -/* Registers a function to be called during graceful shutdown (in reverse order) */ -void sys_on_exit(sys_exit_func *func); - -/* Signals the program to shut down gracefully and run exit callbacks */ -void sys_exit(void); - -/* Forcefully exits the program and displays `msg` to the user */ -void sys_panic(struct string msg); - -/* ========================== * - * Scheduler - * ========================== */ - -i64 sys_current_scheduler_period_ns(void); - /* ========================== * * Wait * ========================== */ @@ -95,176 +72,6 @@ struct sys_scratch_ctx { struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 fiber_id); -/* ========================== * - * App entry point - * ========================== */ - - /* Must be defined by app */ - -void sys_app_startup(struct string args_str); - - - - - - - - - - - - - - - - - - - -/* ========================== * - * Events - * ========================== */ - -enum sys_event_kind { - SYS_EVENT_KIND_NONE, - - SYS_EVENT_KIND_BUTTON_DOWN, - SYS_EVENT_KIND_BUTTON_UP, - SYS_EVENT_KIND_CURSOR_MOVE, - SYS_EVENT_KIND_MOUSE_MOVE, - SYS_EVENT_KIND_TEXT, - SYS_EVENT_KIND_QUIT, - - SYS_EVENT_KIND_COUNT -}; - -enum sys_btn { - SYS_BTN_NONE, - - SYS_BTN_M1, - SYS_BTN_M2, - SYS_BTN_M3, - SYS_BTN_M4, - SYS_BTN_M5, - - SYS_BTN_MWHEELUP, - SYS_BTN_MWHEELDOWN, - - SYS_BTN_ESC, - SYS_BTN_F1, - SYS_BTN_F2, - SYS_BTN_F3, - SYS_BTN_F4, - SYS_BTN_F5, - SYS_BTN_F6, - SYS_BTN_F7, - SYS_BTN_F8, - SYS_BTN_F9, - SYS_BTN_F10, - SYS_BTN_F11, - SYS_BTN_F12, - SYS_BTN_F13, - SYS_BTN_F14, - SYS_BTN_F15, - SYS_BTN_F16, - SYS_BTN_F17, - SYS_BTN_F18, - SYS_BTN_F19, - SYS_BTN_F20, - SYS_BTN_F21, - SYS_BTN_F22, - SYS_BTN_F23, - SYS_BTN_F24, - SYS_BTN_GRAVE_ACCENT, - SYS_BTN_0, - SYS_BTN_1, - SYS_BTN_2, - SYS_BTN_3, - SYS_BTN_4, - SYS_BTN_5, - SYS_BTN_6, - SYS_BTN_7, - SYS_BTN_8, - SYS_BTN_9, - SYS_BTN_MINUS, - SYS_BTN_EQUAL, - SYS_BTN_BACKSPACE, - SYS_BTN_DELETE, - SYS_BTN_TAB, - SYS_BTN_A, - SYS_BTN_B, - SYS_BTN_C, - SYS_BTN_D, - SYS_BTN_E, - SYS_BTN_F, - SYS_BTN_G, - SYS_BTN_H, - SYS_BTN_I, - SYS_BTN_J, - SYS_BTN_K, - SYS_BTN_L, - SYS_BTN_M, - SYS_BTN_N, - SYS_BTN_O, - SYS_BTN_P, - SYS_BTN_Q, - SYS_BTN_R, - SYS_BTN_S, - SYS_BTN_T, - SYS_BTN_U, - SYS_BTN_V, - SYS_BTN_W, - SYS_BTN_X, - SYS_BTN_Y, - SYS_BTN_Z, - SYS_BTN_SPACE, - SYS_BTN_ENTER, - SYS_BTN_CTRL, - SYS_BTN_SHIFT, - SYS_BTN_ALT, - SYS_BTN_UP, - SYS_BTN_LEFT, - SYS_BTN_DOWN, - SYS_BTN_RIGHT, - SYS_BTN_PAGE_UP, - SYS_BTN_PAGE_DOWN, - SYS_BTN_HOME, - SYS_BTN_END, - SYS_BTN_FORWARD_SLASH, - SYS_BTN_PERIOD, - SYS_BTN_COMMA, - SYS_BTN_QUOTE, - SYS_BTN_LEFT_BRACKET, - SYS_BTN_RIGHT_BRACKET, - SYS_BTN_INSERT, - SYS_BTN_SEMICOLON, - - SYS_BTN_COUNT -}; - -struct sys_event { - enum sys_event_kind kind; - - /* SYS_EVENT_KIND_BUTTON_DOWN */ - /* SYS_EVENT_KIND_BUTTON_UP */ - enum sys_btn button; - b32 is_repeat; - - /* SYS_EVENT_KIND_TEXT */ - u32 text_codepoint; - - /* SYS_EVENT_KIND_CURSOR_MOVE */ - struct v2 cursor_position; - - /* SYS_EVENT_KIND_MOUSE_MOVE */ - struct v2 mouse_delta; -}; - -struct sys_event_array { - u64 count; - struct sys_event *events; -}; - /* ========================== * * Memory * ========================== */ @@ -427,6 +234,150 @@ void sys_watch_wake(struct sys_watch *dw); struct sys_watch_info_list sys_watch_info_copy(struct arena *arena, struct sys_watch_info_list src); +/* ========================== * + * Window event + * ========================== */ + +enum sys_window_event_kind { + SYS_EVENT_KIND_NONE, + + SYS_EVENT_KIND_BUTTON_DOWN, + SYS_EVENT_KIND_BUTTON_UP, + SYS_EVENT_KIND_CURSOR_MOVE, + SYS_EVENT_KIND_MOUSE_MOVE, + SYS_EVENT_KIND_TEXT, + SYS_EVENT_KIND_QUIT, + + SYS_EVENT_KIND_COUNT +}; + +enum sys_btn { + SYS_BTN_NONE, + + SYS_BTN_M1, + SYS_BTN_M2, + SYS_BTN_M3, + SYS_BTN_M4, + SYS_BTN_M5, + + SYS_BTN_MWHEELUP, + SYS_BTN_MWHEELDOWN, + + SYS_BTN_ESC, + SYS_BTN_F1, + SYS_BTN_F2, + SYS_BTN_F3, + SYS_BTN_F4, + SYS_BTN_F5, + SYS_BTN_F6, + SYS_BTN_F7, + SYS_BTN_F8, + SYS_BTN_F9, + SYS_BTN_F10, + SYS_BTN_F11, + SYS_BTN_F12, + SYS_BTN_F13, + SYS_BTN_F14, + SYS_BTN_F15, + SYS_BTN_F16, + SYS_BTN_F17, + SYS_BTN_F18, + SYS_BTN_F19, + SYS_BTN_F20, + SYS_BTN_F21, + SYS_BTN_F22, + SYS_BTN_F23, + SYS_BTN_F24, + SYS_BTN_GRAVE_ACCENT, + SYS_BTN_0, + SYS_BTN_1, + SYS_BTN_2, + SYS_BTN_3, + SYS_BTN_4, + SYS_BTN_5, + SYS_BTN_6, + SYS_BTN_7, + SYS_BTN_8, + SYS_BTN_9, + SYS_BTN_MINUS, + SYS_BTN_EQUAL, + SYS_BTN_BACKSPACE, + SYS_BTN_DELETE, + SYS_BTN_TAB, + SYS_BTN_A, + SYS_BTN_B, + SYS_BTN_C, + SYS_BTN_D, + SYS_BTN_E, + SYS_BTN_F, + SYS_BTN_G, + SYS_BTN_H, + SYS_BTN_I, + SYS_BTN_J, + SYS_BTN_K, + SYS_BTN_L, + SYS_BTN_M, + SYS_BTN_N, + SYS_BTN_O, + SYS_BTN_P, + SYS_BTN_Q, + SYS_BTN_R, + SYS_BTN_S, + SYS_BTN_T, + SYS_BTN_U, + SYS_BTN_V, + SYS_BTN_W, + SYS_BTN_X, + SYS_BTN_Y, + SYS_BTN_Z, + SYS_BTN_SPACE, + SYS_BTN_ENTER, + SYS_BTN_CTRL, + SYS_BTN_SHIFT, + SYS_BTN_ALT, + SYS_BTN_UP, + SYS_BTN_LEFT, + SYS_BTN_DOWN, + SYS_BTN_RIGHT, + SYS_BTN_PAGE_UP, + SYS_BTN_PAGE_DOWN, + SYS_BTN_HOME, + SYS_BTN_END, + SYS_BTN_FORWARD_SLASH, + SYS_BTN_PERIOD, + SYS_BTN_COMMA, + SYS_BTN_QUOTE, + SYS_BTN_LEFT_BRACKET, + SYS_BTN_RIGHT_BRACKET, + SYS_BTN_INSERT, + SYS_BTN_SEMICOLON, + + SYS_BTN_COUNT +}; + +struct sys_window_event { + enum sys_window_event_kind kind; + + /* SYS_EVENT_KIND_BUTTON_DOWN */ + /* SYS_EVENT_KIND_BUTTON_UP */ + enum sys_btn button; + b32 is_repeat; + + /* SYS_EVENT_KIND_TEXT */ + u32 text_codepoint; + + /* SYS_EVENT_KIND_CURSOR_MOVE */ + struct v2 cursor_position; + + /* SYS_EVENT_KIND_MOUSE_MOVE */ + struct v2 mouse_delta; +}; + +struct sys_window_event_array { + u64 count; + struct sys_window_event *events; +}; + /* ========================== * * Window * ========================== */ @@ -471,7 +422,7 @@ struct sys_window *sys_window_alloc(void); void sys_window_release(struct sys_window *sys_window); -struct sys_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window); +struct sys_window_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window); void sys_window_update_settings(struct sys_window *sys_window, struct sys_window_settings *settings); @@ -496,29 +447,6 @@ void sys_window_cursor_enable_clip(struct sys_window *sys_window, struct rect bo void sys_window_cursor_disable_clip(struct sys_window *sys_window); -/* ========================== * - * Thread - * ========================== */ - -#define SYS_THREAD_DEF(name, arg_name) void name(void *arg_name) -typedef SYS_THREAD_DEF(sys_thread_func, data); - -/* Creates a new thread running in the supplied `entry_point` */ -struct sys_thread *sys_thread_alloc( - sys_thread_func *entry_point, - void *thread_data, /* Passed as arg to `entry_point` */ - struct string thread_name, - i32 profiler_group -); - -void sys_thread_wait_release(struct sys_thread *thread); - -b32 sys_thread_try_release(struct sys_thread *thread, f32 timeout_seconds); /* Returns 0 if the thread could not release in specified timeout (e.g. because it is still running) */ - -void sys_thread_force_release(struct sys_thread *thread); - -u32 sys_current_thread_id(void); - /* ========================== * * Address * ========================== */ @@ -583,4 +511,32 @@ void sys_true_rand(struct string b); u32 sys_num_logical_processors(void); +u32 sys_current_thread_id(void); + +i64 sys_current_scheduler_period_ns(void); + +/* ========================== * + * Exit + * ========================== */ + + +#define SYS_EXIT_FUNC(name) void name(void) +typedef SYS_EXIT_FUNC(sys_exit_func); + +/* Registers a function to be called during graceful shutdown (in reverse order) */ +void sys_on_exit(sys_exit_func *func); + +/* Signals the program to shut down gracefully and run exit callbacks */ +void sys_exit(void); + +/* Forcefully exits the program and displays `msg` to the user */ +void sys_panic(struct string msg); + +/* ========================== * + * App entry point + * ========================== */ + + /* Must be defined by app */ +void sys_app_startup(struct string args_str); + #endif diff --git a/src/sys_win32.c b/src/sys_win32.c index ad2bfb7d..c94fe291 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -44,6 +44,9 @@ #define THREAD_STACK_SIZE KIBI(64) #define FIBER_STACK_SIZE MEBI(4) +#define THREAD_DEF(name, arg_name) void name(void *arg_name) +typedef THREAD_DEF(thread_func, data); + /* Assume scheduler cycle is 20hz at start to be conservative */ #define DEFAULT_SCHEDULER_CYCLE_PERIOD_NS 50000000 #define NUM_ROLLING_SCHEDULER_PERIODS 1000 @@ -65,15 +68,15 @@ struct ticket_mutex { struct atomic64_padded serving; }; -struct win32_thread { - sys_thread_func *entry_point; +struct thread { + thread_func *entry_point; void *thread_data; char thread_name_cstr[256]; wchar_t thread_name_wstr[256]; i32 profiler_group; - struct win32_thread *next; - struct win32_thread *prev; + struct thread *next; + struct thread *prev; HANDLE handle; }; @@ -114,7 +117,7 @@ struct win32_window { i32 current_event_arena_index; struct arena *event_arenas[2]; - struct sys_thread *window_thread; + struct thread *window_thread; struct atomic32 shutdown; struct win32_window *next_free; @@ -267,7 +270,7 @@ struct alignas(64) job_pool { u64 thread_affinity_mask; b32 thread_is_audio; struct arena *worker_threads_arena; - struct sys_thread **worker_threads; + struct thread **worker_threads; struct worker_ctx *worker_contexts; }; @@ -298,9 +301,9 @@ GLOBAL struct { /* Threads pool */ struct snc_mutex threads_mutex; struct arena *threads_arena; - struct win32_thread *threads_first; - struct win32_thread *threads_last; - struct win32_thread *threads_first_free; + struct thread *first_thread; + struct thread *last_thread; + struct thread *first_free_thread; /* Watches pool */ struct snc_mutex watches_mutex; @@ -351,6 +354,7 @@ GLOBAL struct { +INTERNAL struct fiber *fiber_alloc(struct job_pool *pool); INTERNAL struct fiber *fiber_from_id(i16 id); INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber); @@ -374,92 +378,148 @@ INTERNAL void tm_unlock(struct ticket_mutex *tm) atomic64_fetch_add(&tm->serving.v, 1); } - - - - /* ========================== * - * Exit + * Thread * ========================== */ -void sys_on_exit(sys_exit_func *func) +INTERNAL DWORD WINAPI win32_thread_proc(LPVOID vt) { - i32 index = atomic32_fetch_add(&G.num_exit_funcs, 1); - if (index >= MAX_EXIT_FUNCS) { - sys_panic(LIT("Maximum on exit functions registered")); + fiber_alloc(0); + + struct thread *t = (struct thread *)vt; + __profthread(t->thread_name_cstr, t->profiler_group); + + /* Initialize COM */ + CoInitializeEx(0, COINIT_MULTITHREADED); + + /* Set thread name */ + if (t->thread_name_wstr[0] != 0) { + SetThreadDescription(GetCurrentThread(), t->thread_name_wstr); } - G.exit_funcs[index] = func; + + logf_info("New thread \"%F\" created with ID %F", FMT_STR(string_from_cstr_no_limit(t->thread_name_cstr)), FMT_UINT(sys_current_thread_id())); + + /* Enter thread entry point */ + t->entry_point(t->thread_data); + + /* Uninitialize COM */ + CoUninitialize(); + + return 0; } -void sys_exit(void) +INTERNAL struct thread *thread_alloc(thread_func *entry_point, void *thread_data, struct string thread_name, i32 profiler_group) { - SetEvent(G.exit_begin_event); + __prof; + struct arena_temp scratch = scratch_begin_no_conflict(); + ASSERT(entry_point != 0); + logf_info("Creating thread \"%F\"", FMT_STR(thread_name)); + + + /* Allocate thread object */ + struct thread *t = 0; + { + struct snc_lock lock = snc_lock_e(&G.threads_mutex); + if (G.first_free_thread) { + t = G.first_free_thread; + G.first_free_thread = t->next; + } else { + t = arena_push_no_zero(G.threads_arena, struct thread); + } + MEMZERO_STRUCT(t); + if (G.last_thread) { + G.last_thread->next = t; + t->prev = G.last_thread; + } else { + G.first_thread = t; + } + G.last_thread = t; + snc_unlock(&lock); + } + + + t->entry_point = entry_point; + t->thread_data = thread_data; + t->profiler_group = profiler_group; + + /* Copy thread name to params */ + { + u64 cstr_len = min_u64((countof(t->thread_name_cstr) - 1), thread_name.len); + MEMCPY(t->thread_name_cstr, thread_name.text, cstr_len * sizeof(*t->thread_name_cstr)); + t->thread_name_cstr[cstr_len] = 0; + } + { + struct string16 thread_name16 = string16_from_string(scratch.arena, thread_name); + u64 wstr_len = min_u64((countof(t->thread_name_wstr) - 1), thread_name16.len); + MEMCPY(t->thread_name_wstr, thread_name16.text, wstr_len * sizeof(*t->thread_name_wstr)); + t->thread_name_wstr[wstr_len] = 0; + } + + t->handle = CreateThread( + 0, + THREAD_STACK_SIZE, + win32_thread_proc, + t, + 0, + 0 + ); + + if (!t->handle) { + sys_panic(LIT("Failed to create thread")); + } + + scratch_end(scratch); + return (struct thread *)t; } -void sys_panic(struct string msg) +/* Returns 0 if the thread could not release in specified timeout (e.g. because it is still running) */ +INTERNAL b32 thread_try_release(struct thread *thread, f32 timeout_seconds) { - if (atomic32_fetch_test_set(&G.panicking, 0, 1) == 0) { - log_panic(msg); - - wchar_t *wstr = G.panic_wstr; - u64 wstr_len = 0; - - wchar_t prefix[] = L"A fatal error has occured and the application needs to exit:\n\n"; - MEMCPY(wstr, prefix, min_u64(countof(G.panic_wstr), (countof(prefix) << 1))); - wstr_len += countof(prefix) - 1; - - /* Perform manual string encode to avoid any implicit memory - * allocation (in case allocation is unreliable) */ - struct string str8 = msg; - u64 pos8 = 0; - while (pos8 < str8.len) { - struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; - struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining); - struct uni_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint); - u64 wstr_new_len = wstr_len + encoded.count16; - if (wstr_new_len < (countof(G.panic_wstr) - 1)) { - u16 *dest = wstr + wstr_len; - MEMCPY(dest, encoded.chars16, (encoded.count16 << 1)); - wstr_len = wstr_new_len; - pos8 += decoded.advance8; - } else { - break; + __prof; + b32 success = 0; + struct thread *t = (struct thread *)thread; + HANDLE handle = t->handle; + if (handle) { + /* Wait for thread to stop */ + DWORD timeout_ms = (timeout_seconds == F32_INFINITY) ? INFINITE : math_round_to_int(timeout_seconds * 1000); + DWORD wait_res = WaitForSingleObject(handle, timeout_ms); + if (wait_res == WAIT_OBJECT_0) { + /* Release thread */ + success = 1; + CloseHandle(handle); + { + struct snc_lock lock = snc_lock_e(&G.threads_mutex); + { + struct thread *prev = t->prev; + struct thread *next = t->next; + if (prev) { + prev->next = next; + } else { + G.first_thread = next; + } + if (next) { + next->prev = prev; + } else { + G.last_thread = prev; + } + t->next = G.first_free_thread; + G.first_free_thread = t; + } + snc_unlock(&lock); } } - - wstr[wstr_len] = 0; - -#if RTC - MessageBoxExW(0, wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); - ASSERT(0); -#endif - - SetEvent(G.panic_event); - - /* Wait for process termination */ - if (GetCurrentThreadId() != G.main_thread_id) { - Sleep(INFINITE); - } } + return success; } -/* ========================== * - * Scheduler - * ========================== */ - -i64 sys_current_scheduler_period_ns(void) +INTERNAL void thread_wait_release(struct thread *thread) { - return atomic64_fetch(&G.current_scheduler_cycle_period_ns.v); + __prof; + b32 success = thread_try_release(thread, F32_INFINITY); + ASSERT(success); + (UNUSED)success; } - - - - - - - - /* ========================== * * Wait / wake * ========================== */ @@ -876,15 +936,67 @@ FORCE_INLINE struct fiber *fiber_from_id(i16 id) } } -/* ========================== * - * Test job - * ========================== */ - i16 sys_current_fiber_id(void) { return (i16)(i64)GetFiberData(); } +/* ========================== * + * Job + * ========================== */ + +INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber) +{ + (UNUSED)fiber; + ASSERT(fiber->id == sys_current_fiber_id()); + ASSERT(parent_fiber->id == fiber->parent_id); + ASSERT(parent_fiber->id > 0); + { + __prof_fiber_leave(); + MemoryBarrier(); + SwitchToFiber(parent_fiber->addr); + MemoryBarrier(); + __prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id); + } +} + +INTERNAL void job_fiber_resume(struct fiber *fiber) +{ + MemoryBarrier(); + SwitchToFiber(fiber->addr); + MemoryBarrier(); +} + +INTERNAL void job_fiber_entry(void *id_ptr) +{ + i16 id = (i32)(i64)id_ptr; + struct fiber *fiber = fiber_from_id(id); + __prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id); + for (;;) { + /* Run job */ + { + volatile struct yield_param *yield_param = fiber->yield_param; + yield_param->kind = YIELD_KIND_NONE; + struct sys_job_data data = ZI; + data.id = fiber->job_id; + data.sig = fiber->job_sig; + { + MemoryBarrier(); + fiber->job_func(data); + MemoryBarrier(); + } + } + /* Yield */ + { + volatile struct yield_param *yield_param = fiber->yield_param; + yield_param->kind = YIELD_KIND_DONE; + struct fiber *parent_fiber = fiber_from_id(fiber->parent_id); + job_fiber_yield(fiber, parent_fiber); + } + } +} + + void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter) { if (count > 0) { @@ -931,70 +1043,11 @@ void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, } } -/* ========================== * - * Job fiber control - * ========================== */ - -INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber) -{ - (UNUSED)fiber; - ASSERT(fiber->id == sys_current_fiber_id()); - ASSERT(parent_fiber->id == fiber->parent_id); - ASSERT(parent_fiber->id > 0); - { - __prof_fiber_leave(); - MemoryBarrier(); - SwitchToFiber(parent_fiber->addr); - MemoryBarrier(); - __prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id); - } -} - -INTERNAL void job_fiber_resume(struct fiber *fiber) -{ - MemoryBarrier(); - SwitchToFiber(fiber->addr); - MemoryBarrier(); -} - -/* ========================== * - * Job fiber entry - * ========================== */ - -INTERNAL void job_fiber_entry(void *id_ptr) -{ - i16 id = (i32)(i64)id_ptr; - struct fiber *fiber = fiber_from_id(id); - __prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id); - for (;;) { - /* Run job */ - { - volatile struct yield_param *yield_param = fiber->yield_param; - yield_param->kind = YIELD_KIND_NONE; - struct sys_job_data data = ZI; - data.id = fiber->job_id; - data.sig = fiber->job_sig; - { - MemoryBarrier(); - fiber->job_func(data); - MemoryBarrier(); - } - } - /* Yield */ - { - volatile struct yield_param *yield_param = fiber->yield_param; - yield_param->kind = YIELD_KIND_DONE; - struct fiber *parent_fiber = fiber_from_id(fiber->parent_id); - job_fiber_yield(fiber, parent_fiber); - } - } -} - /* ========================== * * Job worker thread * ========================== */ -INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg) +INTERNAL THREAD_DEF(job_worker_entry, worker_ctx_arg) { struct worker_ctx *ctx = worker_ctx_arg; enum sys_pool pool_kind = ctx->pool_kind; @@ -1293,7 +1346,7 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg) * Job scheduler thread * ========================== */ -INTERNAL SYS_THREAD_DEF(job_scheduler_entry, _) +INTERNAL THREAD_DEF(job_scheduler_entry, _) { (UNUSED)_; { @@ -1358,14 +1411,6 @@ INTERNAL SYS_THREAD_DEF(job_scheduler_entry, _) } } - - - - - - - - /* ========================== * * Scratch context * ========================== */ @@ -1383,70 +1428,6 @@ struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 id) return scratch_ctx; } - - - - - - - - - - - - - - - - -/* ========================== * - * Events - * ========================== */ - -INTERNAL void win32_init_vk_btn_table(void) -{ - MEMZERO_ARRAY(G.vk_btn_table); - - for (u32 i = 'A', j = SYS_BTN_A; i <= 'Z'; ++i, ++j) { - G.vk_btn_table[i] = (enum sys_btn)j; - } - for (u32 i = '0', j = SYS_BTN_0; i <= '9'; ++i, ++j) { - G.vk_btn_table[i] = (enum sys_btn)j; - } - for (u32 i = VK_F1, j = SYS_BTN_F1; i <= VK_F24; ++i, ++j) { - G.vk_btn_table[i] = (enum sys_btn)j; - } - - G.vk_btn_table[VK_ESCAPE] = SYS_BTN_ESC; - G.vk_btn_table[VK_OEM_3] = SYS_BTN_GRAVE_ACCENT; - G.vk_btn_table[VK_OEM_MINUS] = SYS_BTN_MINUS; - G.vk_btn_table[VK_OEM_PLUS] = SYS_BTN_EQUAL; - G.vk_btn_table[VK_BACK] = SYS_BTN_BACKSPACE; - G.vk_btn_table[VK_TAB] = SYS_BTN_TAB; - G.vk_btn_table[VK_SPACE] = SYS_BTN_SPACE; - G.vk_btn_table[VK_RETURN] = SYS_BTN_ENTER; - G.vk_btn_table[VK_CONTROL] = SYS_BTN_CTRL; - G.vk_btn_table[VK_SHIFT] = SYS_BTN_SHIFT; - G.vk_btn_table[VK_MENU] = SYS_BTN_ALT; - G.vk_btn_table[VK_UP] = SYS_BTN_UP; - G.vk_btn_table[VK_LEFT] = SYS_BTN_LEFT; - G.vk_btn_table[VK_DOWN] = SYS_BTN_DOWN; - G.vk_btn_table[VK_RIGHT] = SYS_BTN_RIGHT; - G.vk_btn_table[VK_DELETE] = SYS_BTN_DELETE; - G.vk_btn_table[VK_PRIOR] = SYS_BTN_PAGE_UP; - G.vk_btn_table[VK_NEXT] = SYS_BTN_PAGE_DOWN; - G.vk_btn_table[VK_HOME] = SYS_BTN_HOME; - G.vk_btn_table[VK_END] = SYS_BTN_END; - G.vk_btn_table[VK_OEM_2] = SYS_BTN_FORWARD_SLASH; - G.vk_btn_table[VK_OEM_PERIOD] = SYS_BTN_PERIOD; - G.vk_btn_table[VK_OEM_COMMA] = SYS_BTN_COMMA; - G.vk_btn_table[VK_OEM_7] = SYS_BTN_QUOTE; - G.vk_btn_table[VK_OEM_4] = SYS_BTN_LEFT_BRACKET; - G.vk_btn_table[VK_OEM_6] = SYS_BTN_RIGHT_BRACKET; - G.vk_btn_table[VK_INSERT] = SYS_BTN_INSERT; - G.vk_btn_table[VK_OEM_1] = SYS_BTN_SEMICOLON; -} - /* ========================== * * Memory * ========================== */ @@ -2137,12 +2118,12 @@ struct sys_watch_info_list sys_watch_info_copy(struct arena *arena, struct sys_w INTERNAL void win32_update_window_from_system(struct win32_window *window); INTERNAL void win32_window_wake(struct win32_window *window); -INTERNAL void win32_window_process_event(struct win32_window *window, struct sys_event event) +INTERNAL void win32_window_process_event(struct win32_window *window, struct sys_window_event event) { __prof; struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex); { - *arena_push(window->event_arenas[window->current_event_arena_index], struct sys_event) = event; + *arena_push(window->event_arenas[window->current_event_arena_index], struct sys_window_event) = event; } snc_unlock(&lock); } @@ -2184,7 +2165,7 @@ INTERNAL HWND win32_window_init(struct win32_window *window) return hwnd; } -INTERNAL SYS_THREAD_DEF(window_thread, arg) +INTERNAL THREAD_DEF(window_thread, arg) { struct win32_window *window = (struct win32_window *)arg; @@ -2235,7 +2216,7 @@ INTERNAL struct win32_window *win32_window_alloc(void) * created and receive a HWND, because on Windows a the event proc must run on * the same thread that created the window. */ snc_counter_add(&window->ready_fence, 1); - window->window_thread = sys_thread_alloc(&window_thread, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW); + window->window_thread = thread_alloc(&window_thread, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW); snc_counter_wait(&window->ready_fence); return window; @@ -2246,7 +2227,7 @@ INTERNAL void win32_window_release(struct win32_window *window) /* Stop window threads */ atomic32_fetch_set(&window->shutdown, 1); win32_window_wake(window); - sys_thread_wait_release(window->window_thread); + thread_wait_release(window->window_thread); struct snc_lock lock = snc_lock_e(&G.windows_mutex); { @@ -2256,7 +2237,7 @@ INTERNAL void win32_window_release(struct win32_window *window) snc_unlock(&lock); } -struct sys_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window) +struct sys_window_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window) { __prof; struct win32_window *window = (struct win32_window *)sys_window; @@ -2269,9 +2250,9 @@ struct sys_event_array sys_window_pop_events(struct arena *arena, struct sys_win snc_unlock(&lock); } struct arena *events_arena = window->event_arenas[event_arena_index]; - struct sys_event_array events = ZI; - events.count = events_arena->pos / sizeof(struct sys_event); - events.events = arena_push_array_no_zero(arena, struct sys_event, events.count); + struct sys_window_event_array events = ZI; + events.count = events_arena->pos / sizeof(struct sys_window_event); + events.events = arena_push_array_no_zero(arena, struct sys_window_event, events.count); MEMCPY(events.events, arena_base(events_arena), events_arena->pos); arena_reset(events_arena); return events; @@ -2473,7 +2454,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, case WM_QUIT: case WM_CLOSE: case WM_DESTROY: { - win32_window_process_event(window, (struct sys_event) { .kind = SYS_EVENT_KIND_QUIT }); + win32_window_process_event(window, (struct sys_window_event) { .kind = SYS_EVENT_KIND_QUIT }); } break; case WM_PAINT: { @@ -2501,7 +2482,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, WORD vk_code = LOWORD(wparam); b32 is_repeat = 0; - enum sys_event_kind event_kind = SYS_EVENT_KIND_NONE; + enum sys_window_event_kind event_kind = SYS_EVENT_KIND_NONE; if (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) { event_kind = SYS_EVENT_KIND_BUTTON_DOWN; is_repeat = (lparam & 0x40000000) != 0; @@ -2516,7 +2497,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, win32_window_process_event( window, - (struct sys_event) { + (struct sys_window_event) { .kind = event_kind, .button = button, .is_repeat = is_repeat @@ -2556,7 +2537,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, if((codepoint >= 32 && codepoint != 127) || codepoint == '\t' || codepoint == '\n') { win32_window_process_event( window, - (struct sys_event) { + (struct sys_window_event) { .kind = SYS_EVENT_KIND_TEXT, .text_codepoint = codepoint } @@ -2583,7 +2564,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, SetCapture(hwnd); } - enum sys_event_kind event_kind = is_release ? SYS_EVENT_KIND_BUTTON_UP : SYS_EVENT_KIND_BUTTON_DOWN; + enum sys_window_event_kind event_kind = is_release ? SYS_EVENT_KIND_BUTTON_UP : SYS_EVENT_KIND_BUTTON_DOWN; enum sys_btn button = 0; switch(msg) { @@ -2603,7 +2584,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, if (button) { win32_window_process_event( window, - (struct sys_event) { + (struct sys_window_event) { .kind = event_kind, .button = button } @@ -2618,8 +2599,8 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, enum sys_btn button = dir >= 0 ? SYS_BTN_MWHEELUP : SYS_BTN_MWHEELDOWN; for (i32 i = 0; i < (dir * delta); i += WHEEL_DELTA) { /* Send a button down & button up event simultaneously */ - win32_window_process_event(window, (struct sys_event) { .kind = SYS_EVENT_KIND_BUTTON_DOWN, .button = button }); - win32_window_process_event(window, (struct sys_event) { .kind = SYS_EVENT_KIND_BUTTON_UP, .button = button }); + win32_window_process_event(window, (struct sys_window_event) { .kind = SYS_EVENT_KIND_BUTTON_DOWN, .button = button }); + win32_window_process_event(window, (struct sys_window_event) { .kind = SYS_EVENT_KIND_BUTTON_UP, .button = button }); } } break; @@ -2629,7 +2610,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, i32 y = GET_Y_LPARAM(lparam); win32_window_process_event( window, - (struct sys_event) { + (struct sys_window_event) { .kind = SYS_EVENT_KIND_CURSOR_MOVE, .cursor_position = V2(x, y) } @@ -2657,7 +2638,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam, struct v2 delta = V2(x, y); win32_window_process_event( window, - (struct sys_event) { + (struct sys_window_event) { .kind = SYS_EVENT_KIND_MOUSE_MOVE, .mouse_delta = delta } @@ -2790,179 +2771,6 @@ void sys_window_cursor_disable_clip(struct sys_window *sys_window) win32_window_wake(window); } -/* ========================== * - * Threads - * ========================== */ - -INTERNAL struct win32_thread *win32_thread_alloc(void) -{ - struct win32_thread *t = 0; - struct snc_lock lock = snc_lock_e(&G.threads_mutex); - { - if (G.threads_first_free) { - t = G.threads_first_free; - G.threads_first_free = t->next; - } else { - t = arena_push_no_zero(G.threads_arena, struct win32_thread); - } - MEMZERO_STRUCT(t); - if (!G.threads_first) { - G.threads_first = t; - } else { - G.threads_last->next = t; - } - t->prev = G.threads_last; - G.threads_last = t; - } - snc_unlock(&lock); - return t; -} - -INTERNAL void win32_thread_release(struct win32_thread *t) -{ - struct snc_lock lock = snc_lock_e(&G.threads_mutex); - { - if (t->prev) { - t->prev->next = t->next; - } - if (t->next) { - t->next->prev = t->prev; - } - if (G.threads_first == t) { - G.threads_first = t->next; - } - if (G.threads_last == t) { - G.threads_last = t->prev; - } - t->next = G.threads_first_free; - } - snc_unlock(&lock); -} - -INTERNAL DWORD WINAPI win32_thread_proc(LPVOID vt) -{ - fiber_alloc(0); - - struct win32_thread *t = (struct win32_thread *)vt; - __profthread(t->thread_name_cstr, t->profiler_group); - - /* Initialize COM */ - CoInitializeEx(0, COINIT_MULTITHREADED); - - /* Set thread name */ - if (t->thread_name_wstr[0] != 0) { - SetThreadDescription(GetCurrentThread(), t->thread_name_wstr); - } - - logf_info("New thread \"%F\" created with ID %F", FMT_STR(string_from_cstr_no_limit(t->thread_name_cstr)), FMT_UINT(sys_current_thread_id())); - - /* Enter thread entry point */ - t->entry_point(t->thread_data); - - /* Uninitialize COM */ - CoUninitialize(); - - return 0; -} - -struct sys_thread *sys_thread_alloc(sys_thread_func *entry_point, void *thread_data, struct string thread_name, i32 profiler_group) -{ - __prof; - struct arena_temp scratch = scratch_begin_no_conflict(); - ASSERT(entry_point != 0); - logf_info("Creating thread \"%F\"", FMT_STR(thread_name)); - - - /* Allocate thread object */ - struct win32_thread *t = win32_thread_alloc(); - t->entry_point = entry_point; - t->thread_data = thread_data; - t->profiler_group = profiler_group; - - /* Copy thread name to params */ - { - u64 cstr_len = min_u64((countof(t->thread_name_cstr) - 1), thread_name.len); - MEMCPY(t->thread_name_cstr, thread_name.text, cstr_len * sizeof(*t->thread_name_cstr)); - t->thread_name_cstr[cstr_len] = 0; - } - { - struct string16 thread_name16 = string16_from_string(scratch.arena, thread_name); - u64 wstr_len = min_u64((countof(t->thread_name_wstr) - 1), thread_name16.len); - MEMCPY(t->thread_name_wstr, thread_name16.text, wstr_len * sizeof(*t->thread_name_wstr)); - t->thread_name_wstr[wstr_len] = 0; - } - - t->handle = CreateThread( - 0, - THREAD_STACK_SIZE, - win32_thread_proc, - t, - 0, - 0 - ); - - if (!t->handle) { - sys_panic(LIT("Failed to create thread")); - } - - scratch_end(scratch); - return (struct sys_thread *)t; -} - -void sys_thread_wait_release(struct sys_thread *thread) -{ - __prof; - b32 success = sys_thread_try_release(thread, F32_INFINITY); - ASSERT(success); - (UNUSED)success; -} - -b32 sys_thread_try_release(struct sys_thread *thread, f32 timeout_seconds) -{ - __prof; - b32 success = 0; - struct win32_thread *t = (struct win32_thread *)thread; - HANDLE handle = t->handle; - - /* Wait for thread to stop */ - if (handle) { - DWORD timeout_ms = (timeout_seconds == F32_INFINITY) ? INFINITE : math_round_to_int(timeout_seconds * 1000); - DWORD wait_res = WaitForSingleObject(handle, timeout_ms); - if (wait_res == WAIT_OBJECT_0) { - success = 1; - CloseHandle(handle); - win32_thread_release(t); - } - } - - return success; -} - -void sys_thread_force_release(struct sys_thread *thread) -{ - __prof; - struct win32_thread *t = (struct win32_thread *)thread; - HANDLE handle = t->handle; - - /* Wait for thread to stop */ - if (handle) { - DWORD res = WaitForSingleObject(handle, INFINITE); - TerminateThread(handle, 0); - CloseHandle(handle); - - ASSERT(res != WAIT_FAILED); - (UNUSED)res; - } - - /* Release thread struct */ - win32_thread_release(t); -} - -u32 sys_current_thread_id(void) -{ - return GetCurrentThreadId(); -} - /* ========================== * * Address * ========================== */ @@ -3392,10 +3200,129 @@ u32 sys_num_logical_processors(void) return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); } +u32 sys_current_thread_id(void) +{ + return GetCurrentThreadId(); +} + +i64 sys_current_scheduler_period_ns(void) +{ + return atomic64_fetch(&G.current_scheduler_cycle_period_ns.v); +} + +/* ========================== * + * Exit + * ========================== */ + +void sys_on_exit(sys_exit_func *func) +{ + i32 index = atomic32_fetch_add(&G.num_exit_funcs, 1); + if (index >= MAX_EXIT_FUNCS) { + sys_panic(LIT("Maximum on exit functions registered")); + } + G.exit_funcs[index] = func; +} + +void sys_exit(void) +{ + SetEvent(G.exit_begin_event); +} + +void sys_panic(struct string msg) +{ + if (atomic32_fetch_test_set(&G.panicking, 0, 1) == 0) { + log_panic(msg); + + wchar_t *wstr = G.panic_wstr; + u64 wstr_len = 0; + + wchar_t prefix[] = L"A fatal error has occured and the application needs to exit:\n\n"; + MEMCPY(wstr, prefix, min_u64(countof(G.panic_wstr), (countof(prefix) << 1))); + wstr_len += countof(prefix) - 1; + + /* Perform manual string encode to avoid any implicit memory + * allocation (in case allocation is unreliable) */ + struct string str8 = msg; + u64 pos8 = 0; + while (pos8 < str8.len) { + struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; + struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining); + struct uni_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint); + u64 wstr_new_len = wstr_len + encoded.count16; + if (wstr_new_len < (countof(G.panic_wstr) - 1)) { + u16 *dest = wstr + wstr_len; + MEMCPY(dest, encoded.chars16, (encoded.count16 << 1)); + wstr_len = wstr_new_len; + pos8 += decoded.advance8; + } else { + break; + } + } + + wstr[wstr_len] = 0; + +#if RTC + MessageBoxExW(0, wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); + ASSERT(0); +#endif + + SetEvent(G.panic_event); + + /* Wait for process termination */ + if (GetCurrentThreadId() != G.main_thread_id) { + Sleep(INFINITE); + } + } +} + /* ========================== * * Entry point * ========================== */ +INTERNAL void win32_init_vk_btn_table(void) +{ + MEMZERO_ARRAY(G.vk_btn_table); + + for (u32 i = 'A', j = SYS_BTN_A; i <= 'Z'; ++i, ++j) { + G.vk_btn_table[i] = (enum sys_btn)j; + } + for (u32 i = '0', j = SYS_BTN_0; i <= '9'; ++i, ++j) { + G.vk_btn_table[i] = (enum sys_btn)j; + } + for (u32 i = VK_F1, j = SYS_BTN_F1; i <= VK_F24; ++i, ++j) { + G.vk_btn_table[i] = (enum sys_btn)j; + } + + G.vk_btn_table[VK_ESCAPE] = SYS_BTN_ESC; + G.vk_btn_table[VK_OEM_3] = SYS_BTN_GRAVE_ACCENT; + G.vk_btn_table[VK_OEM_MINUS] = SYS_BTN_MINUS; + G.vk_btn_table[VK_OEM_PLUS] = SYS_BTN_EQUAL; + G.vk_btn_table[VK_BACK] = SYS_BTN_BACKSPACE; + G.vk_btn_table[VK_TAB] = SYS_BTN_TAB; + G.vk_btn_table[VK_SPACE] = SYS_BTN_SPACE; + G.vk_btn_table[VK_RETURN] = SYS_BTN_ENTER; + G.vk_btn_table[VK_CONTROL] = SYS_BTN_CTRL; + G.vk_btn_table[VK_SHIFT] = SYS_BTN_SHIFT; + G.vk_btn_table[VK_MENU] = SYS_BTN_ALT; + G.vk_btn_table[VK_UP] = SYS_BTN_UP; + G.vk_btn_table[VK_LEFT] = SYS_BTN_LEFT; + G.vk_btn_table[VK_DOWN] = SYS_BTN_DOWN; + G.vk_btn_table[VK_RIGHT] = SYS_BTN_RIGHT; + G.vk_btn_table[VK_DELETE] = SYS_BTN_DELETE; + G.vk_btn_table[VK_PRIOR] = SYS_BTN_PAGE_UP; + G.vk_btn_table[VK_NEXT] = SYS_BTN_PAGE_DOWN; + G.vk_btn_table[VK_HOME] = SYS_BTN_HOME; + G.vk_btn_table[VK_END] = SYS_BTN_END; + G.vk_btn_table[VK_OEM_2] = SYS_BTN_FORWARD_SLASH; + G.vk_btn_table[VK_OEM_PERIOD] = SYS_BTN_PERIOD; + G.vk_btn_table[VK_OEM_COMMA] = SYS_BTN_COMMA; + G.vk_btn_table[VK_OEM_7] = SYS_BTN_QUOTE; + G.vk_btn_table[VK_OEM_4] = SYS_BTN_LEFT_BRACKET; + G.vk_btn_table[VK_OEM_6] = SYS_BTN_RIGHT_BRACKET; + G.vk_btn_table[VK_INSERT] = SYS_BTN_INSERT; + G.vk_btn_table[VK_OEM_1] = SYS_BTN_SEMICOLON; +} + INTERNAL SYS_JOB_DEF(sys_app_startup_job, _) { (UNUSED)_; @@ -3483,10 +3410,6 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } #endif - /* ========================== * - * Sys startup - * ========================== */ - /* Set up exit events */ G.panic_event = CreateEventW(0, 1, 0, 0); G.startup_end_event = CreateEventW(0, 1, 0, 0); @@ -3589,7 +3512,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, /* Start job scheduler */ atomic64_fetch_set(&G.current_scheduler_cycle_period_ns.v, DEFAULT_SCHEDULER_CYCLE_PERIOD_NS); - struct sys_thread *scheduler_thread = sys_thread_alloc(job_scheduler_entry, 0, LIT("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER); + struct thread *scheduler_thread = thread_alloc(job_scheduler_entry, 0, LIT("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER); /* Start job workers */ /* TODO: Heuristic worker counts & affinities */ @@ -3642,21 +3565,20 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, } break; } pool->worker_threads_arena = arena_alloc(GIBI(64)); - pool->worker_threads = arena_push_array(pool->worker_threads_arena, struct sys_thread *, pool->num_worker_threads); + pool->worker_threads = arena_push_array(pool->worker_threads_arena, struct thread *, pool->num_worker_threads); pool->worker_contexts = arena_push_array(pool->worker_threads_arena, struct worker_ctx, pool->num_worker_threads); for (i32 i = 0; i < pool->num_worker_threads; ++i) { struct worker_ctx *ctx = &pool->worker_contexts[i]; ctx->pool_kind = pool_kind; ctx->id = i; struct string name = string_format(pool->worker_threads_arena, name_fmt, FMT_SINT(i)); - pool->worker_threads[i] = sys_thread_alloc(job_worker_entry, ctx, name, prof_group + i); + pool->worker_threads[i] = thread_alloc(job_worker_entry, ctx, name, prof_group + i); } } } - /* ========================== * - * App startup - * ========================== */ + /* ================================================== * + * App startup */ /* Run app start job */ if (!atomic32_fetch(&G.panicking)) { @@ -3681,19 +3603,14 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, WaitForMultipleObjects(countof(handles), handles, 0, INFINITE); } - /* ========================== * - * App shutdown - * ========================== */ + /* ================================================== * + * App shutdown */ /* Run exit callbacks job */ if (!atomic32_fetch(&G.panicking)) { sys_run(1, sys_app_shutdown_job, 0, SYS_POOL_FLOATING, SYS_PRIORITY_HIGH, 0); } - /* ========================== * - * Sys shutdown - * ========================== */ - /* Wait for exit end or panic */ if (!atomic32_fetch(&G.panicking)) { HANDLE handles[] = { @@ -3722,26 +3639,26 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, for (enum sys_pool pool_kind = 0; pool_kind < (i32)countof(G.job_pools); ++pool_kind) { struct job_pool *pool = &G.job_pools[pool_kind]; for (i32 i = 0; i < pool->num_worker_threads; ++i) { - struct sys_thread *worker_thread = pool->worker_threads[i]; - sys_thread_wait_release(worker_thread); + struct thread *worker_thread = pool->worker_threads[i]; + thread_wait_release(worker_thread); } } } /* Wait on scheduler thread */ if (!atomic32_fetch(&G.panicking)) { - sys_thread_wait_release(scheduler_thread); + thread_wait_release(scheduler_thread); } /* Find any dangling threads that haven't exited gracefully by now */ if (!atomic32_fetch(&G.panicking)) { struct snc_lock lock = snc_lock_s(&G.threads_mutex); - if (G.threads_first) { + if (G.first_thread) { struct arena_temp scratch = scratch_begin_no_conflict(); u64 num_dangling_threads = 0; struct string threads_msg = ZI; threads_msg.text = arena_push_dry(scratch.arena, u8); - for (struct win32_thread *t = G.threads_first; t; t = t->next) { + for (struct thread *t = G.first_thread; t; t = t->next) { struct string name = string_from_cstr(t->thread_name_cstr, countof(t->thread_name_cstr)); threads_msg.len += string_format(scratch.arena, LIT(" \"%F\"\n"), FMT_STR(name)).len; ++num_dangling_threads; diff --git a/src/user.c b/src/user.c index 92ef51e1..facecd20 100644 --- a/src/user.c +++ b/src/user.c @@ -93,8 +93,8 @@ GLOBAL struct { b32 debug_console; /* Window -> user */ - struct snc_mutex sys_events_mutex; - struct arena *sys_events_arena; + struct snc_mutex sys_window_events_mutex; + struct arena *sys_window_events_arena; /* User -> local sim */ struct snc_mutex user_sim_cmd_mutex; @@ -695,7 +695,7 @@ INTERNAL void user_update(struct sys_window *window) { __profn("Process sys events"); - struct sys_event_array events = sys_window_pop_events(scratch.arena, window); + struct sys_window_event_array events = sys_window_pop_events(scratch.arena, window); /* Reset bind pressed / released states */ for (u32 i = 0; i < countof(G.bind_states); ++i) { @@ -705,7 +705,7 @@ INTERNAL void user_update(struct sys_window *window) } for (u64 ent_index = 0; ent_index < events.count; ++ent_index) { - struct sys_event *event = &events.events[ent_index]; + struct sys_window_event *event = &events.events[ent_index]; if (event->kind == SYS_EVENT_KIND_QUIT) { sys_exit(); }