Add get_current_thread_id to base

This commit is contained in:
Feoramund
2025-01-20 15:00:12 -05:00
parent 4a4294c2af
commit 13dca77d3d
8 changed files with 119 additions and 0 deletions

View File

@@ -5,6 +5,20 @@ Thread_Local_Cleaner :: #type proc "odin" ()
@(private="file")
thread_local_cleaners: [8]Thread_Local_Cleaner
// The thread ID is cached here to save time from making syscalls with every
// call.
@(thread_local) local_thread_id: int
// Return the current thread ID.
@(require_results)
get_current_thread_id :: proc "contextless" () -> int {
if local_thread_id == 0 {
local_thread_id = _get_current_thread_id()
assert_contextless(local_thread_id != 0, "_get_current_thread_id returned 0.")
}
return local_thread_id
}
// Add a procedure that will be run at the end of a thread for the purpose of
// deallocating state marked as `thread_local`.
//

View File

@@ -0,0 +1,17 @@
#+private
package runtime
foreign import lib "system:System.framework"
foreign lib {
pthread_threadid_np :: proc "c" (rawptr, ^u64) -> i32 ---
}
_get_current_thread_id :: proc "contextless" () -> int {
tid: u64
result := pthread_threadid_np(nil, &tid)
if result != 0 {
panic_contextless("Failed to get current thread ID.")
}
return int(tid)
}

View File

@@ -0,0 +1,19 @@
#+private
package runtime
import "base:intrinsics"
SYS_thr_self :: uintptr(432)
_get_current_thread_id :: proc "contextless" () -> int {
when size_of(rawptr) == 4 {
id: i32
} else {
id: i64
}
_, ok := intrinsics.syscall_bsd(SYS_thr_self, uintptr(&id))
if !ok {
panic_contextless("Failed to get current thread ID.")
}
return int(id)
}

View File

@@ -0,0 +1,22 @@
#+private
package runtime
import "base:intrinsics"
when ODIN_ARCH == .amd64 {
SYS_gettid :: uintptr(186)
} else when ODIN_ARCH == .arm32 {
SYS_gettid :: uintptr(224)
} else when ODIN_ARCH == .arm64 {
SYS_gettid :: uintptr(178)
} else when ODIN_ARCH == .i386 {
SYS_gettid :: uintptr(224)
} else when ODIN_ARCH == .riscv64 {
SYS_gettid :: uintptr(178)
} else {
#panic("Syscall numbers related to threading are missing for this Linux architecture.")
}
_get_current_thread_id :: proc "contextless" () -> int {
return int(intrinsics.syscall(SYS_gettid))
}

View File

@@ -0,0 +1,11 @@
#+private
package runtime
import "base:intrinsics"
SYS__lwp_self :: uintptr(311)
_get_current_thread_id :: proc "contextless" () -> int {
result, _ := intrinsics.syscall_bsd(SYS__lwp_self)
return int(result)
}

View File

@@ -0,0 +1,11 @@
#+private
package runtime
import "base:intrinsics"
SYS_getthrid :: uintptr(299)
_get_current_thread_id :: proc "contextless" () -> int {
result, _ := intrinsics.syscall_bsd(SYS_getthrid)
return int(result)
}

View File

@@ -0,0 +1,12 @@
#+private
#+build !darwin
#+build !freebsd
#+build !linux
#+build !netbsd
#+build !openbsd
#+build !windows
package runtime
_get_current_thread_id :: proc "contextless" () -> int {
unimplemented_contextless("This platform does not support multithreading.")
}

View File

@@ -0,0 +1,13 @@
#+private
package runtime
foreign import Kernel32 "system:Kernel32.lib"
@(default_calling_convention="system")
foreign Kernel32 {
GetCurrentThreadId :: proc() -> u32 ---
}
_get_current_thread_id :: proc "contextless" () -> int {
return int(GetCurrentThreadId())
}