forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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);
							 | 
						||
| 
								 | 
							
								}
							 |