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 static DEFERRED_WORK_COUNT: AtomicU64 = AtomicU64::new(0);
31pub static DEFERRED_WORK_TSC: AtomicU64 = AtomicU64::new(0);
32
33pub struct PerfScope {
47 start: u64,
48 accumulator: &'static AtomicU64,
49 counter: &'static AtomicU64,
50}
51
52impl PerfScope {
53 #[inline]
54 pub fn new(accumulator: &'static AtomicU64, counter: &'static AtomicU64) -> Self {
55 Self {
56 start: crate::arch::rdtsc(),
57 accumulator,
58 counter,
59 }
60 }
61}
62
63impl Drop for PerfScope {
64 #[inline]
65 fn drop(&mut self) {
66 let elapsed = crate::arch::rdtsc().wrapping_sub(self.start);
67 self.accumulator.fetch_add(elapsed, Ordering::Relaxed);
68 self.counter.fetch_add(1, Ordering::Relaxed);
69 }
70}
71
72pub struct PerfStat {
78 pub name: &'static str,
79 pub count: u64,
80 pub total_tsc: u64,
81}
82
83impl PerfStat {
84 pub fn avg_us(&self, tsc_khz: u64) -> u64 {
86 if self.count == 0 || tsc_khz == 0 {
87 return 0;
88 }
89 (self.total_tsc / self.count).saturating_mul(1_000) / tsc_khz
92 }
93}
94
95pub fn snapshot() -> [PerfStat; 5] {
97 [
98 PerfStat {
99 name: "irq_timer",
100 count: IRQ_TIMER_COUNT.load(Ordering::Relaxed),
101 total_tsc: IRQ_TIMER_TSC.load(Ordering::Relaxed),
102 },
103 PerfStat {
104 name: "sched_yield",
105 count: SCHED_YIELD_COUNT.load(Ordering::Relaxed),
106 total_tsc: SCHED_YIELD_TSC.load(Ordering::Relaxed),
107 },
108 PerfStat {
109 name: "preempt",
110 count: SCHED_PREEMPT_COUNT.load(Ordering::Relaxed),
111 total_tsc: SCHED_PREEMPT_TSC.load(Ordering::Relaxed),
112 },
113 PerfStat {
114 name: "ctx_switch",
115 count: CTX_SWITCH_COUNT.load(Ordering::Relaxed),
116 total_tsc: CTX_SWITCH_TSC.load(Ordering::Relaxed),
117 },
118 PerfStat {
119 name: "dwork",
120 count: DEFERRED_WORK_COUNT.load(Ordering::Relaxed),
121 total_tsc: DEFERRED_WORK_TSC.load(Ordering::Relaxed),
122 },
123 ]
124}