Skip to main content

spawned_rt/tasks/
affinity.rs

1//! Fallible Linux CPU placement. No affinity is applied to the calling thread
2//! during validation; runtime owners pin themselves before admitting work.
3use std::io;
4#[cfg(target_os = "linux")]
5pub fn available_cpus() -> io::Result<Vec<usize>> {
6    let set =
7        nix::sched::sched_getaffinity(nix::unistd::Pid::from_raw(0)).map_err(io::Error::from)?;
8    (0..nix::libc::CPU_SETSIZE as usize)
9        .filter_map(|cpu| match set.is_set(cpu) {
10            Ok(true) => Some(Ok(cpu)),
11            Ok(false) => None,
12            Err(error) => Some(Err(io::Error::from(error))),
13        })
14        .collect()
15}
16#[cfg(target_os = "linux")]
17pub fn pin_current(cpu: usize) -> io::Result<()> {
18    let mut set = nix::sched::CpuSet::new();
19    set.set(cpu).map_err(io::Error::from)?;
20    nix::sched::sched_setaffinity(nix::unistd::Pid::from_raw(0), &set).map_err(io::Error::from)
21}
22#[cfg(target_os = "linux")]
23pub fn current_cpu() -> io::Result<usize> {
24    nix::sched::sched_getcpu().map_err(io::Error::from)
25}
26#[cfg(not(target_os = "linux"))]
27pub fn available_cpus() -> io::Result<Vec<usize>> {
28    Err(io::Error::new(
29        io::ErrorKind::Unsupported,
30        "hard CPU affinity requires Linux",
31    ))
32}
33#[cfg(not(target_os = "linux"))]
34pub fn pin_current(_: usize) -> io::Result<()> {
35    Err(io::Error::new(
36        io::ErrorKind::Unsupported,
37        "hard CPU affinity requires Linux",
38    ))
39}
40#[cfg(not(target_os = "linux"))]
41pub fn current_cpu() -> io::Result<usize> {
42    Err(io::Error::new(
43        io::ErrorKind::Unsupported,
44        "CPU audit requires Linux",
45    ))
46}