From b3c51a8b4488a34996fbad50228380fd1bd51f2f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 22 Jun 2020 13:28:37 +0100 Subject: [PATCH] Add `thread.run*` shorthand procedures; `Thread.init_context` use new `Maybe` concept --- core/thread/thread.odin | 42 +++++++++++++++++++++++++++++++-- core/thread/thread_unix.odin | 6 ++--- core/thread/thread_windows.odin | 33 +++++++++++++------------- examples/demo/demo.odin | 1 - 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/core/thread/thread.odin b/core/thread/thread.odin index 00ee2f4b3..988e804d2 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -1,6 +1,8 @@ package thread import "core:runtime" +import "core:os" +import "core:sync" Thread_Proc :: #type proc(^Thread); @@ -10,6 +12,42 @@ Thread :: struct { data: rawptr, user_index: int, - init_context: runtime.Context, - use_init_context: bool, + init_context: Maybe(runtime.Context), +} + +#assert(size_of(Thread{}.user_index) == size_of(uintptr)); + + +run :: proc(fn: proc(), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal) { + thread_proc :: proc(t: ^Thread) { + fn := cast(proc())t.data; + fn(); + destroy(t); + } + t := create(thread_proc, priority); + t.data = rawptr(fn); + t.init_context = init_context; + start(t); +} + + +run_with_data :: proc(fn: proc(data: rawptr), data: rawptr, init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal) { + thread_proc :: proc(t: ^Thread) { + fn := cast(proc(rawptr))t.data; + data := rawptr(uintptr(t.user_index)); + fn(data); + destroy(t); + } + t := create(thread_proc, priority); + t.data = rawptr(fn); + t.user_index = int(uintptr(data)); + t.init_context = init_context; + start(t); +} + + +run_with_thread_proc :: proc(fn: Thread_Proc, init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal) { + t := create(fn, priority); + t.init_context = init_context; + start(t); } diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index ffb3fe5b2..42e372956 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -51,14 +51,14 @@ create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^T t.start_gate = {}; c := context; - if t.use_init_context { - c = t.init_context; + if ic, ok := t.init_context.?; ok { + c = ic; } context = c; t.procedure(t); - if !t.use_init_context { + if t.init_context == nil { if context.temp_allocator.data == &runtime.global_default_temp_allocator_data { runtime.default_temp_allocator_destroy(auto_cast context.temp_allocator.data); } diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index 430997441..3f4973307 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -10,33 +10,33 @@ Thread_Os_Specific :: struct { done: bool, // see note in `is_done` } -THREAD_PRIORITY_IDLE :: -15; -THREAD_PRIORITY_LOWEST :: -2; -THREAD_PRIORITY_BELOW_NORMAL :: -1; -THREAD_PRIORITY_NORMAL :: 0; -THREAD_PRIORITY_ABOVE_NORMAL :: 1; -THREAD_PRIORITY_HIGHEST :: 2; -THREAD_PRIORITY_TIME_CRITICAL :: 15; -Thread_Priority :: enum i32 { - Normal = THREAD_PRIORITY_NORMAL, - Low = THREAD_PRIORITY_LOWEST, - High = THREAD_PRIORITY_HIGHEST, +Thread_Priority :: enum { + Normal, + Low, + High, } +_thread_priority_map := map[Thread_Priority]i32{ + .Normal = 0, + .Low = -2, + .High = +2, +}; + create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread { win32_thread_id: u32; __windows_thread_entry_proc :: proc "c" (t: ^Thread) -> i32 { - c := runtime.default_context(); - if t.use_init_context { - c = t.init_context; + context = runtime.default_context(); + c := context; + if ic, ok := t.init_context.?; ok { + c = ic; } context = c; t.procedure(t); - if !t.use_init_context { + if t.init_context == nil { if context.temp_allocator.data == &runtime.global_default_temp_allocator_data { runtime.default_temp_allocator_destroy(auto_cast context.temp_allocator.data); } @@ -58,8 +58,9 @@ create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^T thread.procedure = procedure; thread.win32_thread = win32_thread; thread.win32_thread_id = win32_thread_id; + thread.init_context = context; - ok := win32.set_thread_priority(win32_thread, i32(priority)); + ok := win32.set_thread_priority(win32_thread, _thread_priority_map[priority]); assert(ok == true); return thread; diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 2485ca6f9..fd94f1391 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1120,7 +1120,6 @@ threading_example :: proc() { for in prefix_table { if t := thread.create(worker_proc); t != nil { t.init_context = context; - t.use_init_context = true; t.user_index = len(threads); append(&threads, t); thread.start(t);