diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-07-20 23:57:56 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-07-20 23:57:56 +0100 |
| commit | dbddec33c8247beb5984d0c3fbcdf86a94054248 (patch) | |
| tree | 6f711915422e3a2b76013d4bf6d488ce1221d84e /core/thread.odin | |
| parent | 401a5955a4ed1746e96f29db8e521cb4831a863d (diff) | |
Internal changes; thread.odin for windows only
Diffstat (limited to 'core/thread.odin')
| -rw-r--r-- | core/thread.odin | 76 |
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); +} |