Skip to main content

hiver_runtime/driver/
config.rs

1//! Driver configuration and factory
2//! Driver配置和工厂
3//!
4//! This module provides configuration types and factory methods for creating
5//! different driver implementations.
6//!
7//! 本模块提供配置类型和用于创建不同driver实现的工厂方法。
8
9use std::sync::Arc;
10
11use crate::driver::Driver;
12
13/// Driver type selector using strategy pattern
14/// 使用策略模式的Driver类型选择器
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum DriverType {
17    /// Use epoll driver (Linux) / 使用epoll driver (Linux)
18    Epoll,
19    /// Use io-uring driver (Linux 5.1+) / 使用io-uring driver (Linux 5.1+)
20    IOUring,
21    /// Use kqueue driver (macOS/BSD) / 使用kqueue driver (macOS/BSD)
22    Kqueue,
23    /// Automatically detect and use the best available driver
24    /// 自动检测并使用最佳可用driver
25    Auto,
26}
27
28/// Driver configuration using builder pattern
29/// 使用Builder模式的Driver配置
30#[derive(Debug, Clone, Copy)]
31pub struct DriverConfig {
32    /// Queue depth (must be power of 2 for ring buffer efficiency)
33    /// 队列深度(必须是2的幂以优化环形缓冲区效率)
34    pub entries: u32,
35    /// Wait for completion on submit (blocking mode)
36    /// 提交时等待完成(阻塞模式)
37    pub submit_wait: bool,
38    /// CPU core affinity (None = no affinity)
39    /// CPU核心亲和性(None = 无亲和性)
40    pub cpu_affinity: Option<usize>,
41    /// Enable deferred task wake-up
42    /// 启用延迟任务唤醒
43    pub defer_wakeup: bool,
44    /// Maximum number of concurrent operations per FD
45    /// 每个文件描述符的最大并发操作数
46    pub max_ops_per_fd: u32,
47}
48
49impl Default for DriverConfig {
50    fn default() -> Self {
51        Self {
52            entries: 256,
53            submit_wait: false,
54            cpu_affinity: None,
55            defer_wakeup: true,
56            max_ops_per_fd: 32,
57        }
58    }
59}
60
61/// Driver configuration builder
62/// Driver配置构建器
63///
64/// Provides a fluent API for constructing driver configurations.
65/// 提供用于构建driver配置的流畅API。
66#[derive(Debug, Clone)]
67pub struct DriverConfigBuilder {
68    config: DriverConfig,
69}
70
71impl DriverConfigBuilder {
72    /// Create a new builder with default configuration
73    /// 创建具有默认配置的新构建器
74    #[must_use]
75    pub fn new() -> Self {
76        Self {
77            config: DriverConfig::default(),
78        }
79    }
80
81    /// Set the queue depth (will be rounded up to next power of 2)
82    /// 设置队列深度(将向上舍入到下一个2的幂)
83    #[must_use]
84    pub fn entries(mut self, entries: u32) -> Self {
85        self.config.entries = entries.next_power_of_two();
86        self
87    }
88
89    /// Enable or disable submit-wait mode
90    /// 启用或禁用提交等待模式
91    #[must_use]
92    pub const fn submit_wait(mut self, wait: bool) -> Self {
93        self.config.submit_wait = wait;
94        self
95    }
96
97    /// Set CPU affinity for the driver thread
98    /// 为driver线程设置CPU亲和性
99    #[must_use]
100    pub const fn cpu_affinity(mut self, core: usize) -> Self {
101        self.config.cpu_affinity = Some(core);
102        self
103    }
104
105    /// Clear CPU affinity (no affinity)
106    /// 清除CPU亲和性(无亲和性)
107    #[must_use]
108    pub const fn no_affinity(mut self) -> Self {
109        self.config.cpu_affinity = None;
110        self
111    }
112
113    /// Enable or disable deferred task wake-up
114    /// 启用或禁用延迟任务唤醒
115    #[must_use]
116    pub const fn defer_wakeup(mut self, defer: bool) -> Self {
117        self.config.defer_wakeup = defer;
118        self
119    }
120
121    /// Set maximum operations per file descriptor
122    /// 设置每个文件描述符的最大操作数
123    #[must_use]
124    pub const fn max_ops_per_fd(mut self, max: u32) -> Self {
125        self.config.max_ops_per_fd = max;
126        self
127    }
128
129    /// Build the configuration
130    /// 构建配置
131    #[must_use]
132    pub const fn build(self) -> DriverConfig {
133        self.config
134    }
135}
136
137impl Default for DriverConfigBuilder {
138    fn default() -> Self {
139        Self::new()
140    }
141}
142
143/// Driver factory using factory pattern
144/// 使用工厂模式的Driver工厂
145///
146/// Provides a unified interface for creating different driver implementations.
147/// 提供用于创建不同driver实现的统一接口。
148pub struct DriverFactory;
149
150impl DriverFactory {
151    /// Create a driver with the specified type and default configuration
152    /// 使用指定类型和默认配置创建driver
153    ///
154    /// # Errors / 错误
155    ///
156    /// Returns an error if:
157    /// 返回错误如果:
158    /// - The specified driver type is not available on this platform
159    /// - 指定的driver类型在此平台上不可用
160    /// - Driver initialization fails
161    /// - Driver初始化失败
162    ///
163    /// # Examples / 示例
164    ///
165    /// ```rust,no_run,ignore
166    /// use hiver_runtime::driver::{DriverFactory, DriverType};
167    ///
168    /// let driver = DriverFactory::create(DriverType::Auto).unwrap();
169    /// ```
170    pub fn create(driver_type: DriverType) -> std::io::Result<Arc<dyn Driver>> {
171        Self::create_with_config(driver_type, DriverConfig::default())
172    }
173
174    /// Create a driver with the specified type and configuration
175    /// 使用指定类型和配置创建driver
176    ///
177    /// # Errors / 错误
178    ///
179    /// Returns an error if driver initialization fails.
180    /// 如果driver初始化失败则返回错误。
181    pub fn create_with_config(
182        driver_type: DriverType,
183        config: DriverConfig,
184    ) -> std::io::Result<Arc<dyn Driver>> {
185        let ty = if matches!(driver_type, DriverType::Auto) {
186            Self::detect_best_driver()?
187        } else {
188            driver_type
189        };
190
191        match ty {
192            #[cfg(target_os = "linux")]
193            DriverType::Epoll => {
194                Ok(Arc::new(crate::driver::epoll::EpollDriver::with_config(config)?))
195            },
196            #[cfg(target_os = "linux")]
197            DriverType::IOUring => {
198                Ok(Arc::new(crate::driver::iouring::IoUringDriver::with_config(config)?))
199            },
200            #[cfg(any(
201                target_os = "macos",
202                target_os = "freebsd",
203                target_os = "netbsd",
204                target_os = "openbsd",
205                target_os = "dragonfly"
206            ))]
207            DriverType::Kqueue => {
208                Ok(Arc::new(crate::driver::kqueue::KqueueDriver::with_config(config)?))
209            },
210            #[cfg(not(target_os = "linux"))]
211            DriverType::Epoll => Err(std::io::Error::new(
212                std::io::ErrorKind::Unsupported,
213                "epoll driver is only available on Linux",
214            )),
215            #[cfg(not(target_os = "linux"))]
216            DriverType::IOUring => Err(std::io::Error::new(
217                std::io::ErrorKind::Unsupported,
218                "io-uring driver is only available on Linux",
219            )),
220            #[cfg(not(any(
221                target_os = "macos",
222                target_os = "freebsd",
223                target_os = "netbsd",
224                target_os = "openbsd",
225                target_os = "dragonfly"
226            )))]
227            DriverType::Kqueue => Err(std::io::Error::new(
228                std::io::ErrorKind::Unsupported,
229                "kqueue driver is only available on macOS/BSD",
230            )),
231            DriverType::Auto => {
232                // Auto should have been resolved by detect_best_driver() above.
233                // If we reach here, detection failed — return a clear error.
234                // Auto 应该已被上面的 detect_best_driver() 解析。
235                // 如果到达这里,说明检测失败 — 返回明确的错误。
236                Err(std::io::Error::new(
237                    std::io::ErrorKind::Unsupported,
238                    "Failed to detect a suitable driver for this platform",
239                ))
240            },
241        }
242    }
243
244    /// Detect the best available driver for the current platform
245    /// 检测当前平台的最佳可用driver
246    fn detect_best_driver() -> std::io::Result<DriverType> {
247        #[cfg(target_os = "linux")]
248        {
249            // Check kernel version for io-uring support
250            // 检查内核版本以支持io-uring
251            if Self::has_io_uring_support() {
252                Ok(DriverType::IOUring)
253            } else {
254                Ok(DriverType::Epoll)
255            }
256        }
257
258        #[cfg(any(
259            target_os = "macos",
260            target_os = "freebsd",
261            target_os = "netbsd",
262            target_os = "openbsd",
263            target_os = "dragonfly"
264        ))]
265        {
266            Ok(DriverType::Kqueue)
267        }
268
269        #[cfg(not(any(
270            target_os = "linux",
271            target_os = "macos",
272            target_os = "freebsd",
273            target_os = "netbsd",
274            target_os = "openbsd",
275            target_os = "dragonfly"
276        )))]
277        {
278            Err(std::io::Error::new(
279                std::io::ErrorKind::Unsupported,
280                "No suitable driver found for this platform",
281            ))
282        }
283    }
284
285    /// Check if the system supports io-uring (Linux only)
286    /// 检查系统是否支持io-uring(仅Linux)
287    #[cfg(target_os = "linux")]
288    fn has_io_uring_support() -> bool {
289        // Check for io_uring_setup system call availability
290        // 检查io_uring_setup系统调用的可用性
291        // io-uring requires Linux 5.1+
292        // io-uring需要Linux 5.1+
293        let mut uname = libc::utsname {
294            sysname: [0; 65],
295            nodename: [0; 65],
296            release: [0; 65],
297            version: [0; 65],
298            machine: [0; 65],
299            domainname: [0; 65],
300        };
301
302        unsafe {
303            if libc::uname(&mut uname) != 0 {
304                return false;
305            }
306
307            // Parse kernel version
308            // 解析内核版本
309            let release = std::ffi::CStr::from_ptr(uname.release.as_ptr()).to_string_lossy();
310
311            if let Some((major, rest)) = release.split_once('.') {
312                if let Some((minor, _)) = rest.split_once('.') {
313                    if let (Ok(maj), Ok(min)) = (major.parse::<u32>(), minor.parse::<u32>()) {
314                        return maj > 5 || (maj == 5 && min >= 1);
315                    }
316                }
317            }
318        }
319
320        false
321    }
322}
323
324#[cfg(test)]
325mod tests {
326    use super::*;
327
328    #[test]
329    fn test_config_builder() {
330        let config = DriverConfigBuilder::new()
331            .entries(512)
332            .submit_wait(true)
333            .cpu_affinity(0)
334            .defer_wakeup(false)
335            .build();
336
337        // Should be rounded up to next power of 2
338        // 应向上舍入到下一个2的幂
339        assert_eq!(config.entries, 512);
340        assert!(config.submit_wait);
341        assert_eq!(config.cpu_affinity, Some(0));
342        assert!(!config.defer_wakeup);
343    }
344
345    #[test]
346    fn test_config_rounding() {
347        let config = DriverConfigBuilder::new().entries(100).build();
348
349        // 100 rounds up to 128 (next power of 2)
350        // 100向上舍入到128(下一个2的幂)
351        assert_eq!(config.entries, 128);
352    }
353
354    #[test]
355    fn test_config_default() {
356        let config = DriverConfig::default();
357        assert_eq!(config.entries, 256);
358        assert!(!config.submit_wait);
359        assert_eq!(config.cpu_affinity, None);
360        assert!(config.defer_wakeup);
361    }
362}