diff --git a/backend/cmd/threads/main.ha b/backend/cmd/threads/main.ha index 9c259c4..e73b8aa 100644 --- a/backend/cmd/threads/main.ha +++ b/backend/cmd/threads/main.ha @@ -1,45 +1,16 @@ use types::c; use fmt; +use thread; -export type pthread_t = u64; -export type pthread_attr_t = opaque; -export type pthread_fn = fn(nullable *opaque) nullable *opaque; - -export @symbol("pthread_create") fn pthread_create(thread: nullable *pthread_t, attr: nullable *pthread_attr_t, start_routine: *pthread_fn, arg: nullable *opaque) int; -export @symbol("pthread_join") fn pthread_join(thread: pthread_t, nullable *nullable *opaque) int; - -fn thread_start(arg: nullable *opaque) nullable *opaque = { +fn thread_start() void = { fmt::println("hello from another thread")!; - return null; }; export fn main() void = { fmt::println("starting a thread")!; - let tid: pthread_t = 0; - let ret = pthread_create(&tid, null, &thread_start, null); - fmt::printfln("ret: {}", ret)!; + let tid = thread::spawn(&thread_start)!; fmt::println("joining")!; - ret = pthread_join(tid, null); - fmt::printfln("ret: {}", ret)!; -}; - - -// spawn a thread -// -// returns a handle or an error -fn spawn(f: *pthread_fn) (join_handle | error) = { - void; -}; - -// join a thread -// -// no return value or an error on join -fn join(handle: join_handle) (void | error) = { - void; -}; - -// detach a thread. -fn detach(join_handle) (void | error) = { - void; + thread::join(tid)!; + fmt::println("joined. good bye.")!; }; diff --git a/backend/vendor/hare-thread/thread/thread.ha b/backend/vendor/hare-thread/thread/thread.ha new file mode 100644 index 0000000..b0b51ad --- /dev/null +++ b/backend/vendor/hare-thread/thread/thread.ha @@ -0,0 +1,56 @@ +use types::c; + +export type pthread_t = [8]u8; +type pthread_attr_t = opaque; +type pthread_fn = fn(nullable *opaque) nullable *opaque; +export type thread_fn = fn() void; + +@symbol("pthread_create") fn pthread_create(thread: nullable *pthread_t, attr: nullable *pthread_attr_t, start_routine: *pthread_fn, arg: nullable *opaque) int; +@symbol("pthread_join") fn pthread_join(thread: pthread_t, nullable *nullable *opaque) int; +@symbol("pthread_detach") fn pthread_detach(thread: pthread_t) int; + +fn thread_spawn_wrapper(data: nullable *opaque) nullable *opaque = { + let f = data: *thread_fn; + f(); + return null; +}; + +export type error = !void; +export type join_handle = struct { + thread: pthread_t, +}; + +// spawn a thread +// +// returns a handle or an error +export fn spawn(f: *thread_fn) (join_handle | error) = { + let data = f: *opaque; + + let tid: pthread_t = [0...]; + let ret = pthread_create(&tid, null, &thread_spawn_wrapper, f); + if (ret != 0) { + return error; + }; + + return join_handle { + thread = tid + }; +}; + +// join a thread +// +// no return value or an error on join +export fn join(handle: join_handle) (void | error) = { + let ret = pthread_join(handle.thread, null); + if (ret != 0) { + return error; + }; +}; + +// detach a thread. +export fn detach(handle: join_handle) (void | error) = { + let ret = pthread_detach(handle.thread); + if (ret != 0) { + return error; + }; +};