use std::cell::Cell;
const REFRESH_EVERY: u32 = 64;
thread_local! {
static CACHED: Cell<(usize, u32)> = const { Cell::new((0, REFRESH_EVERY)) };
}
#[inline]
pub(crate) fn current_cpu() -> usize {
CACHED.with(|c| {
let (cpu, age) = c.get();
if age >= REFRESH_EVERY {
let fresh = query_cpu();
c.set((fresh, 0));
fresh
} else {
c.set((cpu, age + 1));
cpu
}
})
}
#[cfg(target_os = "linux")]
#[inline]
fn query_cpu() -> usize {
let cpu = unsafe { libc::sched_getcpu() };
if cpu < 0 {
0
} else {
cpu as usize
}
}
#[cfg(target_os = "windows")]
#[inline]
fn query_cpu() -> usize {
use winapi::um::processthreadsapi::GetCurrentProcessorNumber;
unsafe { GetCurrentProcessorNumber() as usize }
}
#[cfg(not(any(target_os = "linux", target_os = "windows")))]
#[inline]
fn query_cpu() -> usize {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut h = DefaultHasher::new();
std::thread::current().id().hash(&mut h);
h.finish() as usize
}