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);
							 | 
						||
| 
								 | 
							
								}
							 |