diff --git a/run_tree/osx/arm64/debug/convert_csv b/run_tree/osx/arm64/debug/convert_csv index fd55d14..313a0ad 100755 Binary files a/run_tree/osx/arm64/debug/convert_csv and b/run_tree/osx/arm64/debug/convert_csv differ diff --git a/run_tree/osx/arm64/debug/lumenarium b/run_tree/osx/arm64/debug/lumenarium index bdac2b5..b01321e 100755 Binary files a/run_tree/osx/arm64/debug/lumenarium and b/run_tree/osx/arm64/debug/lumenarium differ diff --git a/src_v2/platform/linux/lumenarium_linux_thread.h b/src_v2/platform/linux/lumenarium_linux_thread.h index 5528426..76693da 100644 --- a/src_v2/platform/linux/lumenarium_linux_thread.h +++ b/src_v2/platform/linux/lumenarium_linux_thread.h @@ -1,17 +1,101 @@ #ifndef LUMENARIUM_RASPI_THREADS_H #define LUMENARIUM_RASPI_THREADS_H 1 +typedef struct Os_Linux_Thread Os_Linux_Thread; +struct Os_Linux_Thread +{ + pthread_t thread; + Thread_Proc* proc; + u8* user_data; + Thread_Result result; +}; + +#define LINUX_THREAD_CAP 8 +global Os_Linux_Thread linux_threads_[LINUX_THREAD_CAP]; +global u32 linux_threads_len_; + Thread_Handle os_thread_begin(Thread_Proc* proc, u8* user_data) { - invalid_code_path; - return Thread_Handle{0}; + // Call the actual thread function + // This is essentially a blocking call for the rest of this function + Os_Linux_Thread* thread_data = (Os_Linux_Thread*)arg; + thread_data->result = thread_data->proc(thread_data->user_data); + + // Clean up this threads thread slot so other threads + // can use it + thread_data->proc = 0; + thread_data->user_data = 0; + + pthread_exit(&thread_data->result); } void os_thread_end(Thread_Handle thread_handle) { - invalid_code_path; + // Find an unused thread slot + Thread_Handle result = { .value = 0 }; + if (linux_threads_len_ < OSX_THREAD_CAP) + { + result = (Thread_Handle){ .value = linux_threads_len_++ }; + } + else + { + bool found = false; + for (u32 i = 0; i < OSX_THREAD_CAP; i++) + { + if (linux_threads_[i].proc == 0) + { + result.value = i; + found = true; + } + } + + if (!found) { + printf("ERROR: Unable to create thread.\n"); + invalid_code_path; + } + } + + // Initialize Thread Slot + Os_Linux_Thread* t = linux_threads_ + result.value; + *t = (Os_Linux_Thread){ + .proc = proc, + .user_data = user_data + }; + + // Create PThread + s32 create_error = pthread_create(&t->thread, + NULL, // use default attrs + (void * _Nullable (* _Nonnull)(void * _Nullable))proc, + user_data + ); + + if (create_error) + { + switch (create_error) { + case EAGAIN: { + } break; + + case EINVAL: { + } break; + + // case ELEMULTITHREADFORK: { + // } break; + + case ENOMEM: { + } break; + } + } + + return result; +} + +void +os_thread_end(Thread_Handle thread_handle) +{ + Os_Linux_Thread* t = linux_threads_ + thread_handle.value; + pthread_kill(t->thread, 0); } u32