Nothing to see here, move along meow
1use super::tsc;
2
3pub struct WcetTracker<const N: usize> {
4 name: &'static str,
5 measurements: [u64; N],
6 count: usize,
7 max_cycles: u64,
8 min_cycles: u64,
9}
10
11impl<const N: usize> WcetTracker<N> {
12 pub const fn new(name: &'static str) -> Self {
13 Self {
14 name,
15 measurements: [0u64; N],
16 count: 0,
17 max_cycles: 0,
18 min_cycles: u64::MAX,
19 }
20 }
21
22 pub fn record(&mut self, cycles: u64) {
23 if self.count < N {
24 self.measurements[self.count] = cycles;
25 }
26 self.count += 1;
27
28 self.max_cycles = self.max_cycles.max(cycles);
29 self.min_cycles = self.min_cycles.min(cycles);
30 }
31
32 #[allow(dead_code)]
33 pub fn name(&self) -> &'static str {
34 self.name
35 }
36
37 #[allow(dead_code)]
38 pub fn count(&self) -> usize {
39 self.count
40 }
41
42 #[allow(dead_code)]
43 pub fn max_cycles(&self) -> u64 {
44 self.max_cycles
45 }
46
47 pub fn min_cycles(&self) -> u64 {
48 match self.count {
49 0 => 0,
50 _ => self.min_cycles,
51 }
52 }
53
54 pub fn log_summary(&self) {
55 let freq = tsc::freq_hz();
56 match self.count {
57 0 => crate::kprintln!(" {}: no measurements", self.name),
58 _ => {
59 crate::kprintln!(
60 " {}: {} samples, min={} cycles ({}ns), max={} cycles ({}ns)",
61 self.name,
62 self.count,
63 self.min_cycles(),
64 tsc::cycles_to_ns(self.min_cycles()),
65 self.max_cycles,
66 tsc::cycles_to_ns(self.max_cycles),
67 );
68 let _ = freq;
69 }
70 }
71 }
72}
73
74pub struct WcetGuard<'a, const N: usize> {
75 tracker: &'a mut WcetTracker<N>,
76 start: u64,
77}
78
79impl<'a, const N: usize> WcetGuard<'a, N> {
80 pub fn new(tracker: &'a mut WcetTracker<N>) -> Self {
81 let start = tsc::read_tsc_fenced();
82 Self { tracker, start }
83 }
84}
85
86impl<const N: usize> Drop for WcetGuard<'_, N> {
87 fn drop(&mut self) {
88 let end = tsc::read_tsc_fenced();
89 let elapsed = end - self.start;
90 self.tracker.record(elapsed);
91 }
92}