#include "commons/commons_thread.h" #include "commons/commons_fmt.h" #include "commons/commons_headers_windows.h" // IWYU pragma: keep #include "commons/commons_region_alloc.h" struct _thread { HANDLE handle; void (*fn)(void* userdata); void* userdata; }; namespace { auto WINAPI Trampoline(LPVOID arg) -> DWORD { thread self = (thread)arg; self->fn(self->userdata); return 0; } } // namespace auto API Thread_Create(region_alloc& alloc, void (*fn)(void* userdata), void* userdata) -> thread { _thread& self = RegionAlloc_Alloc<_thread>(alloc); self.fn = fn; self.userdata = userdata; self.handle = CreateThread(nullptr, 0, Trampoline, &self, 0, nullptr); ASSERT(self.handle); return &self; } auto API Thread_CreateMultiple(region_alloc& alloc, uint32_t numberToCreate, void (*fn)(void* userdata), void* userdata) -> thread_array { thread_array ThreadArray = RegionAlloc_AllocArray<_thread>(alloc, numberToCreate); for (_thread& Thread : ThreadArray) { Thread.fn = fn; Thread.userdata = userdata; Thread.handle = CreateThread(nullptr, 0, Trampoline, &Thread, 0, nullptr); ASSERT(Thread.handle); } return ThreadArray; } void API Thread_Join(thread self) { DWORD res = WaitForSingleObject(self->handle, INFINITE); ASSERT(res == WAIT_OBJECT_0); CloseHandle(self->handle); }