37 lines
1.1 KiB
Rust
37 lines
1.1 KiB
Rust
extern crate libc;
|
|
|
|
use std::num::NonZeroUsize;
|
|
use std::{mem, ptr};
|
|
|
|
pub(crate) fn num_threads() -> Option<NonZeroUsize> {
|
|
// Safety: `sysctl` and `getpid` are both thread-safe.
|
|
// `kip` is only accessed if sysctl() succeeds and agrees with the expected size,
|
|
// and the data only trusted if both its embedded size and pid match expectations
|
|
unsafe {
|
|
let pid = libc::getpid();
|
|
let mib: [libc::c_int; 4] = [libc::CTL_KERN, libc::KERN_PROC, libc::KERN_PROC_PID, pid];
|
|
let mut kip: libc::kinfo_proc = mem::zeroed();
|
|
let expected_kip_len = mem::size_of_val(&kip);
|
|
let mut kip_len = expected_kip_len;
|
|
|
|
let ret = libc::sysctl(
|
|
mib.as_ptr(),
|
|
mib.len() as u32,
|
|
&mut kip as *mut _ as *mut libc::c_void,
|
|
&mut kip_len,
|
|
ptr::null(),
|
|
0,
|
|
);
|
|
|
|
if ret == 0
|
|
&& kip_len == expected_kip_len
|
|
&& kip.ki_structsize == expected_kip_len as i32
|
|
&& kip.ki_pid == pid
|
|
{
|
|
NonZeroUsize::new(kip.ki_numthreads as usize)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|