From daa2adce4cbd6b80a50d146eda85fdeb7e059e0d Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 13 May 2026 22:30:18 +0200 Subject: [PATCH] basic wrapper around threads and semaphores (windows) --- Engine/src/delta/platform/os_internal.h | 19 ++++++ Engine/src/delta/platform/os_win32.cpp | 78 +++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/Engine/src/delta/platform/os_internal.h b/Engine/src/delta/platform/os_internal.h index 09c5ced..96afb0c 100644 --- a/Engine/src/delta/platform/os_internal.h +++ b/Engine/src/delta/platform/os_internal.h @@ -32,4 +32,23 @@ namespace delta::platform void* CommitMemory(void* mem, size_t commitSize); void DecommitMemory(void* mem, size_t decommitSize); void ReleaseMemory(void* mem); + + struct OSThreadHandle; + struct OSSemaphoreHandle; + + struct ThreadCreationInfo + { + void (*entryPoint)(void*); + void* userData; + uint32_t coreAffinityMask; + const char* debugName; + }; + + OSThreadHandle* CreateEngineThread(const ThreadCreationInfo& info); + void DestroyEngineThread(OSThreadHandle* thread); + void SetThreadAffinity(OSThreadHandle* thread, uint32_t mask); + + OSSemaphoreHandle* CreateEngineSemaphore(uint32_t initialCount); + void WaitOnSemaphore(OSSemaphoreHandle* sem); + void SignalSemaphore(OSSemaphoreHandle* sem, uint32_t count); } diff --git a/Engine/src/delta/platform/os_win32.cpp b/Engine/src/delta/platform/os_win32.cpp index f8cc81b..cec8efd 100644 --- a/Engine/src/delta/platform/os_win32.cpp +++ b/Engine/src/delta/platform/os_win32.cpp @@ -56,6 +56,24 @@ namespace delta::platform } } + struct OSThreadHandle + { + HANDLE handle; + DWORD osThreadId; + }; + + struct OSSemaphoreHandle + { + HANDLE handle; + }; + + static DWORD WINAPI ThreadWindowsEntry(LPVOID param) + { + auto* info = static_cast(param); + info->entryPoint(info->userData); + return 0; + } + inline static void fetchCpuidValues() { int cpuinfo[4]; @@ -136,6 +154,66 @@ namespace delta::platform return status; } + + OSThreadHandle* CreateEngineThread(const ThreadCreationInfo& info) + { + OSThreadHandle* thread = new OSThreadHandle(); // TODO: custom global allocator, or living on the main thread + thread->handle = CreateThread( + nullptr, 0, + ThreadWindowsEntry, + (void*)&info, + 0, + &thread->osThreadId + ); + + assert(thread->handle != 0); + + if (info.debugName) { + // TODO: Convert to wide string + } + + if (info.coreAffinityMask > 0) { + SetThreadAffinityMask(thread->handle, info.coreAffinityMask); + } + + return thread; + } + + void DestroyEngineThread(OSThreadHandle* thread) + { + if (!thread) + return; + + WaitForSingleObject(thread->handle, INFINITE); + CloseHandle(thread->handle); + + delete thread; + } + + void SetThreadAffinity(OSThreadHandle* thread, uint32_t mask) + { + if (!thread) + return; + + SetThreadAffinityMask(thread->handle, mask); + } + + OSSemaphoreHandle* CreateEngineSemaphore(uint32_t initialCount) + { + OSSemaphoreHandle* sem = new OSSemaphoreHandle(); + sem->handle = CreateSemaphoreA(nullptr, initialCount, LONG_MAX, nullptr); + return sem; + } + + void WaitOnSemaphore(OSSemaphoreHandle* sem) + { + WaitForSingleObject(sem->handle, INFINITE); + } + + void SignalSemaphore(OSSemaphoreHandle* sem, uint32_t count) + { + ReleaseSemaphore(sem->handle, count, nullptr); + } } #endif