forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			88 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			88 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #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); | ||
|  | } |