diff options
Diffstat (limited to 'std/thread.zc')
| -rw-r--r-- | std/thread.zc | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/std/thread.zc b/std/thread.zc new file mode 100644 index 0000000..f1aae69 --- /dev/null +++ b/std/thread.zc @@ -0,0 +1,130 @@ + +include <pthread.h>; +include <time.h>; +include <unistd.h>; + +import "./core.zc" +import "./result.zc" + +raw { + typedef void (*ZenThreadFunc)(void*); + + struct ZenThreadCtx { + void *func_ptr; + void *ctx; + }; + + static void* _z_thread_trampoline(void *arg) { + struct ZenThreadCtx *c = (struct ZenThreadCtx*)arg; + z_closure_T *closure = (z_closure_T*)c; + void (*f)(void*) = (void(*)(void*))closure->func; + f(closure->ctx); + free(c); + return NULL; + } + + static int _z_thread_spawn(void *ctx_copy, size_t *out_handle) { + pthread_t pt; + int ret = pthread_create(&pt, NULL, _z_thread_trampoline, ctx_copy); + if (ret == 0) { + *out_handle = (size_t)pt; + } + return ret; + } + + static int _z_thread_join(void *handle) { + return pthread_join((pthread_t)handle, NULL); + } + + static void _z_mutex_init(void *ptr) { + pthread_mutex_init((pthread_mutex_t*)ptr, NULL); + } + + static void _z_mutex_lock(void *ptr) { + pthread_mutex_lock((pthread_mutex_t*)ptr); + } + + static void _z_mutex_unlock(void *ptr) { + pthread_mutex_unlock((pthread_mutex_t*)ptr); + } + + static void _z_mutex_destroy(void *ptr) { + pthread_mutex_destroy((pthread_mutex_t*)ptr); + } + + static void _z_usleep(int micros) { + usleep(micros); + } +} + +extern fn _z_thread_spawn(ctx: void*, out: usize*) -> int; +extern fn _z_thread_join(handle: void*) -> int; +extern fn _z_mutex_init(ptr: void*); +extern fn _z_mutex_lock(ptr: void*); +extern fn _z_mutex_unlock(ptr: void*); +extern fn _z_mutex_destroy(ptr: void*); +extern fn _z_usleep(micros: int); + + + +struct Thread { + handle: void*; +} + +impl Thread { + fn spawn(func: fn()) -> Result<Thread> { + var t: usize = 0; + + var ctx_copy = malloc(16); // z_closure_T is 16 bytes + if (ctx_copy == NULL) return Result<Thread>::Err("OOM"); + + memcpy(ctx_copy, &func, 16); + + var ret = _z_thread_spawn(ctx_copy, &t); + + if (ret != 0) { + free(ctx_copy); + return Result<Thread>::Err("Failed to create thread"); + } + + return Result<Thread>::Ok(Thread { handle: (void*)t }); + } + + fn join(self) -> Result<bool> { + var ret = _z_thread_join(self.handle); + if (ret != 0) return Result<bool>::Err("Join failed"); + return Result<bool>::Ok(true); + } +} + +struct Mutex { + handle: void*; +} + +impl Mutex { + fn new() -> Mutex { + var ptr = malloc(64); + _z_mutex_init(ptr); + return Mutex { handle: ptr }; + } + + fn lock(self) { + _z_mutex_lock(self.handle); + } + + fn unlock(self) { + _z_mutex_unlock(self.handle); + } + + fn free(self) { + if (self.handle) { + _z_mutex_destroy(self.handle); + free(self.handle); + } + } +} + +fn sleep_ms(ms: int) { + _z_usleep(ms * 1000); +} + |
