forked from LeenkxTeam/LNXSDK
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(KINC_WINDOWS) || defined(KINC_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(KINC_WINDOWS) || defined(KINC_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
|
@ -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);
|
||||
}
|
@ -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 KINC_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 KINC_WINDOWSAPP
|
||||
fiber->impl.fiber = ConvertThreadToFiber(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void kinc_fiber_init(kinc_fiber_t *fiber, void (*func)(void *param), void *param) {
|
||||
#ifndef KINC_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 KINC_WINDOWSAPP
|
||||
DeleteFiber(fiber->impl.fiber);
|
||||
fiber->impl.fiber = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void kinc_fiber_switch(kinc_fiber_t *fiber) {
|
||||
#ifndef KINC_WINDOWSAPP
|
||||
SwitchToFiber(fiber->impl.fiber);
|
||||
#endif
|
||||
}
|
@ -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(KINC_WINDOWS) || defined(KINC_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(KINC_WINDOWS) || defined(KINC_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(KINC_WINDOWS) || defined(KINC_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(KINC_WINDOWS) || defined(KINC_WINDOWSAPP)
|
||||
bool succ = ReleaseMutex((HANDLE)mutex->impl.id) == FALSE ? false : true;
|
||||
assert(succ);
|
||||
#endif
|
||||
}
|
@ -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);
|
||||
}
|
@ -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