strat9_kernel/process/scheduler/
perf_counters.rs1use core::sync::atomic::{AtomicU64, Ordering};
8
9pub static IRQ_TIMER_COUNT: AtomicU64 = AtomicU64::new(0);
15pub static IRQ_TIMER_TSC: AtomicU64 = AtomicU64::new(0);
16
17pub static SCHED_YIELD_COUNT: AtomicU64 = AtomicU64::new(0);
19pub static SCHED_YIELD_TSC: AtomicU64 = AtomicU64::new(0);
20
21pub static SCHED_PREEMPT_COUNT: AtomicU64 = AtomicU64::new(0);
23pub static SCHED_PREEMPT_TSC: AtomicU64 = AtomicU64::new(0);
24
25pub static CTX_SWITCH_COUNT: AtomicU64 = AtomicU64::new(0);
27pub static CTX_SWITCH_TSC: AtomicU64 = AtomicU64::new(0);
28
29pub struct PerfScope {
43 start: u64,
44 accumulator: &'static AtomicU64,
45 counter: &'static AtomicU64,
46}
47
48impl PerfScope {
49 #[inline]
50 pub fn new(accumulator: &'static AtomicU64, counter: &'static AtomicU64) -> Self {
51 Self {
52 start: crate::arch::x86_64::rdtsc(),
53 accumulator,
54 counter,
55 }
56 }
57}
58
59impl Drop for PerfScope {
60 #[inline]
61 fn drop(&mut self) {
62 let elapsed = crate::arch::x86_64::rdtsc().wrapping_sub(self.start);
63 self.accumulator.fetch_add(elapsed, Ordering::Relaxed);
64 self.counter.fetch_add(1, Ordering::Relaxed);
65 }
66}
67
68pub struct PerfStat {
74 pub name: &'static str,
75 pub count: u64,
76 pub total_tsc: u64,
77}
78
79impl PerfStat {
80 pub fn avg_us(&self, tsc_khz: u64) -> u64 {
82 if self.count == 0 || tsc_khz == 0 {
83 return 0;
84 }
85 (self.total_tsc / self.count).saturating_mul(1_000) / tsc_khz
88 }
89}
90
91pub fn snapshot() -> [PerfStat; 4] {
93 [
94 PerfStat {
95 name: "irq_timer",
96 count: IRQ_TIMER_COUNT.load(Ordering::Relaxed),
97 total_tsc: IRQ_TIMER_TSC.load(Ordering::Relaxed),
98 },
99 PerfStat {
100 name: "sched_yield",
101 count: SCHED_YIELD_COUNT.load(Ordering::Relaxed),
102 total_tsc: SCHED_YIELD_TSC.load(Ordering::Relaxed),
103 },
104 PerfStat {
105 name: "preempt",
106 count: SCHED_PREEMPT_COUNT.load(Ordering::Relaxed),
107 total_tsc: SCHED_PREEMPT_TSC.load(Ordering::Relaxed),
108 },
109 PerfStat {
110 name: "ctx_switch",
111 count: CTX_SWITCH_COUNT.load(Ordering::Relaxed),
112 total_tsc: CTX_SWITCH_TSC.load(Ordering::Relaxed),
113 },
114 ]
115}