use std::io;
use super::{Config, Driver, system};
#[derive(Clone, Copy, Debug, Default)]
pub struct Backend;
impl crate::backend::Backend for Backend {
type Driver = Driver;
type Config = Config;
fn new_driver(cfg: Self::Config) -> std::io::Result<Self::Driver> {
Driver::new(cfg)
}
fn init_process(cfg: &Config) -> io::Result<()> {
unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN) };
unsafe { libc::mlockall(libc::MCL_CURRENT | libc::MCL_FUTURE) };
system::Snapshot::raise_nofile()?;
let snap = system::Snapshot::detect()?;
snap.check(cfg).map_err(io::Error::from)
}
fn init_thread(cpu_id: u16) -> io::Result<()> {
if cpu_id >= libc::CPU_SETSIZE as u16 {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"dope: cpu index exceeds CPU_SETSIZE",
));
}
let mut set: libc::cpu_set_t = unsafe { std::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 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
fn allowed_cpus() -> Vec<u16> {
let mut set: libc::cpu_set_t = unsafe { std::mem::zeroed() };
let rc = unsafe { libc::sched_getaffinity(0, size_of::<libc::cpu_set_t>(), &mut set) };
if rc != 0 {
let n = std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1);
return (0..n as u16).collect();
}
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);
}
}
cpus
}
}