aboutsummaryrefslogtreecommitdiff
path: root/core/thread.odin
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-07-20 23:57:56 +0100
committerGinger Bill <bill@gingerbill.org>2017-07-20 23:57:56 +0100
commitdbddec33c8247beb5984d0c3fbcdf86a94054248 (patch)
tree6f711915422e3a2b76013d4bf6d488ce1221d84e /core/thread.odin
parent401a5955a4ed1746e96f29db8e521cb4831a863d (diff)
Internal changes; thread.odin for windows only
Diffstat (limited to 'core/thread.odin')
-rw-r--r--core/thread.odin76
1 files changed, 76 insertions, 0 deletions
diff --git a/core/thread.odin b/core/thread.odin
new file mode 100644
index 000000000..b6a39cd89
--- /dev/null
+++ b/core/thread.odin
@@ -0,0 +1,76 @@
+_ :: compile_assert(ODIN_OS == "windows");
+
+import win32 "sys/windows.odin";
+
+Thread :: struct {
+ using specific: OsSpecific;
+ procedure: Proc;
+ data: rawptr;
+ user_index: int;
+
+ init_context: Context;
+ use_init_context: bool;
+
+ Proc :: #type proc(^Thread) -> int;
+ OsSpecific :: struct {
+ win32_thread: win32.Handle;
+ win32_thread_id: u32;
+ }
+}
+
+
+create :: proc(procedure: Thread.Proc) -> ^Thread {
+ win32_thread_id: u32;
+
+ __windows_thread_entry_proc :: proc(data: rawptr) -> i32 #cc_c {
+ if data == nil do return 0;
+
+ t := cast(^Thread)data;
+
+ c := context;
+ if t.use_init_context {
+ c = t.init_context;
+ }
+
+ exit := 0;
+ push_context c {
+ exit = t.procedure(t);
+ }
+
+ return cast(i32)exit;
+ }
+
+
+ win32_thread_proc := cast(rawptr)__windows_thread_entry_proc;
+ thread := new(Thread);
+
+ win32_thread := win32.create_thread(nil, 0, win32_thread_proc, thread, win32.CREATE_SUSPENDED, &win32_thread_id);
+ if win32_thread == nil {
+ free(thread);
+ return nil;
+ }
+ thread.procedure = procedure;
+ thread.win32_thread = win32_thread;
+ thread.win32_thread_id = win32_thread_id;
+
+ return thread;
+}
+
+start :: proc(using thread: ^Thread) {
+ win32.resume_thread(win32_thread);
+}
+
+is_done :: proc(using thread: ^Thread) -> bool {
+ res := win32.wait_for_single_object(win32_thread, 0);
+ return res != win32.WAIT_TIMEOUT;
+}
+
+join :: proc(using thread: ^Thread) {
+ win32.wait_for_single_object(win32_thread, win32.INFINITE);
+ win32.close_handle(win32_thread);
+ win32_thread = win32.INVALID_HANDLE;
+}
+destroy :: proc(thread: ^Thread) {
+ join(thread);
+ free(thread);
+}