ruvix_shell/commands/
cpu.rs1use crate::ShellBackend;
4use alloc::format;
5use alloc::string::String;
6
7#[must_use]
9pub fn execute<B: ShellBackend>(backend: &B) -> String {
10 let cpus = backend.cpu_info();
11
12 if cpus.is_empty() {
13 return String::from("No CPU information available.");
14 }
15
16 let online_count = cpus.iter().filter(|c| c.online).count();
17 let total_count = cpus.len();
18
19 let mut output = String::from("CPU Information (SMP)\n");
20 output.push_str("=====================\n");
21 output.push_str(&format!("CPUs: {} online / {} total\n\n", online_count, total_count));
22 output.push_str(" ID STATE FREQ LOAD TYPE\n");
23 output.push_str(" --- -------- ------- ----- --------\n");
24
25 for cpu in &cpus {
26 let state = if cpu.online { "ONLINE" } else { "OFFLINE" };
27 let cpu_type = if cpu.is_primary { "PRIMARY" } else { "SECONDARY" };
28 let freq = if cpu.freq_mhz > 0 {
29 format!("{} MHz", cpu.freq_mhz)
30 } else {
31 String::from("N/A")
32 };
33 let load = if cpu.online {
34 format!("{}%", cpu.load_percent)
35 } else {
36 String::from("-")
37 };
38
39 let line = format!(
40 " {:>3} {:<8} {:>7} {:>5} {}\n",
41 cpu.id, state, freq, load, cpu_type
42 );
43 output.push_str(&line);
44 }
45
46 let online_cpus: alloc::vec::Vec<_> = cpus.iter().filter(|c| c.online).collect();
48 if !online_cpus.is_empty() {
49 let total_load: u32 = online_cpus.iter().map(|c| u32::from(c.load_percent)).sum();
50 let avg_load = total_load / online_cpus.len() as u32;
51 output.push_str(&format!("\nAverage load: {}%", avg_load));
52 }
53
54 output
55}
56
57#[cfg(test)]
58mod tests {
59 use crate::CpuInfo;
60
61 #[test]
62 fn test_cpu_info() {
63 let cpu = CpuInfo {
64 id: 0,
65 online: true,
66 is_primary: true,
67 freq_mhz: 1800,
68 load_percent: 25,
69 };
70 assert_eq!(cpu.id, 0);
71 assert!(cpu.online);
72 assert!(cpu.is_primary);
73 }
74}