alith_devices/devices/
cpu.rs

1#[derive(Debug, Clone)]
2pub struct CpuConfig {
3    pub num_cpus: usize,
4    pub threads: Option<i16>,
5    pub threads_batch: Option<i16>,
6    pub use_percentage: f32,
7}
8
9impl Default for CpuConfig {
10    fn default() -> Self {
11        let mut sys = sysinfo::System::new_all();
12        sys.refresh_all();
13
14        let num_cpus = match sys.physical_core_count() {
15            Some(cores) => cores,
16            None => sys.cpus().len(), // Fallback to logical core count for VMs
17        };
18
19        Self {
20            num_cpus,
21            threads: None,
22            threads_batch: None,
23            use_percentage: 0.70,
24        }
25    }
26}
27
28impl CpuConfig {
29    pub(crate) fn initialize(&mut self, error_on_config_issue: bool) -> crate::Result<()> {
30        if self.use_percentage > 1.0 || self.use_percentage < 0.0 {
31            if error_on_config_issue {
32                crate::bail!(
33                    "Percentage of total CPU cores must be between 0.0 and 1.0. use_percentage: {}",
34                    self.use_percentage
35                );
36            } else {
37                crate::warn!(
38                    "Percentage of total CPU must be between 0.0 and 1.0. use_percentage: {}. Falling back to default value of 0.70",
39                    self.use_percentage
40                );
41                self.use_percentage = 0.70;
42            }
43        }
44        self.threads = self.check_thread_count(self.threads, error_on_config_issue)?;
45        self.threads_batch = self.check_thread_count(self.threads_batch, error_on_config_issue)?;
46        Ok(())
47    }
48
49    fn check_thread_count(
50        &self,
51        threads: Option<i16>,
52        error_on_config_issue: bool,
53    ) -> crate::Result<Option<i16>> {
54        if let Some(threads) = threads {
55            if threads > self.num_cpus as i16 {
56                if error_on_config_issue {
57                    crate::bail!(
58                        "Requested threads {} is greater than the number of available physical CPU cores {}. Exiting",
59                        threads,
60                        self.num_cpus
61                    );
62                } else {
63                    crate::warn!(
64                        "Requested threads {} is greater than the number of available physical CPU cores {}. Using the number of available physical CPU cores",
65                        threads,
66                        self.num_cpus
67                    );
68                    Ok(Some(self.num_cpus as i16))
69                }
70            } else {
71                Ok(Some(threads))
72            }
73        } else {
74            Ok(None)
75        }
76    }
77
78    pub fn thread_count_or_default(&self) -> i16 {
79        self.count_or_default(self.threads)
80    }
81
82    pub fn thread_count_batch_or_default(&self) -> i16 {
83        self.count_or_default(self.threads_batch)
84    }
85
86    fn count_or_default(&self, threads: Option<i16>) -> i16 {
87        if let Some(threads) = threads {
88            threads
89        } else {
90            (self.num_cpus as f32 * self.use_percentage) as i16
91        }
92    }
93}
94
95impl std::fmt::Display for CpuConfig {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        writeln!(f)?;
98        writeln!(f, "CpuConfig:")?;
99        crate::i_nlns(
100            f,
101            &[
102                format_args!("num_cpus: {}", self.num_cpus),
103                format_args!("threads: {:?}", self.threads),
104                format_args!("threads_batch: {:?}", self.threads_batch),
105                format_args!("use_percentage: {}", self.use_percentage),
106            ],
107        )
108    }
109}