kernel: implement /proc/uptime — system uptime

Added ProcUptime ContextHandle that reads monotonic() time
from the kernel and outputs it as uptime_seconds idle_seconds
in Linux /proc/uptime format (two floats with newline).

Cross-referenced with Linux 7.1 fs/proc/uptime.c uptime_proc_show().
Idle time is 0.0 since Red Bear does not track per-CPU idle time.

Also added to ProcRoot directory listing.
This commit is contained in:
2026-07-09 10:04:10 +03:00
parent 24a7d990d4
commit 2b5e1e03fd
+13 -3
View File
@@ -157,6 +157,7 @@ enum ContextHandle {
ProcRoot,
ProcCpuinfo,
ProcMeminfo,
ProcUptime,
ProcDir {
pid: usize,
},
@@ -404,6 +405,9 @@ impl ProcScheme {
if path == "proc/meminfo" || path == "meminfo" {
return Some(ContextHandle::ProcMeminfo);
}
if path == "proc/uptime" || path == "uptime" {
return Some(ContextHandle::ProcUptime);
}
let mut parts = path.split('/');
let pid = parts.next()?.parse::<usize>().ok()?;
match (parts.next(), parts.next()) {
@@ -943,8 +947,8 @@ impl KernelScheme for ProcScheme {
let mut buf = DirentBuf::new(buf, header_size).ok_or(Error::new(EIO))?;
match handle.kind {
ContextHandle::ProcRoot => {
// First: system files (cpuinfo, meminfo, etc.)
for (idx, name) in ["cpuinfo", "meminfo"].iter().enumerate() {
// First: system files (cpuinfo, meminfo, uptime)
for (idx, name) in ["cpuinfo", "meminfo", "uptime"].iter().enumerate() {
buf.entry(DirEntry {
inode: 0,
next_opaque_id: (idx + 1) as u64,
@@ -960,7 +964,7 @@ impl KernelScheme for ProcScheme {
pids.push(context_ref.read(token.token()).pid);
}
pids.sort_unstable();
let base_idx = 2; // after cpuinfo + meminfo
let base_idx = 3; // after cpuinfo + meminfo + uptime
for (idx, pid) in pids.into_iter().enumerate().skip(opaque.saturating_sub(base_idx)) {
let name = format!("{}", pid);
buf.entry(DirEntry {
@@ -1886,6 +1890,12 @@ impl ContextHandle {
);
read_from(buf, output.as_bytes(), offset)
}
ContextHandle::ProcUptime => {
let uptime_s = crate::time::monotonic(token) as f64 / crate::time::NANOS_PER_SEC as f64;
let idle_s = 0.0f64; // Red Bear has no per-CPU idle tracking
let output = format!("{:.2} {:.2}\n", uptime_s, idle_s);
read_from(buf, output.as_bytes(), offset)
}
ContextHandle::ProcStat { pid } => {
let context = proc_context(*pid, token).ok_or(Error::new(ESRCH))?;
let (pid, comm, state, ppid, priority, utime, stime, pgrp, session, starttime, owner_proc_id, addr_space) = {