From 1318e71efd0001c486f9e5b315dc3b0e080f2415 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 11 Jun 2016 11:27:48 -0700 Subject: [PATCH] Figured out why future crashed, added in simple threading library. Future isn't fixed yet, but could be with a similar approach --- stdlib/thread.krak | 51 ++++++++++++++++++++++++++++++ tests/test_thread.expected_results | 5 +++ tests/test_thread.krak | 20 ++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 stdlib/thread.krak create mode 100644 tests/test_thread.expected_results create mode 100644 tests/test_thread.krak diff --git a/stdlib/thread.krak b/stdlib/thread.krak new file mode 100644 index 0000000..3d8f1cd --- /dev/null +++ b/stdlib/thread.krak @@ -0,0 +1,51 @@ +import io:* +import os:* +import mem:* +import util:* + +#link(pthread) +ext fun pthread_attr_init(attr_ptr: *void): int +ext fun pthread_create(thread: *ulong, attr_ptr: *void, func: *void, param: *void): int +ext fun pthread_attr_destroy(attr_ptr: *void): int +ext fun pthread_join(thread: ulong, ret: **void): int + +obj dual_ptrs { var data: *void; var func: *void; } +fun extract_func_ptr(func: T): *void { + return (&func) cast *dual_ptrs -> func +} +fun run(func :fun(T): void, data: T) : *ulong { + var thread = new() + var data_copy = new() + // TODO: figure out why the func type structs aren't the same + // to avoid extra copy etc + var func_copy = new() + var func_and_data = new>()->construct() + *data_copy = data + memmove((func_copy) cast *void, (&func) cast *void, #sizeof) + *func_and_data = make_pair((func_copy) cast *void, data_copy) + var wrapper = fun(func_and_data: *void): *void { + var fnd_pair = (func_and_data) cast *pair<*fun(T):void, *T> + (*fnd_pair->first)(*fnd_pair->second) + delete(fnd_pair->first) + delete(fnd_pair->second) + delete(fnd_pair) + return null() + } + // I counted 18 or so word-sized or smaller members (recursively) in the attr struct + var attr = malloc(20*#sizeof<*void>) + pthread_attr_init(attr) + // joinable is default + var ret = pthread_create(thread, attr, extract_func_ptr(wrapper), (func_and_data) cast *void) + // error check ret? + pthread_attr_destroy(attr) + free(attr) + return thread +} + +fun join(thrd : *ulong) : void { + // yep **void null + pthread_join(*thrd, null<*void>()) + // error check join + delete(thrd) +} + diff --git a/tests/test_thread.expected_results b/tests/test_thread.expected_results new file mode 100644 index 0000000..d9e0874 --- /dev/null +++ b/tests/test_thread.expected_results @@ -0,0 +1,5 @@ +hello from main first +hello from thread first 1347 +hello from main middle +hello from thread second 1347 +hello from main after join diff --git a/tests/test_thread.krak b/tests/test_thread.krak new file mode 100644 index 0000000..2165ddd --- /dev/null +++ b/tests/test_thread.krak @@ -0,0 +1,20 @@ +import io:* +import os:* +import thread:* + +fun main(): int { + var a = 1337 + println("hello from main first"); + var t = run(fun(l: int) { + print("hello from thread first ") + println(a+l) + system("sleep 2") + print("hello from thread second ") + println(a+l) + }, 10) + system("sleep 1") + println("hello from main middle"); + join(t) + println("hello from main after join"); + return 0 +}