83 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			83 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #include <kinc/threads/thread.h>
 | ||
|  | 
 | ||
|  | #include <assert.h>
 | ||
|  | #include <stdio.h>
 | ||
|  | #include <string.h>
 | ||
|  | #include <unistd.h>
 | ||
|  | #include <wchar.h>
 | ||
|  | 
 | ||
|  | #if !defined(KINC_IOS) && !defined(KINC_MACOS)
 | ||
|  | 
 | ||
|  | 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 void *ThreadProc(void *arg) { | ||
|  | 	intptr_t start_index = (intptr_t)arg; | ||
|  | 	starts[start_index].thread(starts[start_index].param); | ||
|  | 	pthread_exit(NULL); | ||
|  | 	return NULL; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_thread_init(kinc_thread_t *t, void (*thread)(void *param), void *param) { | ||
|  | 	t->impl.param = param; | ||
|  | 	t->impl.thread = thread; | ||
|  | 	pthread_attr_t attr; | ||
|  | 	pthread_attr_init(&attr); | ||
|  | 	// pthread_attr_setstacksize(&attr, 1024 * 64);
 | ||
|  | 	struct sched_param sp; | ||
|  | 	memset(&sp, 0, sizeof(sp)); | ||
|  | 	sp.sched_priority = 0; | ||
|  | 	pthread_attr_setschedparam(&attr, &sp); | ||
|  | 	intptr_t start_index = thread_start_index++; | ||
|  | 	if (thread_start_index >= THREAD_STARTS) { | ||
|  | 		thread_start_index = 0; | ||
|  | 	} | ||
|  | 	starts[start_index].thread = thread; | ||
|  | 	starts[start_index].param = param; | ||
|  | 	int ret = pthread_create(&t->impl.pthread, &attr, &ThreadProc, (void *)start_index); | ||
|  | 	assert(ret == 0); | ||
|  | 	pthread_attr_destroy(&attr); | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_thread_wait_and_destroy(kinc_thread_t *thread) { | ||
|  | 	int ret; | ||
|  | 	do { | ||
|  | 		ret = pthread_join(thread->impl.pthread, NULL); | ||
|  | 	} while (ret != 0); | ||
|  | } | ||
|  | 
 | ||
|  | bool kinc_thread_try_to_destroy(kinc_thread_t *thread) { | ||
|  | 	return pthread_join(thread->impl.pthread, NULL) == 0; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_threads_init() {} | ||
|  | 
 | ||
|  | void kinc_threads_quit() {} | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if !defined(KINC_IOS) && !defined(KINC_MACOS)
 | ||
|  | // Alternatively _GNU_SOURCE can be defined to make
 | ||
|  | // the headers declare it but let's not make it too
 | ||
|  | // easy to write Linux-specific POSIX-code
 | ||
|  | int pthread_setname_np(pthread_t thread, const char *name); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | void kinc_thread_set_name(const char *name) { | ||
|  | #if !defined(KINC_IOS) && !defined(KINC_MACOS)
 | ||
|  | 	pthread_setname_np(pthread_self(), name); | ||
|  | #else
 | ||
|  | 	pthread_setname_np(name); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_thread_sleep(int milliseconds) { | ||
|  | 	usleep(1000 * (useconds_t)milliseconds); | ||
|  | } |