diff --git a/platform_all/4ed_link_system_functions.cpp b/platform_all/4ed_link_system_functions.cpp index 0444ee8b..85764045 100644 --- a/platform_all/4ed_link_system_functions.cpp +++ b/platform_all/4ed_link_system_functions.cpp @@ -11,7 +11,7 @@ // TODO(allen): Should auto-gen this! -#define SYSLINK(name) system->name = system_##name +#define SYSLINK(name) sysfunc.name = system_##name internal void link_system_code(System_Functions *system){ diff --git a/platform_all/4ed_work_queues.cpp b/platform_all/4ed_work_queues.cpp index 0d76f75f..bc584011 100644 --- a/platform_all/4ed_work_queues.cpp +++ b/platform_all/4ed_work_queues.cpp @@ -9,6 +9,28 @@ // TOP +struct Thread_Context{ + u32 job_id; + b32 running; + b32 cancel; + + Work_Queue *queue; + u32 id; + u32 group_id; + u32 windows_id; + Thread thread; +}; + +struct Thread_Group{ + Thread_Context *threads; + i32 count; + + Unbounded_Work_Queue queue; + + i32 cancel_lock0; + i32 cancel_cv0; +}; + struct Threading_Vars{ Thread_Memory *thread_memory; Work_Queue queues[THREAD_GROUP_COUNT]; @@ -28,8 +50,10 @@ Sys_Release_Lock_Sig(system_release_lock){ system_release_lock(&threadvars.locks[id]); } -internal void -job_thread_proc(System_Functions *system, Thread_Context *thread){ +internal +PLAT_THREAD_SIG(job_thread_proc){ + Thread_Context *thread = (Thread_Context*)ptr; + Work_Queue *queue = threadvars.queues + thread->group_id; Thread_Group *group = threadvars.groups + thread->group_id; @@ -66,7 +90,7 @@ job_thread_proc(System_Functions *system, Thread_Context *thread){ if (safe_running_thread == THREAD_NOT_ASSIGNED){ thread->job_id = full_job->id; thread->running = true; - full_job->job.callback(system, thread, thread_memory, full_job->job.data); + full_job->job.callback(&sysfunc, thread, thread_memory, full_job->job.data); system_schedule_step(); thread->running = false; diff --git a/platform_linux/linux_4ed.cpp b/platform_linux/linux_4ed.cpp index 09dc5989..98edba11 100644 --- a/platform_linux/linux_4ed.cpp +++ b/platform_linux/linux_4ed.cpp @@ -76,6 +76,7 @@ #include #include +#include "4ed_link_system_functions.cpp" // // Linux macros @@ -112,34 +113,15 @@ struct Linux_Coroutine { b32 done; }; -struct Thread_Context{ - u32 job_id; - b32 running; - b32 cancel; - - Work_Queue *queue; - u32 id; - u32 group_id; - pthread_t handle; -}; +// +// Linux forward declarations +// -struct Thread_Group{ - Thread_Context *threads; - i32 count; - - Unbounded_Work_Queue queue; - - i32 cancel_lock0; - i32 cancel_cv0; -}; +internal void LinuxScheduleStep(void); -struct Mutex{ - pthread_mutex_t crit; -}; - -struct Condition_Variable{ - pthread_cond_t cv; -}; +internal void LinuxStringDup(String*, void*, size_t); +internal void LinuxToggleFullscreen(Display*, Window); +internal void LinuxFatalErrorMsg(const char* msg); struct Linux_Vars{ Display *XDisplay; @@ -195,7 +177,6 @@ struct Linux_Vars{ i32 dpi_x, dpi_y; Plat_Settings settings; - System_Functions system; App_Functions app; Custom_API custom_api; b32 vsync; @@ -208,30 +189,85 @@ struct Linux_Vars{ // Linux globals // +global System_Functions sysfunc; global Linux_Vars linuxvars; global Application_Memory memory_vars; -// -// Linux forward declarations -// +//////////////////////////////// -internal void LinuxScheduleStep(void); +internal Plat_Handle +handle_sem(sem_t *sem){ + return(*(Plat_Handle*)&sem); +} -internal Plat_Handle LinuxSemToHandle(sem_t*); -internal sem_t* LinuxHandleToSem(Plat_Handle); +internal sem_t* +handle_sem(Plat_Handle h){ + return(*(sem_t**)&h); +} -internal Plat_Handle LinuxFDToHandle(int); -internal int LinuxHandleToFD(Plat_Handle); +internal Plat_Handle +handle_fd(int fd){ + return(*(Plat_Handle*)&fd); +} -internal void LinuxStringDup(String*, void*, size_t); -internal void LinuxToggleFullscreen(Display*, Window); -internal void LinuxFatalErrorMsg(const char* msg); +internal int +handle_fd(Plat_Handle h){ + return(*(int*)&h); +} -internal Sys_Acquire_Lock_Sig(system_acquire_lock); -internal Sys_Release_Lock_Sig(system_release_lock); +//////////////////////////////// -internal void system_wait_cv(i32, i32); -internal void system_signal_cv(i32, i32); +struct Thread{ + pthread_t t; +}; + +struct Mutex{ + pthread_mutex_t crit; +}; + +struct Condition_Variable{ + pthread_cond_t cv; +}; + +internal void +system_acquire_lock(Mutex *m){ + pthread_mutex_lock(m->crit); +} + +internal void +system_release_lock(Mutex *m){ + pthread_mutex_unlock(m->crit); +} + +internal void +system_wait_cv(Condition_Variable *cv, Mutex *m){ + pthread_cond_wait(cv->cv, m->crit); +} + +internal void +system_signal_cv(Condition_Variable *cv, Mutex *m){ + pthread_cond_signal(cv->cv); +} + +// HACK(allen): Reduce this down to just one layer of call. +internal void +system_schedule_step(){ + LinuxScheduleStep(); +} + +internal void +system_wait_on(Plat_Handle handle){ + sem_wait(handle_sem(handle)); +} + +internal void +system_release_semaphore(Plat_Handle handle){ + sem_post(handle_sem(handle)); +} + +#define PLAT_THREAD_SIG(n) void* n(void *ptr) + +//////////////////////////////// internal Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){ @@ -482,56 +518,8 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ return(close_me); } -// -// Multithreading -// - -internal void -system_acquire_lock(Mutex *m){ - pthread_mutex_lock(m->crit); -} - -internal void -system_release_lock(Mutex *m){ - pthread_mutex_unlock(m->crit); -} - -internal void -system_wait_cv(Condition_Variable *cv, Mutex *m){ - pthread_cond_wait(cv->cv, m->crit); -} - -internal void -system_signal_cv(Condition_Variable *cv, Mutex *m){ - pthread_cond_signal(cv->cv); -} - -// HACK(allen): Reduce this down to just one layer of call. -internal void -system_schedule_step(){ - LinuxScheduleStep(); -} - -internal void -system_wait_on(Plat_Handle handle){ - sem_wait(LinuxHandleToSem(handle)); -} - -internal void -system_release_semaphore(Plat_Handle handle){ - sem_post(LinuxHandleToSem(handle)); -} - #include "4ed_work_queues.cpp" -internal void* -JobThreadProc(void* lpParameter){ - Thread_Context *thread = (Thread_Context*)lpParameter; - job_thread_proc(&linuxvars.system, thread); - InvalidCodePath; - return(0); -} - // // Linux rendering/font system functions // @@ -585,7 +573,7 @@ LinuxLoadRenderCode(){ internal void LinuxRedrawTarget(){ - launch_rendering(&linuxvars.system, &linuxvars.target); + launch_rendering(&sysfunc, &linuxvars.target); //glFlush(); glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow); } @@ -1077,26 +1065,6 @@ LinuxPushKey(Key_Code code, Key_Code chr, Key_Code chr_nocaps, b8 (*mods)[MDFR_I // Misc utility funcs // -internal Plat_Handle -LinuxSemToHandle(sem_t* sem){ - return *(Plat_Handle*)&sem; -} - -internal sem_t* -LinuxHandleToSem(Plat_Handle h){ - return *(sem_t**)&h; -} - -internal Plat_Handle -LinuxFDToHandle(int fd){ - return *(Plat_Handle*)&fd; -} - -internal int -LinuxHandleToFD(Plat_Handle h){ - return *(int*)&h; -} - internal void LinuxStringDup(String* str, void* data, size_t size){ if (str->memory_size < size){ @@ -1946,7 +1914,7 @@ main(int argc, char **argv){ return 99; } - link_system_code(&linuxvars.system); + link_system_code(&sysfunc); LinuxLoadRenderCode(); memory_vars.vars_memory_size = MB(2); @@ -1988,7 +1956,7 @@ main(int argc, char **argv){ i32 *file_count; i32 output_size; - output_size = linuxvars.app.read_command_line(&linuxvars.system, &memory_vars, current_directory, &linuxvars.settings, &files, &file_count, clparams); + output_size = linuxvars.app.read_command_line(&sysfunc, &memory_vars, current_directory, &linuxvars.settings, &files, &file_count, clparams); if (output_size > 0){ LOGF("%.*s", output_size, (char*)memory_vars.target_memory); @@ -2099,7 +2067,7 @@ main(int argc, char **argv){ memory->id = thread->id; thread->queue = &threadvars.queues[BACKGROUND_THREADS]; - pthread_create(&thread->handle, NULL, &JobThreadProc, thread); + pthread_create(&thread->handle, NULL, &job_thread_proc, thread); } initialize_unbounded_queue(&threadvars.groups[BACKGROUND_THREADS].queue); @@ -2208,7 +2176,7 @@ main(int argc, char **argv){ // Font System Init // - system_font_init(&linuxvars.system.font, 0, 0, linuxvars.settings.font_size, linuxvars.settings.use_hinting); + system_font_init(&sysfunc.font, 0, 0, linuxvars.settings.font_size, linuxvars.settings.use_hinting); // // Epoll init @@ -2241,7 +2209,7 @@ main(int argc, char **argv){ XAddConnectionWatch(linuxvars.XDisplay, &LinuxX11ConnectionWatch, NULL); - linuxvars.app.init(&linuxvars.system, &linuxvars.target, &memory_vars, linuxvars.clipboard_contents, current_directory, linuxvars.custom_api); + linuxvars.app.init(&sysfunc, &linuxvars.target, &memory_vars, linuxvars.clipboard_contents, current_directory, linuxvars.custom_api); LinuxResizeTarget(window_width, window_height); @@ -2319,14 +2287,7 @@ main(int argc, char **argv){ linuxvars.last_step = system_now_time(); if (linuxvars.input.first_step || !linuxvars.has_xfixes){ - XConvertSelection( - linuxvars.XDisplay, - linuxvars.atom_CLIPBOARD, - linuxvars.atom_UTF8_STRING, - linuxvars.atom_CLIPBOARD, - linuxvars.XWindow, - CurrentTime - ); + XConvertSelection(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.atom_UTF8_STRING, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime); } Application_Step_Result result = {}; @@ -2342,14 +2303,7 @@ main(int argc, char **argv){ b32 keep_running = linuxvars.keep_running; - linuxvars.app.step( - &linuxvars.system, - &linuxvars.target, - &memory_vars, - &linuxvars.input, - &result, - clparams - ); + linuxvars.app.step(&sysfunc, &linuxvars.target, &memory_vars, &linuxvars.input, &result, clparams); if (result.perform_kill){ break; diff --git a/platform_linux/linux_4ed_fonts.cpp b/platform_linux/linux_4ed_fonts.cpp index 50e01c15..b8c29c61 100644 --- a/platform_linux/linux_4ed_fonts.cpp +++ b/platform_linux/linux_4ed_fonts.cpp @@ -71,7 +71,7 @@ Sys_Font_Get_Render_Data_By_ID_Sig(system_font_get_render_data_by_id){ internal Sys_Font_Load_Page_Sig(system_font_load_page){ - system_set_page(&linuxvars.system, &linux_fonts.part, font, page, page_number, linuxvars.settings.font_size, linuxvars.settings.use_hinting); + system_set_page(&sysfunc, &linux_fonts.part, font, page, page_number, linuxvars.settings.font_size, linuxvars.settings.use_hinting); } internal @@ -157,7 +157,7 @@ Sys_Font_Init_Sig(system_font_init){ if (i < font_count_max){ Render_Font *render_font = &linux_fonts.fonts[i]; - system_set_font(&linuxvars.system, &linux_fonts.part, render_font, ptr->c_filename, font_size, use_hinting); + system_set_font(&sysfunc, &linux_fonts.part, render_font, ptr->c_filename, font_size, use_hinting); } ++font_count; diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 4bc349c7..bdf7eb34 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -135,38 +135,7 @@ enum CV_ID{ CV_COUNT }; -struct Thread_Context{ - u32 job_id; - b32 running; - b32 cancel; - - Work_Queue *queue; - u32 id; - u32 group_id; - u32 windows_id; - HANDLE handle; -}; - -struct Thread_Group{ - Thread_Context *threads; - i32 count; - - Unbounded_Work_Queue queue; - - i32 cancel_lock0; - i32 cancel_cv0; -}; - -struct Mutex{ - CRITICAL_SECTION crit; -}; - -struct Condition_Variable{ - CONDITION_VARIABLE cv; -}; - struct Win32_Vars{ - System_Functions system; App_Functions app; Custom_API custom_api; HMODULE app_code; @@ -208,9 +177,79 @@ struct Win32_Vars{ }; +global System_Functions sysfunc; global Win32_Vars win32vars; global Application_Memory memory_vars; +//////////////////////////////// + +internal HANDLE +handle_type(Plat_Handle h){ + HANDLE result; + memcpy(&result, &h, sizeof(result)); + return(result); +} + +internal Plat_Handle +handle_type(HANDLE h){ + Plat_Handle result = {0}; + memcpy(&result, &h, sizeof(h)); + return(result); +} + +//////////////////////////////// + +struct Thread{ + HANDLE t; +}; + +struct Mutex{ + CRITICAL_SECTION crit; +}; + +struct Condition_Variable{ + CONDITION_VARIABLE cv; +}; + +internal void +system_acquire_lock(Mutex *m){ + EnterCriticalSection(&m->crit); +} + +internal void +system_release_lock(Mutex *m){ + LeaveCriticalSection(&m->crit); +} + +internal void +system_wait_cv(Condition_Variable *cv, Mutex *lock){ + SleepConditionVariableCS(&cv->cv, &lock->crit, INFINITE); +} + +internal void +system_signal_cv(Condition_Variable *cv, Mutex *lock){ + WakeConditionVariable(&cv->cv); +} + +internal void +system_schedule_step(){ + PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); +} + +internal void +system_wait_on(Plat_Handle handle){ + WaitForSingleObject(handle_type(handle), INFINITE); +} + +internal void +system_release_semaphore(Plat_Handle handle){ + ReleaseSemaphore(handle_type(handle), 1, 0); +} + +#define PLAT_THREAD_SIG(n) DWORD CALL_CONVENTION n(LPVOID ptr) + +//////////////////////////////// + // // 4ed path // @@ -254,40 +293,6 @@ Sys_Log_Sig(system_log){ } } -// -// Helpers -// - -internal HANDLE -Win32Handle(Plat_Handle h){ - HANDLE result; - memcpy(&result, &h, sizeof(result)); - return(result); -} - -internal Plat_Handle -Win32Handle(HANDLE h){ - Plat_Handle result = {0}; - Assert(sizeof(Plat_Handle) >= sizeof(h)); - memcpy(&result, &h, sizeof(h)); - return(result); -} - -internal void* -Win32Ptr(Plat_Handle h){ - void *result; - memcpy(&result, &h, sizeof(result)); - return(result); -} - -internal Plat_Handle -Win32Ptr(void *h){ - Plat_Handle result = {0}; - memcpy(&result, &h, sizeof(h)); - return(result); -} - - // // Memory (not exposed to application, but needed in system_shared.cpp) // @@ -333,55 +338,8 @@ Sys_Memory_Free_Sig(system_memory_free){ VirtualFree(ptr, 0, MEM_RELEASE); } -// -// Multithreading -// - -internal void -system_acquire_lock(Mutex *m){ - EnterCriticalSection(&m->crit); -} - -internal void -system_release_lock(Mutex *m){ - LeaveCriticalSection(&m->crit); -} - -internal void -system_wait_cv(Condition_Variable *cv, Mutex *lock){ - SleepConditionVariableCS(&cv->cv, &lock->crit, INFINITE); -} - -internal void -system_signal_cv(Condition_Variable *cv, Mutex *lock){ - WakeConditionVariable(&cv->cv); -} - -internal void -system_schedule_step(){ - PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); -} - -internal void -system_wait_on(Plat_Handle handle){ - WaitForSingleObject(Win32Handle(handle), INFINITE); -} - -internal void -system_release_semaphore(Plat_Handle handle){ - ReleaseSemaphore(Win32Handle(handle), 1, 0); -} - #include "4ed_work_queues.cpp" -internal DWORD CALL_CONVENTION -JobThreadProc(LPVOID lpParameter){ - Thread_Context *thread = (Thread_Context*)lpParameter; - job_thread_proc(&win32vars.system, thread); - InvalidCodePath; - return(0); -} - // // Coroutines // @@ -422,7 +380,7 @@ Sys_Create_Coroutine_Sig(system_create_coroutine){ fiber = CreateFiber(0, Win32CoroutineMain, coroutine); - coroutine->plat_handle = Win32Handle(fiber); + coroutine->plat_handle = handle_type(fiber); coroutine->func = func; return(coroutine); @@ -433,7 +391,7 @@ Sys_Launch_Coroutine_Sig(system_launch_coroutine){ Win32_Coroutine *c = (Win32_Coroutine*)coroutine; void *fiber; - fiber = Win32Handle(coroutine->plat_handle); + fiber = handle_type(coroutine->plat_handle); coroutine->yield_handle = GetCurrentFiber(); coroutine->in = in; coroutine->out = out; @@ -459,7 +417,7 @@ Sys_Resume_Coroutine_Sig(system_resume_coroutine){ coroutine->in = in; coroutine->out = out; - fiber = Win32Ptr(coroutine->plat_handle); + fiber = handle_type(coroutine->plat_handle); SwitchToFiber(fiber); @@ -1207,7 +1165,7 @@ Win32KeycodeInit(){ internal void Win32RedrawScreen(HDC hdc){ - launch_rendering(&win32vars.system, &win32vars.target); + launch_rendering(&sysfunc, &win32vars.target); glFlush(); SwapBuffers(hdc); } @@ -1677,7 +1635,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS Thread_Memory thread_memory[ArrayCount(background)]; threadvars.thread_memory = thread_memory; - threadvars.queues[BACKGROUND_THREADS].semaphore =Win32Handle(CreateSemaphore(0, 0, threadvars.groups[BACKGROUND_THREADS].count, 0)); + threadvars.queues[BACKGROUND_THREADS].semaphore =handle_type(CreateSemaphore(0, 0, threadvars.groups[BACKGROUND_THREADS].count, 0)); u32 creation_flag = 0; for (i32 i = 0; i < threadvars.groups[BACKGROUND_THREADS].count; ++i){ @@ -1691,7 +1649,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS thread->queue = &threadvars.queues[BACKGROUND_THREADS]; - thread->handle = CreateThread(0, 0, JobThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); + thread->thread.t = CreateThread(0, 0, job_thread_proc, thread, creation_flag, (LPDWORD)&thread->windows_id); } initialize_unbounded_queue(&threadvars.groups[BACKGROUND_THREADS].queue); @@ -1754,11 +1712,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } - link_system_code(&win32vars.system); + link_system_code(&sysfunc); Win32LoadRenderCode(); - System_Functions *system = &win32vars.system; - // // Shared Systems Init // @@ -1785,7 +1741,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS char **files = 0; i32 *file_count = 0; - win32vars.app.read_command_line(system, &memory_vars, current_directory, &win32vars.settings, &files, &file_count, clparams); + win32vars.app.read_command_line(&sysfunc, &memory_vars, current_directory, &win32vars.settings, &files, &file_count, clparams); sysshared_filter_real_files(files, file_count); LOG("Loaded system code, read command line.\n"); @@ -1907,7 +1863,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS // LOG("Initializing fonts\n"); - system_font_init(&system->font, 0, 0, win32vars.settings.font_size, win32vars.settings.use_hinting); + system_font_init(&sysfunc.font, 0, 0, win32vars.settings.font_size, win32vars.settings.use_hinting); // // Misc System Initializations @@ -1956,7 +1912,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS // LOG("Initializing application variables\n"); - win32vars.app.init(system, &win32vars.target, &memory_vars, win32vars.clipboard_contents, current_directory, win32vars.custom_api); + win32vars.app.init(&sysfunc, &win32vars.target, &memory_vars, win32vars.clipboard_contents, current_directory, win32vars.custom_api); system_memory_free(current_directory.str, 0); @@ -2157,7 +2113,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS win32vars.send_exit_signal = 0; } - win32vars.app.step(system, &win32vars.target, &memory_vars, &input, &result, clparams); + win32vars.app.step(&sysfunc, &win32vars.target, &memory_vars, &input, &result, clparams); if (result.perform_kill){ keep_playing = 0; diff --git a/platform_win32/win32_4ed_fonts.cpp b/platform_win32/win32_4ed_fonts.cpp index 0ce23fcb..b9b1656f 100644 --- a/platform_win32/win32_4ed_fonts.cpp +++ b/platform_win32/win32_4ed_fonts.cpp @@ -71,7 +71,7 @@ Sys_Font_Get_Render_Data_By_ID_Sig(system_font_get_render_data_by_id){ internal Sys_Font_Load_Page_Sig(system_font_load_page){ - system_set_page(&win32vars.system, &win32_fonts.part, font, page, page_number, win32vars.settings.font_size, win32vars.settings.use_hinting); + system_set_page(&sysfunc, &win32_fonts.part, font, page, page_number, win32vars.settings.font_size, win32vars.settings.use_hinting); } internal @@ -157,7 +157,7 @@ Sys_Font_Init_Sig(system_font_init){ if (i < font_count_max){ Render_Font *render_font = &win32_fonts.fonts[i]; - system_set_font(&win32vars.system, &win32_fonts.part, render_font, ptr->c_filename, font_size, use_hinting); + system_set_font(&sysfunc, &win32_fonts.part, render_font, ptr->c_filename, font_size, use_hinting); } ++font_count;