Add additional counter for syscall switches.

This commit is contained in:
4lDO2
2026-09-02 13:16:09 +02:00
parent d2874a167d
commit f4d59db53e
4 changed files with 24 additions and 7 deletions
+6 -3
View File
@@ -386,11 +386,12 @@ impl Drop for PreemptGuardL2<'_> {
}
}
pub fn get_contexts_stats(token: &mut CleanLockToken) -> (usize, usize, usize, usize) {
pub fn get_contexts_stats(token: &mut CleanLockToken) -> [usize; 5] {
let alive = contexts(token.downgrade()).len();
let mut running = 0;
let mut switches = 0;
let mut syscall_switches = 0;
for i in 0..crate::cpu_count() {
if let Some(percpu) = unsafe {
@@ -399,11 +400,13 @@ pub fn get_contexts_stats(token: &mut CleanLockToken) -> (usize, usize, usize, u
.as_ref()
} {
running += percpu.switch_internals.run_queue.lock().queue.len();
switches += CpuStatsData::from(&percpu.stats).context_switches as usize;
let data = CpuStatsData::from(&percpu.stats);
switches += data.context_switches as usize;
syscall_switches += data.syscall_switches as usize;
}
}
let blocked = alive.saturating_sub(running);
(alive, running, blocked, switches)
[alive, running, blocked, switches, syscall_switches]
}
+1 -1
View File
@@ -180,7 +180,7 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult {
let switch_time = crate::time::monotonic(token);
let percpu = PercpuBlock::current();
percpu.stats.add_context_switch();
percpu.stats.add_context_switch(percpu.inside_syscall.get());
//set PIT Interrupt counter to 0, giving each process same amount of PIT ticks
percpu.switch_internals.pit_ticks.set(0);
+14 -2
View File
@@ -39,8 +39,10 @@ pub struct CpuStats {
irq: AtomicU64,
/// Current state of the CPU
state: AtomicU8,
/// The number of times (overall) where a CPU switched from one context to another.
/// The number of times this CPU switched from one context to another.
context_switches: AtomicU64,
/// The number of times this CPU switched while handling a syscall.
syscall_switches: AtomicU64,
}
impl CpuStats {
@@ -53,6 +55,7 @@ impl CpuStats {
irq: AtomicU64::new(0),
state: AtomicU8::new(0),
context_switches: AtomicU64::new(0),
syscall_switches: AtomicU64::new(0),
}
}
}
@@ -70,6 +73,8 @@ pub struct CpuStatsData {
pub irq: u64,
/// Number of context switches on this CPU
pub context_switches: u64,
/// Number of syscall-caused context switches on this CPU
pub syscall_switches: u64,
}
impl CpuStats {
@@ -118,12 +123,18 @@ impl CpuStats {
/// Add a context switch to the count.
#[inline]
pub fn add_context_switch(&self) {
pub fn add_context_switch(&self, inside_syscall: bool) {
// Again this is percpu, so fetch_add is unnecessary.
self.context_switches.store(
self.context_switches.load(Ordering::Relaxed) + 1,
Ordering::Relaxed,
);
if inside_syscall {
self.syscall_switches.store(
self.syscall_switches.load(Ordering::Relaxed) + 1,
Ordering::Relaxed,
);
}
}
}
@@ -146,6 +157,7 @@ impl From<&CpuStats> for CpuStatsData {
idle: val.idle.load(Ordering::Relaxed),
irq: val.irq.load(Ordering::Relaxed),
context_switches: val.context_switches.load(Ordering::Relaxed),
syscall_switches: val.syscall_switches.load(Ordering::Relaxed),
}
}
}
+3 -1
View File
@@ -15,7 +15,7 @@ use alloc::{string::String, vec::Vec};
pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
let start_time_sec = *START.lock(token.token()) / 1_000_000_000;
let (contexts_alive, contexts_running, contexts_blocked, context_switches) =
let [contexts_alive, contexts_running, contexts_blocked, context_switches, syscall_switches] =
get_contexts_stats(token);
let (event_keys, event_subs) = get_event_stat(token);
let (futex_keys, futex_subs) = get_futex_stat(token);
@@ -25,6 +25,7 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
"{}{}\n\
boot_time: {start_time_sec}\n\
context_switches: {}\n\
syscall_switches: {}\n\
contexts_created: {}\n\
contexts_alive: {contexts_alive}\n\
contexts_running: {contexts_running}\n\
@@ -38,6 +39,7 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
get_cpu_stats(),
get_irq_stats(),
context_switches,
syscall_switches,
get_contexts_count(),
);