diff --git a/src/context/mod.rs b/src/context/mod.rs index 37c73f5a37..c185364642 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -82,6 +82,7 @@ static IDLE_CONTEXTS: Mutex> = Mutex::new(VecDeque: pub struct RunContextData { set: [VecDeque; 40], + count: usize, } impl RunContextData { @@ -89,8 +90,13 @@ impl RunContextData { const EMPTY_VEC: VecDeque = VecDeque::new(); Self { set: [EMPTY_VEC; 40], + count: 0, } } + pub fn update_count(&mut self) -> usize { + self.count = self.set.iter().map(|q| q.len()).sum(); + self.count + } } /// Get the global schemes list, const @@ -322,3 +328,11 @@ impl Drop for PreemptGuardL2<'_> { self.context.write(self.token.token()).preempt_locks -= 1; } } + +pub fn get_contexts_stats(token: &mut CleanLockToken) -> (usize, usize, usize) { + let alive = contexts(token.downgrade()).len(); + let running = run_contexts(token.token()).count; + let blocked = idle_contexts(token.downgrade()).len(); + + (alive, running, blocked) +} diff --git a/src/context/switch.rs b/src/context/switch.rs index 177e213fcd..e0e4535eae 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -384,7 +384,6 @@ fn select_next_context( ) -> Option<(ArcContextLockWriteGuard, Option)> { let contexts_data = run_contexts(token.token()); let (mut contexts_data, mut token) = contexts_data.into_split(); - let contexts_list = &mut contexts_data.set; let idle_context = percpu.switch_internals.idle_context(); let mut balance = percpu.balance.get(); let mut i = percpu.last_queue.get() % 40; @@ -396,7 +395,8 @@ fn select_next_context( let mut total_iters = 0; let mut next_context_guard_opt = None; - let total_contexts: usize = contexts_list.iter().map(|q| q.len()).sum(); + let total_contexts: usize = contexts_data.update_count(); + let contexts_list = &mut contexts_data.set; let mut skipped_contexts = 0; 'priority: loop { diff --git a/src/event.rs b/src/event.rs index 66b986be4e..ade64c885c 100644 --- a/src/event.rs +++ b/src/event.rs @@ -190,6 +190,17 @@ pub fn unregister_file(scheme: SchemeId, number: usize, token: &mut CleanLockTok registry.remove(&RegKey { scheme, number }); } +pub fn get_event_stat(token: &mut CleanLockToken) -> (usize, usize) { + let mut regc = 0; + let mut regl = 0; + let registry = REGISTRY.read(token.token()); + for (k, v) in registry.iter() { + regl += v.len(); + regc += 1; + } + (regc, regl) +} + //TODO: Implement unregister_queue // pub fn unregister_queue(scheme: SchemeId, number: usize) { // diff --git a/src/scheme/sys/stat.rs b/src/scheme/sys/stat.rs index 6e094280a6..b583a398d9 100644 --- a/src/scheme/sys/stat.rs +++ b/src/scheme/sys/stat.rs @@ -1,8 +1,9 @@ use core::fmt::Write as _; use crate::{ - context::{contexts, Status}, + context::{contexts, get_contexts_stats, Status}, cpu_stats::{get_context_switch_count, get_contexts_count, irq_counts}, + event::get_event_stat, percpu::get_all_stats, sync::CleanLockToken, syscall::error::Result, @@ -14,14 +15,18 @@ use alloc::{string::String, vec::Vec}; pub fn resource(token: &mut CleanLockToken) -> Result> { let start_time_sec = *START.lock(token.token()) / 1_000_000_000; - let (contexts_running, contexts_blocked) = get_contexts_stats(token); + let (contexts_alive, contexts_running, contexts_blocked) = get_contexts_stats(token); + let (event_keys, event_subs) = get_event_stat(token); let res = format!( "{}{}\n\ boot_time: {start_time_sec}\n\ context_switches: {}\n\ contexts_created: {}\n\ + contexts_alive: {contexts_alive}\n\ contexts_running: {contexts_running}\n\ - contexts_blocked: {contexts_blocked}", + contexts_blocked: {contexts_blocked}\n\ + event_registries: {event_keys}\n\ + event_subcribers: {event_subs}\n", get_cpu_stats(), get_irq_stats(), get_context_switch_count(), @@ -70,27 +75,3 @@ fn get_irq_stats() -> String { output } - -/// Format contexts stats. -fn get_contexts_stats(token: &mut CleanLockToken) -> (u64, u64) { - let mut running = 0; - let mut blocked = 0; - - let statuses = { - let mut contexts = contexts(token.downgrade()); - let (contexts, mut token) = contexts.token_split(); - contexts - .iter() - .map(|context| context.read(token.token()).status.clone()) - .collect::>() - }; - - for status in statuses { - if status.is_runnable() { - running += 1; - } else if !status.is_dead() { - blocked += 1; - } - } - (running, blocked) -}