dope-core 0.9.1

The manifold runtime
Documentation
use std::io;

use crate::backend::Backend;
use crate::driver::Config;

pub(crate) trait ExtBackend {
    fn create(cfg: &Config) -> io::Result<(Backend, usize)>;
    fn init_thread(cpu_id: u16) -> io::Result<()>;
    fn allowed_cpus() -> io::Result<Vec<u16>>;
}

#[cfg(target_os = "linux")]
mod linux {
    use std::io::{self, Error, ErrorKind};
    use std::mem;

    use super::{Backend, Config, ExtBackend};

    impl ExtBackend for Backend {
        fn create(cfg: &Config) -> io::Result<(Backend, usize)> {
            Backend::new(cfg)
        }

        fn init_thread(cpu_id: u16) -> io::Result<()> {
            if cpu_id >= libc::CPU_SETSIZE as u16 {
                return Err(Error::new(
                    ErrorKind::InvalidInput,
                    "dope: cpu index exceeds CPU_SETSIZE",
                ));
            }
            let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
            unsafe {
                libc::CPU_ZERO(&mut set);
                libc::CPU_SET(cpu_id as usize, &mut set);
            }
            let rc = unsafe { libc::sched_setaffinity(0, size_of::<libc::cpu_set_t>(), &set) };
            if rc == 0 {
                Ok(())
            } else {
                Err(Error::last_os_error())
            }
        }

        fn allowed_cpus() -> io::Result<Vec<u16>> {
            let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
            let rc = unsafe { libc::sched_getaffinity(0, size_of::<libc::cpu_set_t>(), &mut set) };
            if rc != 0 {
                return Err(Error::last_os_error());
            }
            let mut cpus = Vec::new();
            for cpu in 0..libc::CPU_SETSIZE as usize {
                if unsafe { libc::CPU_ISSET(cpu, &set) } {
                    cpus.push(cpu as u16);
                }
            }
            Ok(cpus)
        }
    }
}

#[cfg(not(target_os = "linux"))]
mod kqueue {
    use std::io::{self, Error, ErrorKind};

    use super::{Backend, Config, ExtBackend};

    impl ExtBackend for Backend {
        fn create(cfg: &Config) -> io::Result<(Backend, usize)> {
            Backend::new(cfg)
        }

        fn init_thread(cpu_id: u16) -> io::Result<()> {
            let _ = cpu_id;
            Err(Error::new(
                ErrorKind::Unsupported,
                "dope: hard CPU affinity is unavailable on this target",
            ))
        }

        fn allowed_cpus() -> io::Result<Vec<u16>> {
            Err(Error::new(
                ErrorKind::Unsupported,
                "dope: CPU affinity discovery is unavailable on this target",
            ))
        }
    }
}