1use std::io;
2
3use super::{Config, Driver};
4
5pub trait DriverExt: Sized {
6 fn new(cfg: Config) -> io::Result<Self>;
7 fn init_thread(cpu_id: u16) -> io::Result<()>;
8 fn allowed_cpus() -> io::Result<Vec<u16>>;
9}
10
11cfg_select! {
12 target_os = "linux" => {
13 use std::io::{Error, ErrorKind};
14 use std::mem;
15
16 use crate::backend::uring::driver::Uring;
17
18 impl DriverExt for Driver {
19 fn new(cfg: Config) -> io::Result<Self> {
20 cfg.validate()?;
21 let (state, slots) = Uring::new(&cfg)?;
22 Driver::from_state(
23 state,
24 slots,
25 cfg.ready_slots,
26 cfg.provided.entries as usize,
27 )
28 }
29
30 fn init_thread(cpu_id: u16) -> io::Result<()> {
31 if cpu_id >= libc::CPU_SETSIZE as u16 {
32 return Err(Error::new(
33 ErrorKind::InvalidInput,
34 "dope: cpu index exceeds CPU_SETSIZE",
35 ));
36 }
37 let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
38 unsafe {
39 libc::CPU_ZERO(&mut set);
40 libc::CPU_SET(cpu_id as usize, &mut set);
41 }
42 let rc = unsafe { libc::sched_setaffinity(0, size_of::<libc::cpu_set_t>(), &set) };
43 if rc != 0 {
44 Err(Error::last_os_error())
45 } else {
46 Ok(())
47 }
48 }
49
50 fn allowed_cpus() -> io::Result<Vec<u16>> {
51 let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
52 let rc = unsafe { libc::sched_getaffinity(0, size_of::<libc::cpu_set_t>(), &mut set) };
53 if rc != 0 {
54 return Err(Error::last_os_error());
55 }
56 let mut cpus = Vec::new();
57 for cpu in 0..libc::CPU_SETSIZE as usize {
58 if unsafe { libc::CPU_ISSET(cpu, &set) } {
59 cpus.push(cpu as u16);
60 }
61 }
62 Ok(cpus)
63 }
64 }
65 }
66 _ => {
67 use std::io::{Error, ErrorKind};
68
69 use crate::backend::kqueue::driver::Kqueue;
70
71 impl DriverExt for Driver {
72 fn new(cfg: Config) -> io::Result<Self> {
73 cfg.validate()?;
74 let (state, slots) = Kqueue::new(&cfg)?;
75 Driver::from_state(
76 state,
77 slots,
78 cfg.ready_slots,
79 cfg.provided.entries as usize,
80 )
81 }
82
83 fn init_thread(cpu_id: u16) -> io::Result<()> {
84 let _ = cpu_id;
85 Err(Error::new(
86 ErrorKind::Unsupported,
87 "dope: hard CPU affinity is unavailable on this target",
88 ))
89 }
90
91 fn allowed_cpus() -> io::Result<Vec<u16>> {
92 Err(Error::new(
93 ErrorKind::Unsupported,
94 "dope: CPU affinity discovery is unavailable on this target",
95 ))
96 }
97 }
98 }
99}