mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-01 03:38:55 +00:00
thread.create et al with name parameter
This commit is contained in:
@@ -48,6 +48,9 @@ Thread :: struct {
|
||||
// started. Should be set after the thread has been created, but before
|
||||
// it is started.
|
||||
data: rawptr,
|
||||
// Thread's Name/Description that will get set during thread creation
|
||||
// for thread's creation only : do not refer to it, use thread.get_name instead
|
||||
name: Maybe(string),
|
||||
// User-supplied integer, that will be available to the thread once it is
|
||||
// started. Should be set after the thread has been created, but before
|
||||
// it is started.
|
||||
@@ -102,8 +105,8 @@ thread will be in a suspended state, until `start()` procedure is called.
|
||||
To start the thread, call `start()`. Also the `create_and_start()`
|
||||
procedure can be called to create and start the thread immediately.
|
||||
*/
|
||||
create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread {
|
||||
return _create(procedure, priority)
|
||||
create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal, name: Maybe(string) = nil) -> ^Thread {
|
||||
return _create(procedure, priority, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,20 +169,6 @@ get_name :: proc(thread: ^Thread, allocator := context.temp_allocator, loc := #c
|
||||
return _get_name(thread, allocator, loc)
|
||||
}
|
||||
|
||||
/*
|
||||
Set thread's name/description.
|
||||
|
||||
If thread is nil the procedure will set the name of the calling thread.
|
||||
|
||||
the provided string must be available until this procedure ends
|
||||
and will be truncated to fit their platform's limit.
|
||||
|
||||
MacOS: only supports changing the name of the calling thread.
|
||||
if thread is not nil the procedure will do nothing.
|
||||
*/
|
||||
set_name :: proc(thread: ^Thread, name: string) {
|
||||
_set_name(thread, name)
|
||||
}
|
||||
/*
|
||||
Run a procedure on a different thread.
|
||||
|
||||
@@ -191,8 +180,8 @@ to execute. The thread will have priority specified by the `priority` parameter.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
run :: proc(fn: proc(), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal) {
|
||||
create_and_start(fn, init_context, priority, true)
|
||||
run :: proc(fn: proc(), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, name: Maybe(string) = nil) {
|
||||
create_and_start(fn, init_context, priority, true, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -206,8 +195,8 @@ to execute. The thread will have priority specified by the `priority` parameter.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
run_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal) {
|
||||
create_and_start_with_data(data, fn, init_context, priority, true)
|
||||
run_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, name: Maybe(string) = nil) {
|
||||
create_and_start_with_data(data, fn, init_context, priority, true, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -221,9 +210,9 @@ to execute. The thread will have priority specified by the `priority` parameter.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
run_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
run_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, name: Maybe(string) = nil)
|
||||
where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data(data, fn, init_context, priority, true)
|
||||
create_and_start_with_poly_data(data, fn, init_context, priority, true, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -237,9 +226,9 @@ to execute. The thread will have priority specified by the `priority` parameter.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
run_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
run_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, name: Maybe(string) = nil)
|
||||
where size_of(T1) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data2(arg1, arg2, fn, init_context, priority, true)
|
||||
create_and_start_with_poly_data2(arg1, arg2, fn, init_context, priority, true, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -253,9 +242,9 @@ to execute. The thread will have priority specified by the `priority` parameter.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
run_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
run_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, name: Maybe(string) = nil)
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data3(arg1, arg2, arg3, fn, init_context, priority, true)
|
||||
create_and_start_with_poly_data3(arg1, arg2, arg3, fn, init_context, priority, true, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -269,9 +258,9 @@ to execute. The thread will have priority specified by the `priority` parameter.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
run_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal)
|
||||
run_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, name: Maybe(string) = nil)
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) + size_of(T4) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
create_and_start_with_poly_data4(arg1, arg2, arg3, arg4, fn, init_context, priority, true)
|
||||
create_and_start_with_poly_data4(arg1, arg2, arg3, arg4, fn, init_context, priority, true, name)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -292,12 +281,12 @@ That includes calling `join`, which needs to dereference ^Thread`.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
create_and_start :: proc(fn: proc(), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> (t: ^Thread) {
|
||||
create_and_start :: proc(fn: proc(), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false, name: Maybe(string) = nil) -> (t: ^Thread) {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc())t.data
|
||||
fn()
|
||||
}
|
||||
if t = create(thread_proc, priority); t == nil {
|
||||
if t = create(thread_proc, priority, name); t == nil {
|
||||
return
|
||||
}
|
||||
t.data = rawptr(fn)
|
||||
@@ -327,14 +316,14 @@ That includes calling `join`, which needs to dereference ^Thread`.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
create_and_start_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> (t: ^Thread) {
|
||||
create_and_start_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false, name: Maybe(string) = nil) -> (t: ^Thread) {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(rawptr))t.data
|
||||
assert(t.user_index >= 1)
|
||||
data := t.user_args[0]
|
||||
fn(data)
|
||||
}
|
||||
if t = create(thread_proc, priority); t == nil {
|
||||
if t = create(thread_proc, priority, name); t == nil {
|
||||
return
|
||||
}
|
||||
t.data = rawptr(fn)
|
||||
@@ -366,7 +355,7 @@ That includes calling `join`, which needs to dereference ^Thread`.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> (t: ^Thread)
|
||||
create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false, name: Maybe(string) = nil) -> (t: ^Thread)
|
||||
where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T))t.data
|
||||
@@ -374,7 +363,7 @@ create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: T), init_contex
|
||||
data := (^T)(&t.user_args[0])^
|
||||
fn(data)
|
||||
}
|
||||
if t = create(thread_proc, priority); t == nil {
|
||||
if t = create(thread_proc, priority, name); t == nil {
|
||||
return
|
||||
}
|
||||
t.data = rawptr(fn)
|
||||
@@ -411,7 +400,7 @@ That includes calling `join`, which needs to dereference ^Thread`.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
create_and_start_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> (t: ^Thread)
|
||||
create_and_start_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false, name: Maybe(string) = nil) -> (t: ^Thread)
|
||||
where size_of(T1) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T1, T2))t.data
|
||||
@@ -423,7 +412,7 @@ create_and_start_with_poly_data2 :: proc(arg1: $T1, arg2: $T2, fn: proc(T1, T2),
|
||||
|
||||
fn(arg1, arg2)
|
||||
}
|
||||
if t = create(thread_proc, priority); t == nil {
|
||||
if t = create(thread_proc, priority, name); t == nil {
|
||||
return
|
||||
}
|
||||
t.data = rawptr(fn)
|
||||
@@ -462,7 +451,7 @@ That includes calling `join`, which needs to dereference ^Thread`.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
create_and_start_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> (t: ^Thread)
|
||||
create_and_start_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: proc(arg1: T1, arg2: T2, arg3: T3), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false, name: Maybe(string) = nil) -> (t: ^Thread)
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T1, T2, T3))t.data
|
||||
@@ -475,7 +464,7 @@ create_and_start_with_poly_data3 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, fn: pr
|
||||
|
||||
fn(arg1, arg2, arg3)
|
||||
}
|
||||
if t = create(thread_proc, priority); t == nil {
|
||||
if t = create(thread_proc, priority, name); t == nil {
|
||||
return
|
||||
}
|
||||
t.data = rawptr(fn)
|
||||
@@ -515,7 +504,7 @@ That includes calling `join`, which needs to dereference ^Thread`.
|
||||
is used, the thread procedure needs to call `runtime.default_temp_allocator_destroy()`
|
||||
in order to free the resources associated with the temporary allocations.
|
||||
*/
|
||||
create_and_start_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false) -> (t: ^Thread)
|
||||
create_and_start_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4, fn: proc(arg1: T1, arg2: T2, arg3: T3, arg4: T4), init_context: Maybe(runtime.Context) = nil, priority := Thread_Priority.Normal, self_cleanup := false, name: Maybe(string) = nil) -> (t: ^Thread)
|
||||
where size_of(T1) + size_of(T2) + size_of(T3) + size_of(T4) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
|
||||
thread_proc :: proc(t: ^Thread) {
|
||||
fn := cast(proc(T1, T2, T3, T4))t.data
|
||||
@@ -529,7 +518,7 @@ create_and_start_with_poly_data4 :: proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4:
|
||||
|
||||
fn(arg1, arg2, arg3, arg4)
|
||||
}
|
||||
if t = create(thread_proc, priority); t == nil {
|
||||
if t = create(thread_proc, priority, name); t == nil {
|
||||
return
|
||||
}
|
||||
t.data = rawptr(fn)
|
||||
|
||||
@@ -14,7 +14,7 @@ _thread_priority_map := [Thread_Priority]i32{
|
||||
.High = +2,
|
||||
}
|
||||
|
||||
_create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread {
|
||||
_create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal, name: Maybe(string) = nil) -> ^Thread {
|
||||
unimplemented("core:thread procedure not supported on target")
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Thread_Os_Specific :: struct #align(16) {
|
||||
// Creates a thread which will run the given procedure.
|
||||
// It then waits for `start` to be called.
|
||||
//
|
||||
_create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
_create :: proc(procedure: Thread_Proc, priority: Thread_Priority, name: Maybe(string)) -> ^Thread {
|
||||
__unix_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr {
|
||||
t := (^Thread)(t)
|
||||
|
||||
@@ -58,6 +58,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
runtime.run_thread_local_cleaners()
|
||||
}
|
||||
|
||||
_set_name(t)
|
||||
|
||||
t.procedure(t)
|
||||
}
|
||||
|
||||
@@ -211,23 +213,18 @@ _get_name :: proc(thread: ^Thread, allocator: runtime.Allocator, loc: runtime.So
|
||||
return
|
||||
}
|
||||
|
||||
_set_name :: proc(thread: ^Thread, name: string) {
|
||||
// Haiku doesn't have pthread_getname yet
|
||||
when ODIN_OS == .Haiku {
|
||||
unimplemented("core:thread set_name for haiku is not yet supported")
|
||||
} else when ODIN_OS == .Darwin {
|
||||
if thread != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
tid: posix.pthread_t
|
||||
if thread == nil {
|
||||
tid = posix.pthread_self()
|
||||
} else {
|
||||
tid = thread.unix_thread
|
||||
}
|
||||
_set_name :: proc(thread: ^Thread) {
|
||||
if ODIN_OS == .Haiku {
|
||||
return
|
||||
}
|
||||
|
||||
name, ok := thread.name.?
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
tid := thread.unix_thread
|
||||
|
||||
buf: [_MAX_PTHREAD_NAME_LENGTH]u8
|
||||
copy(buf[:], name)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ _thread_priority_map := [Thread_Priority]i32{
|
||||
.High = +2,
|
||||
}
|
||||
|
||||
_create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
_create :: proc(procedure: Thread_Proc, priority: Thread_Priority, name: Maybe(string)) -> ^Thread {
|
||||
win32_thread_id: win32.DWORD
|
||||
|
||||
__windows_thread_entry_proc :: proc "system" (t_: rawptr) -> win32.DWORD {
|
||||
@@ -47,6 +47,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
runtime.run_thread_local_cleaners()
|
||||
}
|
||||
|
||||
_set_name(t)
|
||||
|
||||
t.procedure(t)
|
||||
}
|
||||
|
||||
@@ -79,6 +81,7 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
||||
thread.win32_thread = win32_thread
|
||||
thread.win32_thread_id = win32_thread_id
|
||||
thread.id = int(win32_thread_id)
|
||||
thread.name = name
|
||||
|
||||
ok := win32.SetThreadPriority(win32_thread, _thread_priority_map[priority])
|
||||
assert(ok == true)
|
||||
@@ -170,14 +173,14 @@ _get_name :: proc(thread: ^Thread, allocator: runtime.Allocator, loc: runtime.So
|
||||
return
|
||||
}
|
||||
|
||||
_set_name :: proc(thread: ^Thread, name: string) {
|
||||
t_handle: win32.HANDLE
|
||||
if thread == nil {
|
||||
t_handle = win32.GetCurrentThread()
|
||||
} else {
|
||||
t_handle = thread.win32_thread
|
||||
_set_name :: proc(thread: ^Thread) {
|
||||
name, ok := thread.name.?
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
t_handle = thread.win32_thread
|
||||
|
||||
buf: [_THREAD_DESCRIPTION_LENGTH]u16
|
||||
// _THREAD_DESCRIPTION_LENGTH includes terminating null
|
||||
utf16.encode_string(buf[:len(buf) - 1], name)
|
||||
|
||||
Reference in New Issue
Block a user