mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-01 03:38:55 +00:00
Get/Set Thread names
This commit is contained in:
@@ -5,7 +5,7 @@ import "core:c"
|
||||
|
||||
when ODIN_OS == .Darwin {
|
||||
foreign import lib "system:System.framework"
|
||||
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Linux {
|
||||
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Linux || ODIN_OS == .OpenBSD {
|
||||
foreign import lib "system:pthread"
|
||||
} else {
|
||||
foreign import lib "system:c"
|
||||
|
||||
@@ -155,6 +155,28 @@ yield :: proc() {
|
||||
_yield()
|
||||
}
|
||||
|
||||
/*
|
||||
Get thread's name/description.
|
||||
|
||||
If thread is nil the procedure will get the name of the calling thread.
|
||||
|
||||
allocates memory for the returned string using provided allocator.
|
||||
*/
|
||||
get_name :: proc(thread: ^Thread, allocator := context.allocator, loc := #caller_location) -> (string, runtime.Allocator_Error) #optional_allocator_error {
|
||||
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.
|
||||
|
||||
MacOS: only support 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.
|
||||
|
||||
|
||||
13
core/thread/thread_name_darwin.odin
Normal file
13
core/thread/thread_name_darwin.odin
Normal file
@@ -0,0 +1,13 @@
|
||||
#+build darwin
|
||||
#+private
|
||||
package thread
|
||||
|
||||
import "core:sys/posix"
|
||||
import "core:c"
|
||||
|
||||
foreign import pthread "system:System.framework"
|
||||
|
||||
foreign pthread {
|
||||
pthread_getname_np :: proc(thread: posix.pthread_t, name: [^]u8, len: c.size_t) -> posix.Errno ---
|
||||
pthread_setname_np :: proc(name: [^]u8) -> posix.Errno ---
|
||||
}
|
||||
13
core/thread/thread_name_freebsd.odin
Normal file
13
core/thread/thread_name_freebsd.odin
Normal file
@@ -0,0 +1,13 @@
|
||||
#+build freebsd
|
||||
#+private
|
||||
package thread
|
||||
|
||||
import "core:sys/posix"
|
||||
import "core:c"
|
||||
|
||||
foreign import pthread "system:pthread"
|
||||
|
||||
foreign pthread {
|
||||
pthread_getname_np :: proc(thread: posix.pthread_t, name: [^]u8, len: c.size_t) -> posix.Errno ---
|
||||
pthread_setname_np :: proc(thread: posix.pthread_t, name: [^]u8) -> posix.Errno ---
|
||||
}
|
||||
13
core/thread/thread_name_linux.odin
Normal file
13
core/thread/thread_name_linux.odin
Normal file
@@ -0,0 +1,13 @@
|
||||
#+build linux
|
||||
#+private
|
||||
package thread
|
||||
|
||||
import "core:sys/posix"
|
||||
import "core:c"
|
||||
|
||||
foreign import pthread "system:pthread"
|
||||
|
||||
foreign pthread {
|
||||
pthread_getname_np :: proc(thread: posix.pthread_t, name: [^]u8, len: c.size_t) -> posix.Errno ---
|
||||
pthread_setname_np :: proc(thread: posix.pthread_t, name: [^]u8) -> posix.Errno ---
|
||||
}
|
||||
13
core/thread/thread_name_netbsd.odin
Normal file
13
core/thread/thread_name_netbsd.odin
Normal file
@@ -0,0 +1,13 @@
|
||||
#+build netbsd
|
||||
#+private
|
||||
package thread
|
||||
|
||||
import "core:sys/posix"
|
||||
import "core:c"
|
||||
|
||||
foreign import pthread "system:pthread"
|
||||
|
||||
foreign pthread {
|
||||
pthread_getname_np :: proc(thread: posix.pthread_t, name: [^]u8, len: c.size_t) -> posix.Errno ---
|
||||
pthread_setname_np :: proc(thread: posix.pthread_t, name: [^]u8, arg: rawptr) -> posix.Errno ---
|
||||
}
|
||||
13
core/thread/thread_name_openbsd.odin
Normal file
13
core/thread/thread_name_openbsd.odin
Normal file
@@ -0,0 +1,13 @@
|
||||
#+build openbsd
|
||||
#+private
|
||||
package thread
|
||||
|
||||
import "core:sys/posix"
|
||||
import "core:c"
|
||||
|
||||
foreign import pthread "system:pthread"
|
||||
|
||||
foreign pthread {
|
||||
pthread_get_name_np :: proc(thread: posix.pthread_t, name: [^]u8, len: c.size_t) ---
|
||||
pthread_set_name_np :: proc(thread: posix.pthread_t, name: [^]u8) ---
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
package thread
|
||||
|
||||
import "base:intrinsics"
|
||||
import "base:runtime"
|
||||
|
||||
_IS_SUPPORTED :: false
|
||||
|
||||
@@ -45,3 +46,7 @@ _yield :: proc() {
|
||||
unimplemented("core:thread procedure not supported on target")
|
||||
}
|
||||
|
||||
_get_name :: proc(thread: Thread, allocator : runtime.Allocator, loc : runtime.Source_Code_Location) -> (string, runtime.Allocator_Error) {
|
||||
unimplemented("core:thread procedure not supported on target")
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import "core:sync"
|
||||
import "core:sys/posix"
|
||||
|
||||
_IS_SUPPORTED :: true
|
||||
|
||||
_MAX_PTHREAD_NAME_LENGTH :: 16
|
||||
// NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t.
|
||||
// Also see core/sys/darwin/mach_darwin.odin/semaphore_t.
|
||||
Thread_Os_Specific :: struct #align(16) {
|
||||
@@ -182,3 +182,57 @@ _terminate :: proc(t: ^Thread, exit_code: int) {
|
||||
_yield :: proc() {
|
||||
posix.sched_yield()
|
||||
}
|
||||
|
||||
_get_name :: proc(thread: ^Thread, allocator: runtime.Allocator, loc: runtime.Source_Code_Location) -> (name:string, err:runtime.Allocator_Error) {
|
||||
// Haiku doesn't have pthread_getname yet
|
||||
when ODIN_OS == .Haiku {
|
||||
unimplemented("core:thread get_name for haiku is not yet supported")
|
||||
}
|
||||
|
||||
tid : posix.pthread_t
|
||||
if thread == nil do tid = transmute(posix.pthread_t)sync.current_thread_id()
|
||||
else do tid = thread.unix_thread
|
||||
|
||||
buf := make([]u8, _MAX_PTHREAD_NAME_LENGTH, allocator, loc) or_return
|
||||
|
||||
when ODIN_OS == .Darwin || ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
|
||||
pthread_getname_np(tid, raw_data(buf), len(buf))
|
||||
} else when ODIN_OS == .OpenBSD {
|
||||
pthread_get_name_np(tid, raw_data(buf), len(buf))
|
||||
}
|
||||
|
||||
name = transmute(string)buf
|
||||
|
||||
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 do return
|
||||
} else {
|
||||
tid: posix.pthread_t
|
||||
if thread == nil do tid = transmute(posix.pthread_t)sync.current_thread_id
|
||||
else do tid = t.unix_thread
|
||||
}
|
||||
|
||||
buf : [_MAX_PTHREAD_NAME_LENGTH]u8
|
||||
copy_from_string(buf[:], name)
|
||||
|
||||
// _MAX_PTHREAD_NAME_LENGTH includes terminating null
|
||||
buf[len(buf) - 1] = 0
|
||||
|
||||
when ODIN_OS == .Darwin {
|
||||
pthread_setname_np(raw_data(buf[:]))
|
||||
} else when ODIN_OS == .OpenBSD {
|
||||
pthread_set_name_np(tid, raw_data(buf[:]))
|
||||
} else when ODIN_OS == .NetBSD {
|
||||
format := []u8{'%','s', 0}
|
||||
pthread_setname_np(tid, raw_data(format), raw_data(buf[:]))
|
||||
} else {
|
||||
pthread_setname_np(tid, raw_data(buf[:]))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,8 +6,11 @@ import "base:intrinsics"
|
||||
import "base:runtime"
|
||||
import "core:sync"
|
||||
import win32 "core:sys/windows"
|
||||
import "core:unicode/utf16"
|
||||
|
||||
_IS_SUPPORTED :: true
|
||||
//NOTE(peperronii): not sure about the exact length but there must be a limit
|
||||
_THREAD_DESCRIPTION_LENGTH :: 64
|
||||
|
||||
Thread_Os_Specific :: struct {
|
||||
win32_thread: win32.HANDLE,
|
||||
@@ -152,3 +155,33 @@ _yield :: proc() {
|
||||
win32.SwitchToThread()
|
||||
}
|
||||
|
||||
_get_name :: proc(thread: ^Thread, allocator: runtime.Allocator, loc : runtime.Source_Code_Location) -> (name:string, err:runtime.Allocator_Error) {
|
||||
t_handle : win32.HANDLE
|
||||
if thread == nil do t_handle = win32.GetCurrentThread()
|
||||
else do t_handle = t.win32_thread
|
||||
|
||||
buf_8 : [_THREAD_DESCRIPTION_LENGTH * 2]u8
|
||||
buf_16 : [_THREAD_DESCRIPTION_LENGTH]u16
|
||||
win32.GetThreadDescription(t_handle, raw_data(buf_16[:]))
|
||||
n := utf16.decode_to_utf(buf_8[:], buf_16[:])
|
||||
buf := make([]u8, n, allocator, loc)
|
||||
|
||||
copy(buf, buf_8[:])
|
||||
|
||||
name = transmute(string)buf
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
_set_name :: proc(thread: ^Thread, name: string) {
|
||||
t_handle : win32.HANDLE
|
||||
if thread == nil do t_handle = win32.GetCurrentThread()
|
||||
else do t_handle = t.win32_thread
|
||||
|
||||
buf : [_THREAD_DESCRIPTION_LENGTH]u16
|
||||
utf16.encode_string(buf_16[:], name)
|
||||
// _THREAD_DESCRIPTION_LENGTH includes terminating null
|
||||
buf[len(buf) - 1] = 0
|
||||
win32.SetThreadDescription(t_handle, raw_data(buf[:]))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user