os_id/thread/
unix.rs

1use crate::ThreadName;
2
3#[cfg(all(unix, not(target_os = "linux"), not(target_os = "android"), not(target_os = "macos"), not(target_os = "ios"), not(target_os = "netbsd"), not(target_os = "freebsd")))]
4///Raw thread id type, which is opaque type, platform dependent
5pub type RawId = libc::pthread_t;
6
7#[cfg(any(target_os = "linux", target_os = "android"))]
8///Raw thread id as `pid_t` which is signed integer
9///
10///Can be accessed via `gettid` on Linux and Android
11pub type RawId = libc::pid_t;
12
13#[cfg(target_os = "freebsd")]
14///Raw thread id signed integer
15///
16///Can be accessed via `pthread_threadid_np` on freebsd
17pub type RawId = libc::c_int;
18
19#[cfg(target_os = "netbsd")]
20///Raw thread id unsigned integer
21///
22///Can be accessed via `_lwp_self` on netbsd
23pub type RawId = libc::c_uint;
24
25#[cfg(any(target_os = "macos", target_os = "ios"))]
26///Raw thread id as unsigned 64 bit integer.
27///
28///Can be accessed via `pthread_threadid_np` on mac
29pub type RawId = u64;
30
31#[cfg(target_os = "freebsd")]
32#[inline]
33///Accesses id using `pthread_threadid_np`
34pub fn get_raw_id() -> RawId {
35    #[link(name = "pthread")]
36    extern "C" {
37        fn pthread_getthreadid_np() -> libc::c_int;
38    }
39
40    //According to documentation it cannot fail
41    unsafe { pthread_getthreadid_np() }
42}
43
44#[cfg(target_os = "netbsd")]
45#[inline]
46///Accesses id using `_lwp_self`
47pub fn get_raw_id() -> RawId {
48    extern "C" {
49        fn _lwp_self() -> libc::c_uint;
50    }
51
52    //According to documentation it cannot fail
53    unsafe { _lwp_self() }
54}
55
56#[cfg(any(target_os = "macos", target_os = "ios"))]
57#[inline]
58///Accesses id using `pthread_threadid_np`
59pub fn get_raw_id() -> RawId {
60    #[link(name = "pthread")]
61    extern "C" {
62        fn pthread_threadid_np(thread: libc::pthread_t, thread_id: *mut u64) -> libc::c_int;
63    }
64    let mut tid: u64 = 0;
65    let err = unsafe { pthread_threadid_np(0, &mut tid) };
66    assert_eq!(err, 0);
67    tid
68}
69
70#[cfg(any(target_os = "android", target_os = "linux"))]
71#[inline]
72///Accesses id using `gettid`
73pub fn get_raw_id() -> RawId {
74    unsafe { libc::syscall(libc::SYS_gettid) as libc::pid_t }
75}
76
77#[cfg(all(unix, not(target_os = "linux"), not(target_os = "android"), not(target_os = "macos"), not(target_os = "ios"), not(target_os = "netbsd"), not(target_os = "freebsd")))]
78#[inline]
79///Access id using `pthread_self`
80pub fn get_raw_id() -> RawId {
81    unsafe {
82        libc::pthread_self()
83    }
84}
85
86#[inline(always)]
87///Thread equality function.
88///
89///Guarantees to compare regardless of raw type.
90pub fn raw_thread_eq(left: RawId, right: RawId) -> bool {
91    #[cfg(any(target_os = "linux", target_os = "android", target_os = "macos", target_os = "ios", target_os = "netbsd", target_os = "freebsd"))]
92    {
93        left == right
94    }
95
96    #[cfg(all(not(target_os = "linux"), not(target_os = "android"), not(target_os = "macos"), not(target_os = "ios"), not(target_os = "netbsd"), not(target_os = "freebsd")))]
97    {
98        #[link(name = "pthread")]
99        extern "C" {
100            pub fn pthread_equal(left: RawId, right: RawId) -> libc::c_int;
101        }
102
103        unsafe {
104            pthread_equal(left, right) != 0
105        }
106    }
107}
108
109///Accesses current thread name using `pthread_getname_np`.
110pub fn get_current_thread_name() -> ThreadName {
111     #[link(name = "pthread")]
112    extern "C" {
113        pub fn pthread_getname_np(thread: libc::pthread_t, name: *mut i8, len: libc::size_t) -> libc::c_int;
114    }
115
116    let mut storage = [0u8; 16];
117
118    let result = unsafe {
119        pthread_getname_np(libc::pthread_self(), storage.as_mut_ptr() as _, storage.len() as _)
120    };
121
122    if result == 0 {
123        ThreadName::name(storage)
124    } else {
125        ThreadName::new()
126    }
127}