Files
RedBear-OS/src/scheme/sys/context.rs
T
2024-03-04 19:03:00 +01:00

129 lines
4.2 KiB
Rust

use alloc::string::ToString;
use alloc::{string::String, vec::Vec};
use crate::{context, paging::PAGE_SIZE, syscall::error::Result};
pub fn resource() -> Result<Vec<u8>> {
let mut string = format!(
"{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<11}{:<12}{:<8}{}\n",
"PID",
"PGID",
"PPID",
"SID",
"RUID",
"RGID",
"RNS",
"EUID",
"EGID",
"ENS",
"STAT",
"CPU",
"AFFINITY",
"TIME",
"MEM",
"NAME"
);
{
let contexts = context::contexts();
for (_id, context_lock) in contexts.iter() {
let context = context_lock.read();
let mut stat_string = String::new();
// TODO: All user programs must have some grant in order for executable memory to even
// exist, but is this a good indicator of whether it is user or kernel?
stat_string.push(if let Ok(addr_space) = context.addr_space() {
if addr_space.inner.read().grants.is_empty() {
'K'
} else {
'U'
}
} else {
'R'
});
match context.status {
context::Status::Runnable => {
stat_string.push('R');
}
context::Status::Blocked | context::Status::HardBlocked { .. } => {
if context.wake.is_some() {
stat_string.push('S');
} else {
stat_string.push('B');
}
}
context::Status::Stopped(_sig) => {
stat_string.push('T');
}
context::Status::Exited(_status) => {
stat_string.push('Z');
}
}
if context.running {
stat_string.push('+');
}
let cpu_string = if let Some(cpu_id) = context.cpu_id {
format!("{}", cpu_id)
} else {
format!("?")
};
let affinity = context.sched_affinity.to_string();
let cpu_time_s = context.cpu_time / crate::time::NANOS_PER_SEC;
let cpu_time_ns = context.cpu_time % crate::time::NANOS_PER_SEC;
let cpu_time_string = format!(
"{:02}:{:02}:{:02}.{:02}",
cpu_time_s / 3600,
(cpu_time_s / 60) % 60,
cpu_time_s % 60,
cpu_time_ns / 10_000_000
);
let mut memory = context.kfx.len();
if let Some(ref kstack) = context.kstack {
memory += kstack.len();
}
if let Ok(addr_space) = context.addr_space() {
for (_base, info) in addr_space.inner.read().grants.iter() {
// TODO: method
if matches!(info.provider, context::memory::Provider::Allocated { .. }) {
memory += info.page_count() * PAGE_SIZE;
}
}
}
let memory_string = if memory >= 1024 * 1024 * 1024 {
format!("{} GB", memory / 1024 / 1024 / 1024)
} else if memory >= 1024 * 1024 {
format!("{} MB", memory / 1024 / 1024)
} else if memory >= 1024 {
format!("{} KB", memory / 1024)
} else {
format!("{} B", memory)
};
string.push_str(&format!(
"{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<11}{:<12}{:<8}{}\n",
context.id.get(),
context.pgid.get(),
context.ppid.get(),
context.session_id.get(),
context.ruid,
context.rgid,
context.rns.get(),
context.euid,
context.egid,
context.ens.get(),
stat_string,
cpu_string,
affinity,
cpu_time_string,
memory_string,
context.name
));
}
}
Ok(string.into_bytes())
}