Update Files
This commit is contained in:
		| @ -0,0 +1,102 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef _WIN64 | ||||
| typedef __int64 INT_PTR; | ||||
| typedef unsigned __int64 UINT_PTR; | ||||
| typedef __int64 LONG_PTR; | ||||
| typedef unsigned __int64 ULONG_PTR; | ||||
| #else | ||||
| typedef _W64 int INT_PTR; | ||||
| typedef _W64 unsigned int UINT_PTR; | ||||
| typedef _W64 long LONG_PTR; | ||||
| typedef _W64 unsigned long ULONG_PTR; | ||||
| #endif // WIN64 | ||||
|  | ||||
| typedef unsigned long DWORD; | ||||
| typedef DWORD *LPDWORD; | ||||
| #define STD_OUTPUT_HANDLE ((DWORD)-11) | ||||
| #define STD_ERROR_HANDLE ((DWORD)-12) | ||||
| #define WINAPI __stdcall | ||||
| typedef void *HWND; | ||||
| typedef void *HANDLE; | ||||
| typedef unsigned int UINT; | ||||
| #define WINBASEAPI | ||||
| typedef int BOOL; | ||||
| #define CONST const | ||||
| #define VOID void | ||||
| typedef void *LPVOID; | ||||
| typedef char CHAR; | ||||
| typedef const CHAR *LPCSTR; | ||||
| typedef wchar_t WCHAR; | ||||
| typedef const WCHAR *LPCWSTR; | ||||
| typedef CONST CHAR *LPCCH, *PCCH; | ||||
| #define CP_UTF8 65001 | ||||
| typedef wchar_t WCHAR; | ||||
| typedef WCHAR *LPWSTR; | ||||
| typedef void *PVOID; | ||||
| typedef long LONG; | ||||
| typedef LONG *PLONG; | ||||
| typedef CONST void *LPCVOID; | ||||
|  | ||||
| #define GENERIC_READ (0x80000000L) | ||||
| #define GENERIC_WRITE (0x40000000L) | ||||
|  | ||||
| #define FILE_SHARE_READ 0x00000001 | ||||
|  | ||||
| #define CREATE_ALWAYS 2 | ||||
| #define OPEN_EXISTING 3 | ||||
|  | ||||
| #define FILE_ATTRIBUTE_NORMAL 0x00000080 | ||||
| #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) | ||||
| #define FILE_BEGIN 0 | ||||
| #define FILE_CURRENT 1 | ||||
| #define MAX_PATH 260 | ||||
|  | ||||
| typedef struct _SECURITY_ATTRIBUTES { | ||||
| 	DWORD nLength; | ||||
| 	LPVOID lpSecurityDescriptor; | ||||
| 	BOOL bInheritHandle; | ||||
| } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; | ||||
|  | ||||
| typedef struct _OVERLAPPED { | ||||
| 	ULONG_PTR Internal; | ||||
| 	ULONG_PTR InternalHigh; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			DWORD Offset; | ||||
| 			DWORD OffsetHigh; | ||||
| 		} DUMMYSTRUCTNAME; | ||||
| 		PVOID Pointer; | ||||
| 	} DUMMYUNIONNAME; | ||||
|  | ||||
| 	HANDLE hEvent; | ||||
| } OVERLAPPED, *LPOVERLAPPED; | ||||
|  | ||||
| WINBASEAPI BOOL WINAPI WriteConsoleA(HANDLE hConsoleOutput, CONST VOID *lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, | ||||
|                                      LPVOID lpReserved); | ||||
|  | ||||
| WINBASEAPI BOOL WINAPI WriteConsoleW(HANDLE hConsoleOutput, CONST VOID *lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, | ||||
|                                      LPVOID lpReserved); | ||||
|  | ||||
| WINBASEAPI VOID WINAPI OutputDebugStringA(LPCSTR lpOutputString); | ||||
|  | ||||
| WINBASEAPI VOID WINAPI OutputDebugStringW(LPCWSTR lpOutputString); | ||||
|  | ||||
| WINBASEAPI HANDLE WINAPI GetStdHandle(DWORD nStdHandle); | ||||
|  | ||||
| int WINAPI MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); | ||||
|  | ||||
| WINBASEAPI HANDLE WINAPI CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, | ||||
|                                      DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); | ||||
|  | ||||
| WINBASEAPI DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); | ||||
|  | ||||
| WINBASEAPI BOOL WINAPI ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); | ||||
|  | ||||
| WINBASEAPI DWORD WINAPI SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); | ||||
|  | ||||
| WINBASEAPI BOOL WINAPI CloseHandle(HANDLE hObject); | ||||
|  | ||||
| WINBASEAPI BOOL WINAPI WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); | ||||
|  | ||||
| int WINAPI MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); | ||||
| @ -0,0 +1,46 @@ | ||||
| #include "SystemMicrosoft.h" | ||||
|  | ||||
| #include <kinc/error.h> | ||||
| #include <kinc/libs/stb_sprintf.h> | ||||
|  | ||||
| #define S_OK ((HRESULT)0L) | ||||
|  | ||||
| static void winerror(HRESULT result) { | ||||
| 	LPVOID buffer = NULL; | ||||
| 	DWORD dw = GetLastError(); | ||||
|  | ||||
| 	__debugbreak(); | ||||
|  | ||||
| #if defined(KORE_WINDOWS) || defined(KORE_WINDOWSAPP) | ||||
| 	if (dw != 0) { | ||||
| 		FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, | ||||
| 		               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL); | ||||
|  | ||||
| 		kinc_error_message("Error: %s", buffer); | ||||
| 	} | ||||
| 	else { | ||||
| #endif | ||||
| 		kinc_error_message("Unknown Windows error, return value was 0x%x.", result); | ||||
| #if defined(KORE_WINDOWS) || defined(KORE_WINDOWSAPP) | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_microsoft_affirm(HRESULT result) { | ||||
| 	if (result != S_OK) { | ||||
| 		winerror(result); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void kinc_microsoft_affirm_message(HRESULT result, const char *format, ...) { | ||||
| 	va_list args; | ||||
| 	va_start(args, format); | ||||
| 	kinc_affirm_args(result == S_OK, format, args); | ||||
| 	va_end(args); | ||||
| } | ||||
|  | ||||
| void kinc_microsoft_format(const char *format, va_list args, wchar_t *buffer) { | ||||
| 	char cbuffer[4096]; | ||||
| 	vsprintf(cbuffer, format, args); | ||||
| 	MultiByteToWideChar(CP_UTF8, 0, cbuffer, -1, buffer, 4096); | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <stdio.h> | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef long HRESULT; | ||||
|  | ||||
| void kinc_microsoft_affirm(HRESULT result); | ||||
| void kinc_microsoft_affirm_message(HRESULT result, const char *format, ...); | ||||
| void kinc_microsoft_format(const char *format, va_list args, wchar_t *buffer); | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										53
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/atomic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/atomic.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifndef _WIN64 | ||||
| #include <kinc/error.h> | ||||
| #endif | ||||
|  | ||||
| #include <intrin.h> | ||||
|  | ||||
| static inline bool kinc_atomic_compare_exchange(volatile int32_t *pointer, int32_t old_value, int32_t new_value) { | ||||
| 	return _InterlockedCompareExchange((volatile long *)pointer, new_value, old_value) == old_value; | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_COMPARE_EXCHANGE(pointer, oldValue, newValue) (kinc_atomic_compare_exchange(pointer, oldValue, newValue)) | ||||
|  | ||||
| static inline bool kinc_atomic_compare_exchange_pointer(void *volatile *pointer, void *old_value, void *new_value) { | ||||
| 	return _InterlockedCompareExchangePointer(pointer, new_value, old_value) == old_value; | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_COMPARE_EXCHANGE_POINTER(pointer, oldValue, newValue) (kinc_atomic_compare_exchange_pointer(pointer, oldValue, newValue)) | ||||
|  | ||||
| static inline int32_t kinc_atomic_increment(volatile int32_t *pointer) { | ||||
| 	return _InterlockedIncrement((volatile long *)pointer) - 1; | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_INCREMENT(pointer) (kinc_atomic_increment(pointer)) | ||||
|  | ||||
| static inline int32_t kinc_atomic_decrement(volatile int32_t *pointer) { | ||||
| 	return _InterlockedDecrement((volatile long *)pointer) + 1; | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_DECREMENT(pointer) (kinc_atomic_decrement(pointer)) | ||||
|  | ||||
| static inline void kinc_atomic_exchange(volatile int32_t *pointer, int32_t value) { | ||||
| 	_InterlockedExchange((volatile long *)pointer, value); | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_EXCHANGE_32(pointer, value) (kinc_atomic_exchange(pointer, value)) | ||||
|  | ||||
| static inline void kinc_atomic_exchange_float(volatile float *pointer, float value) { | ||||
| 	_InterlockedExchange((volatile long *)pointer, *(long *)&value); | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_EXCHANGE_FLOAT(pointer, value) (kinc_atomic_exchange_float(pointer, value)) | ||||
|  | ||||
| static inline void kinc_atomic_exchange_double(volatile double *pointer, double value) { | ||||
| #ifdef _WIN64 | ||||
| 	_InterlockedExchange64((volatile __int64 *)pointer, *(__int64 *)&value); | ||||
| #else | ||||
| 	kinc_error_message("kinc_atomic_exchange_double is not supported for 32 bit Windows builds"); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #define KINC_ATOMIC_EXCHANGE_DOUBLE(pointer, value) (kinc_atomic_exchange_double(pointer, value)) | ||||
| @ -0,0 +1,25 @@ | ||||
| #include <kinc/threads/event.h> | ||||
|  | ||||
| void kinc_event_init(kinc_event_t *event, bool auto_clear) { | ||||
| 	event->impl.event = CreateEvent(0, auto_clear ? FALSE : TRUE, 0, 0); | ||||
| } | ||||
|  | ||||
| void kinc_event_destroy(kinc_event_t *event) { | ||||
| 	CloseHandle(event->impl.event); | ||||
| } | ||||
|  | ||||
| void kinc_event_signal(kinc_event_t *event) { | ||||
| 	SetEvent(event->impl.event); | ||||
| } | ||||
|  | ||||
| void kinc_event_wait(kinc_event_t *event) { | ||||
| 	WaitForSingleObject(event->impl.event, INFINITE); | ||||
| } | ||||
|  | ||||
| bool kinc_event_try_to_wait(kinc_event_t *event, double seconds) { | ||||
| 	return WaitForSingleObject(event->impl.event, (DWORD)(seconds * 1000.0)) != WAIT_TIMEOUT; | ||||
| } | ||||
|  | ||||
| void kinc_event_reset(kinc_event_t *event) { | ||||
| 	ResetEvent(event->impl.event); | ||||
| } | ||||
							
								
								
									
										13
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/event.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/event.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
| 	void *event; | ||||
| } kinc_event_impl_t; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -0,0 +1,35 @@ | ||||
| #include <kinc/threads/fiber.h> | ||||
|  | ||||
| VOID WINAPI fiber_func(LPVOID param) { | ||||
| #ifndef KORE_WINDOWSAPP | ||||
| 	kinc_fiber_t *fiber = (kinc_fiber_t *)param; | ||||
| 	fiber->impl.func(fiber->impl.param); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_fiber_init_current_thread(kinc_fiber_t *fiber) { | ||||
| #ifndef KORE_WINDOWSAPP | ||||
| 	fiber->impl.fiber = ConvertThreadToFiber(NULL); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_fiber_init(kinc_fiber_t *fiber, void (*func)(void *param), void *param) { | ||||
| #ifndef KORE_WINDOWSAPP | ||||
| 	fiber->impl.func = func; | ||||
| 	fiber->impl.param = param; | ||||
| 	fiber->impl.fiber = CreateFiber(0, fiber_func, fiber); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_fiber_destroy(kinc_fiber_t *fiber) { | ||||
| #ifndef KORE_WINDOWSAPP | ||||
| 	DeleteFiber(fiber->impl.fiber); | ||||
| 	fiber->impl.fiber = NULL; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_fiber_switch(kinc_fiber_t *fiber) { | ||||
| #ifndef KORE_WINDOWSAPP | ||||
| 	SwitchToFiber(fiber->impl.fiber); | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										15
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/fiber.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/fiber.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
| 	void *fiber; | ||||
| 	void (*func)(void *param); | ||||
| 	void *param; | ||||
| } kinc_fiber_impl_t; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -0,0 +1,56 @@ | ||||
| // Windows XP | ||||
| #define WINVER 0x0501 | ||||
| #define _WIN32_WINNT 0x0501 | ||||
|  | ||||
| #define NOATOM | ||||
| #define NOCLIPBOARD | ||||
| #define NOCOLOR | ||||
| #define NOCOMM | ||||
| #define NOCTLMGR | ||||
| #define NODEFERWINDOWPOS | ||||
| #define NODRAWTEXT | ||||
| #define NOGDI | ||||
| #define NOGDICAPMASKS | ||||
| #define NOHELP | ||||
| #define NOICONS | ||||
| #define NOKANJI | ||||
| #define NOKEYSTATES | ||||
| #define NOMB | ||||
| #define NOMCX | ||||
| #define NOMEMMGR | ||||
| #define NOMENUS | ||||
| #define NOMETAFILE | ||||
| #define NOMINMAX | ||||
| #define NOMSG | ||||
| //#define NONLS | ||||
| #define NOOPENFILE | ||||
| #define NOPROFILER | ||||
| #define NORASTEROPS | ||||
| #define NOSCROLL | ||||
| #define NOSERVICE | ||||
| #define NOSHOWWINDOW | ||||
| #define NOSOUND | ||||
| #define NOSYSCOMMANDS | ||||
| #define NOSYSMETRICS | ||||
| #define NOTEXTMETRIC | ||||
| #define NOUSER | ||||
| #define NOVIRTUALKEYCODES | ||||
| #define NOWH | ||||
| #define NOWINMESSAGES | ||||
| #define NOWINOFFSETS | ||||
| #define NOWINSTYLES | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
|  | ||||
| #include <Windows.h> | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <intrin.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "SystemMicrosoft.c.h" | ||||
| #include "event.c.h" | ||||
| #include "fiber.c.h" | ||||
| #include "mutex.c.h" | ||||
| #include "semaphore.c.h" | ||||
| #include "thread.c.h" | ||||
| #include "threadlocal.c.h" | ||||
| @ -0,0 +1,60 @@ | ||||
| #include <kinc/threads/mutex.h> | ||||
|  | ||||
| void kinc_mutex_init(kinc_mutex_t *mutex) { | ||||
| 	assert(sizeof(RTL_CRITICAL_SECTION) == sizeof(kinc_microsoft_critical_section_t)); | ||||
| 	InitializeCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection); | ||||
| } | ||||
|  | ||||
| void kinc_mutex_destroy(kinc_mutex_t *mutex) { | ||||
| 	DeleteCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection); | ||||
| } | ||||
|  | ||||
| void kinc_mutex_lock(kinc_mutex_t *mutex) { | ||||
| 	EnterCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection); | ||||
| } | ||||
|  | ||||
| bool kinc_mutex_try_to_lock(kinc_mutex_t *mutex) { | ||||
| 	return TryEnterCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection); | ||||
| } | ||||
|  | ||||
| void kinc_mutex_unlock(kinc_mutex_t *mutex) { | ||||
| 	LeaveCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection); | ||||
| } | ||||
|  | ||||
| bool kinc_uber_mutex_init(kinc_uber_mutex_t *mutex, const char *name) { | ||||
| #if defined(KORE_WINDOWS) || defined(KORE_WINDOWSAPP) | ||||
| 	mutex->impl.id = (void *)CreateMutexA(NULL, FALSE, name); | ||||
| 	HRESULT res = GetLastError(); | ||||
| 	if (res && res != ERROR_ALREADY_EXISTS) { | ||||
| 		mutex->impl.id = NULL; | ||||
| 		assert(false); | ||||
| 		return false; | ||||
| 	} | ||||
| 	return true; | ||||
| #else | ||||
| 	return false; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_uber_mutex_destroy(kinc_uber_mutex_t *mutex) { | ||||
| #if defined(KORE_WINDOWS) || defined(KORE_WINDOWSAPP) | ||||
| 	if (mutex->impl.id) { | ||||
| 		CloseHandle((HANDLE)mutex->impl.id); | ||||
| 		mutex->impl.id = NULL; | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_uber_mutex_lock(kinc_uber_mutex_t *mutex) { | ||||
| #if defined(KORE_WINDOWS) || defined(KORE_WINDOWSAPP) | ||||
| 	bool succ = WaitForSingleObject((HANDLE)mutex->impl.id, INFINITE) == WAIT_FAILED ? false : true; | ||||
| 	assert(succ); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_uber_mutex_unlock(kinc_uber_mutex_t *mutex) { | ||||
| #if defined(KORE_WINDOWS) || defined(KORE_WINDOWSAPP) | ||||
| 	bool succ = ReleaseMutex((HANDLE)mutex->impl.id) == FALSE ? false : true; | ||||
| 	assert(succ); | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										26
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/mutex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/mutex.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
| 	void *DebugInfo; | ||||
| 	long LockCount; | ||||
| 	long RecursionCount; | ||||
| 	void *OwningThread; | ||||
| 	void *LockSemaphore; | ||||
| 	unsigned long __w64 SpinCount; | ||||
| } kinc_microsoft_critical_section_t; | ||||
|  | ||||
| typedef struct { | ||||
| 	kinc_microsoft_critical_section_t criticalSection; | ||||
| } kinc_mutex_impl_t; | ||||
|  | ||||
| typedef struct { | ||||
| 	void *id; | ||||
| } kinc_uber_mutex_impl_t; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -0,0 +1,22 @@ | ||||
| #include <kinc/threads/semaphore.h> | ||||
|  | ||||
| void kinc_semaphore_init(kinc_semaphore_t *semaphore, int current, int max) { | ||||
| 	semaphore->impl.handle = CreateSemaphoreA(NULL, current, max, NULL); | ||||
| } | ||||
|  | ||||
| void kinc_semaphore_destroy(kinc_semaphore_t *semaphore) { | ||||
| 	CloseHandle(semaphore->impl.handle); | ||||
| 	semaphore->impl.handle = NULL; | ||||
| } | ||||
|  | ||||
| void kinc_semaphore_release(kinc_semaphore_t *semaphore, int count) { | ||||
| 	ReleaseSemaphore(semaphore->impl.handle, count, NULL); | ||||
| } | ||||
|  | ||||
| void kinc_semaphore_acquire(kinc_semaphore_t *semaphore) { | ||||
| 	WaitForSingleObject(semaphore->impl.handle, INFINITE); | ||||
| } | ||||
|  | ||||
| bool kinc_semaphore_try_to_acquire(kinc_semaphore_t *semaphore, double seconds) { | ||||
| 	return WaitForSingleObject(semaphore->impl.handle, (DWORD)(seconds * 1000)) == WAIT_OBJECT_0; | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| #pragma once | ||||
|  | ||||
| typedef struct { | ||||
| 	void *handle; | ||||
| } kinc_semaphore_impl_t; | ||||
| @ -0,0 +1,87 @@ | ||||
| #include <kinc/threads/thread.h> | ||||
|  | ||||
| #ifdef KINC_VTUNE | ||||
| #include <ittnotify.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef KINC_SUPERLUMINAL | ||||
| #include <Superluminal/PerformanceAPI_capi.h> | ||||
| #endif | ||||
|  | ||||
| void kinc_threads_init() {} | ||||
|  | ||||
| void kinc_threads_quit() {} | ||||
|  | ||||
| struct thread_start { | ||||
| 	void (*thread)(void *param); | ||||
| 	void *param; | ||||
| }; | ||||
|  | ||||
| #define THREAD_STARTS 64 | ||||
| static struct thread_start starts[THREAD_STARTS]; | ||||
| static int thread_start_index = 0; | ||||
|  | ||||
| static DWORD WINAPI ThreadProc(LPVOID arg) { | ||||
| 	intptr_t start_index = (intptr_t)arg; | ||||
| 	starts[start_index].thread(starts[start_index].param); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void kinc_thread_init(kinc_thread_t *thread, void (*func)(void *param), void *param) { | ||||
| 	thread->impl.func = func; | ||||
| 	thread->impl.param = param; | ||||
|  | ||||
| 	intptr_t start_index = thread_start_index++; | ||||
| 	if (thread_start_index >= THREAD_STARTS) { | ||||
| 		thread_start_index = 0; | ||||
| 	} | ||||
| 	starts[start_index].thread = func; | ||||
| 	starts[start_index].param = param; | ||||
| 	thread->impl.handle = CreateThread(0, 65536, ThreadProc, (LPVOID)start_index, 0, 0); | ||||
| 	assert(thread->impl.handle != NULL); | ||||
| } | ||||
|  | ||||
| void kinc_thread_wait_and_destroy(kinc_thread_t *thread) { | ||||
| 	WaitForSingleObject(thread->impl.handle, INFINITE); | ||||
| 	CloseHandle(thread->impl.handle); | ||||
| } | ||||
|  | ||||
| bool kinc_thread_try_to_destroy(kinc_thread_t *thread) { | ||||
| 	DWORD code; | ||||
| 	GetExitCodeThread(thread->impl.handle, &code); | ||||
| 	if (code != STILL_ACTIVE) { | ||||
| 		CloseHandle(thread->impl.handle); | ||||
| 		return true; | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| typedef HRESULT(WINAPI *SetThreadDescriptionType)(HANDLE hThread, PCWSTR lpThreadDescription); | ||||
| static SetThreadDescriptionType MySetThreadDescription = NULL; | ||||
| static bool set_thread_description_loaded = false; | ||||
|  | ||||
| void kinc_thread_set_name(const char *name) { | ||||
| 	if (!set_thread_description_loaded) { | ||||
| 		HMODULE kernel32 = LoadLibraryA("kernel32.dll"); | ||||
| 		MySetThreadDescription = (SetThreadDescriptionType)GetProcAddress(kernel32, "SetThreadDescription"); | ||||
| 		set_thread_description_loaded = true; | ||||
| 	} | ||||
|  | ||||
| 	if (MySetThreadDescription != NULL) { | ||||
| 		wchar_t wide_name[256]; | ||||
| 		MultiByteToWideChar(CP_ACP, 0, name, -1, wide_name, 256); | ||||
| 		MySetThreadDescription(GetCurrentThread(), wide_name); | ||||
| 	} | ||||
|  | ||||
| #ifdef KINC_VTUNE | ||||
| 	__itt_thread_set_name(name); | ||||
| #endif | ||||
|  | ||||
| #ifdef KINC_SUPERLUMINAL | ||||
| 	PerformanceAPI_SetCurrentThreadName(name); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void kinc_thread_sleep(int milliseconds) { | ||||
| 	Sleep(milliseconds); | ||||
| } | ||||
							
								
								
									
										15
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/thread.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Kinc/Backends/System/Microsoft/Sources/kinc/backend/thread.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
| 	void *handle; | ||||
| 	void *param; | ||||
| 	void (*func)(void *param); | ||||
| } kinc_thread_impl_t; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -0,0 +1,18 @@ | ||||
| #include <kinc/threads/threadlocal.h> | ||||
|  | ||||
| void kinc_thread_local_init(kinc_thread_local_t *local) { | ||||
| 	local->impl.slot = TlsAlloc(); | ||||
| 	TlsSetValue(local->impl.slot, 0); | ||||
| } | ||||
|  | ||||
| void kinc_thread_local_destroy(kinc_thread_local_t *local) { | ||||
| 	TlsFree(local->impl.slot); | ||||
| } | ||||
|  | ||||
| void *kinc_thread_local_get(kinc_thread_local_t *local) { | ||||
| 	return TlsGetValue(local->impl.slot); | ||||
| } | ||||
|  | ||||
| void kinc_thread_local_set(kinc_thread_local_t *local, void *data) { | ||||
| 	TlsSetValue(local->impl.slot, data); | ||||
| } | ||||
| @ -0,0 +1,13 @@ | ||||
| #pragma once | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| typedef struct { | ||||
| 	int slot; | ||||
| } kinc_thread_local_impl_t; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user