ruvix_shell/commands/
tasks.rs1use crate::{ShellBackend, TaskState};
4use alloc::format;
5use alloc::string::String;
6
7fn state_str(state: TaskState) -> &'static str {
9 match state {
10 TaskState::Ready => "READY",
11 TaskState::Running => "RUN",
12 TaskState::Blocked => "BLOCK",
13 TaskState::Sleeping => "SLEEP",
14 TaskState::Exited => "EXIT",
15 }
16}
17
18fn task_name(name: &[u8; 16]) -> String {
20 let end = name.iter().position(|&b| b == 0).unwrap_or(16);
21 String::from_utf8_lossy(&name[..end]).into_owned()
22}
23
24#[must_use]
26pub fn execute<B: ShellBackend>(backend: &B) -> String {
27 let tasks = backend.task_list();
28
29 if tasks.is_empty() {
30 return String::from("No tasks.");
31 }
32
33 let mut output = String::from("Task List\n=========\n");
34 output.push_str(" ID NAME STATE PRI PART CPU CAPS\n");
35 output.push_str(" --- --------------- ------ --- ---- ---- ----\n");
36
37 for task in &tasks {
38 let name = task_name(&task.name);
39 let line = format!(
40 " {:<3} {:<15} {:<6} {:>3} {:>4} 0x{:02X} {:>4}\n",
41 task.id,
42 if name.len() > 15 {
43 &name[..15]
44 } else {
45 &name
46 },
47 state_str(task.state),
48 task.priority,
49 task.partition,
50 task.cpu_affinity,
51 task.cap_count
52 );
53 output.push_str(&line);
54 }
55
56 output.push_str(&format!("\nTotal: {} task(s)", tasks.len()));
57 output
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_state_str() {
66 assert_eq!(state_str(TaskState::Ready), "READY");
67 assert_eq!(state_str(TaskState::Running), "RUN");
68 assert_eq!(state_str(TaskState::Blocked), "BLOCK");
69 assert_eq!(state_str(TaskState::Sleeping), "SLEEP");
70 assert_eq!(state_str(TaskState::Exited), "EXIT");
71 }
72
73 #[test]
74 fn test_task_name() {
75 let name1 = *b"test\0\0\0\0\0\0\0\0\0\0\0\0";
76 assert_eq!(task_name(&name1), "test");
77
78 let name2 = *b"very_long_name!!";
79 assert_eq!(task_name(&name2), "very_long_name!!");
80
81 let name3 = [0u8; 16];
82 assert_eq!(task_name(&name3), "");
83 }
84}