moto_sys/
stats.rs

1// Various statistics, best effort (never precise).
2
3#[cfg(feature = "userspace")]
4use crate::syscalls::SysMem;
5#[cfg(feature = "userspace")]
6use crate::ErrorCode;
7
8pub const PID_SYSTEM: u64 = 0; // Used for aggregate (System) stats.
9pub const PID_KERNEL: u64 = 1;
10pub const PID_SYS_IO: u64 = 2;
11
12// Instead of having a version field and mutate the struct,
13// which is unsafe/brittle, we will just be adding new structs.
14#[repr(C)]
15#[derive(Default)]
16pub struct ProcessStatsV1 {
17    pub pid: u64, // PID_SYSTEM, PID_KERNEL, or actual process ID.
18    pub parent_pid: u64,
19    pub pages_user: u64,
20    pub pages_kernel: u64,
21    pub total_threads: u64,   // All threads created by this process.
22    pub total_children: u64,  // All direct child processes spawned.
23    pub active_threads: u64,  // Threads still running.
24    pub active_children: u64, // Children still running.
25    pub debug_name_bytes: [u8; 32],
26    pub debug_name_len: u8,
27    pub active: u8, // 0 => zombie; 1 => active.
28}
29
30#[cfg(feature = "userspace")]
31impl ProcessStatsV1 {
32    // List processes, in PID order. Completed processes without running
33    // descendants may not be listed. @start will be included, if present.
34    pub fn list(start: u64, buf: &mut [ProcessStatsV1]) -> Result<usize, ErrorCode> {
35        super::syscalls::SysCtl::list_processes_v1(start, true, buf)
36    }
37
38    // List direct children of the process. @parent will not be included.
39    pub fn list_children(parent: u64, buf: &mut [ProcessStatsV1]) -> Result<usize, ErrorCode> {
40        super::syscalls::SysCtl::list_processes_v1(parent, false, buf)
41    }
42
43    pub fn debug_name(&self) -> &str {
44        core::str::from_utf8(&self.debug_name_bytes[0..(self.debug_name_len as usize)])
45            .unwrap_or("~")
46    }
47
48    pub fn total_bytes(&self) -> u64 {
49        (self.pages_user + self.pages_kernel) << SysMem::PAGE_SIZE_SMALL_LOG2
50    }
51}
52
53// Physical memory stats.
54#[repr(C)]
55#[derive(Default)]
56pub struct MemoryStats {
57    pub available: u64,  // Total physical memory.
58    pub used_pages: u64, // Physical pages mapped.
59    pub heap_total: u64, // Total memory in the kernel heap.
60}
61
62#[cfg(feature = "userspace")]
63impl MemoryStats {
64    pub fn get() -> Result<MemoryStats, ErrorCode> {
65        SysMem::query_stats()
66    }
67
68    pub fn used(&self) -> u64 {
69        self.used_pages << SysMem::PAGE_SIZE_SMALL_LOG2
70    }
71}
72
73#[cfg(feature = "userspace")]
74pub fn get_cpu_usage(buf: &mut [f32]) -> Result<(), ErrorCode> {
75    crate::syscalls::SysCpu::query_stats(buf)
76}