compio_driver/
driver_type.rs1use std::sync::atomic::{AtomicU8, Ordering};
2
3const UNINIT: u8 = u8::MAX;
4const IO_URING: u8 = 0;
5const POLLING: u8 = 1;
6const IOCP: u8 = 2;
7
8static DRIVER_TYPE: AtomicU8 = AtomicU8::new(UNINIT);
9
10#[repr(u8)]
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum DriverType {
14 Poll = POLLING,
16
17 IoUring = IO_URING,
19
20 IOCP = IOCP,
22}
23
24impl DriverType {
25 fn from_num(n: u8) -> Self {
26 match n {
27 IO_URING => Self::IoUring,
28 POLLING => Self::Poll,
29 IOCP => Self::IOCP,
30 _ => unreachable!("invalid driver type"),
31 }
32 }
33
34 fn get() -> DriverType {
36 cfg_if::cfg_if! {
37 if #[cfg(windows)] {
38 DriverType::IOCP
39 } else if #[cfg(fusion)] {
40 use io_uring::opcode::*;
41
42 const USED_OP: &[u8] = &[
44 Read::CODE,
45 Readv::CODE,
46 Write::CODE,
47 Writev::CODE,
48 Fsync::CODE,
49 Accept::CODE,
50 Connect::CODE,
51 RecvMsg::CODE,
52 SendMsg::CODE,
53 AsyncCancel::CODE,
54 OpenAt::CODE,
55 Close::CODE,
56 Shutdown::CODE,
57 Socket::CODE,
58 ];
59
60 (|| {
61 let uring = io_uring::IoUring::new(2)?;
62 let mut probe = io_uring::Probe::new();
63 uring.submitter().register_probe(&mut probe)?;
64 if USED_OP.iter().all(|op| probe.is_supported(*op)) {
65 std::io::Result::Ok(DriverType::IoUring)
66 } else {
67 Ok(DriverType::Poll)
68 }
69 })()
70 .unwrap_or(DriverType::Poll) } else if #[cfg(io_uring)] {
72 DriverType::IoUring
73 } else if #[cfg(unix)] {
74 DriverType::Poll
75 } else {
76 compile_error!("unsupported platform");
77 }
78 }
79 }
80
81 pub fn current() -> DriverType {
84 match DRIVER_TYPE.load(Ordering::Acquire) {
85 UNINIT => {}
86 x => return DriverType::from_num(x),
87 }
88 let dev_ty = Self::get();
89
90 DRIVER_TYPE.store(dev_ty as u8, Ordering::Release);
91
92 dev_ty
93 }
94
95 pub fn is_polling() -> bool {
97 Self::current() == DriverType::Poll
98 }
99
100 pub fn is_iouring() -> bool {
102 Self::current() == DriverType::IoUring
103 }
104
105 pub fn is_iocp() -> bool {
107 Self::current() == DriverType::IOCP
108 }
109}