mmtk/util/statistics/counter/
event_counter.rs1use super::*;
2use crate::util::statistics::stats::{SharedStats, DEFAULT_NUM_PHASES};
3use std::sync::Arc;
4
5pub struct EventCounter {
10 name: String,
11 pub implicitly_start: bool,
12 merge_phases: bool,
13 pub(super) count: Vec<u64>,
16 current_count: u64,
17 running: bool,
18 stats: Arc<SharedStats>,
19}
20
21impl EventCounter {
22 pub fn new(
23 name: String,
24 stats: Arc<SharedStats>,
25 implicitly_start: bool,
26 merge_phases: bool,
27 ) -> Self {
28 EventCounter {
29 name,
30 implicitly_start,
31 merge_phases,
32 count: Vec::with_capacity(DEFAULT_NUM_PHASES),
33 current_count: 0,
34 running: false,
35 stats,
36 }
37 }
38
39 pub fn inc(&mut self) {
43 if self.running {
44 self.inc_by(1);
45 }
46 }
47
48 pub fn inc_by(&mut self, value: u64) {
52 if self.running {
53 self.current_count += value;
54 }
55 }
56
57 pub fn print_current(&self) {
58 self.print_value(self.current_count);
59 }
60
61 fn print_value(&self, value: u64) {
62 print!("{}", value);
63 }
64}
65
66impl Counter for EventCounter {
67 fn start(&mut self) {
68 if !self.stats.get_gathering_stats() {
69 return;
70 }
71 debug_assert!(!self.running);
72 self.current_count = 0;
73 self.running = true;
74 }
75
76 fn stop(&mut self) {
77 if !self.stats.get_gathering_stats() {
78 return;
79 }
80 debug_assert!(self.running);
81 self.count.push(self.current_count);
82 debug_assert_eq!(self.count[self.stats.get_phase()], self.current_count);
83 self.running = false;
84 }
85
86 fn phase_change(&mut self, old_phase: usize) {
87 if self.running {
88 self.count.push(self.current_count);
89 debug_assert_eq!(self.count[old_phase], self.current_count);
90 self.current_count = 0;
91 }
92 }
93
94 fn print_count(&self, phase: usize) {
95 if self.merge_phases() {
96 debug_assert!((phase | 1) == (phase + 1));
97 self.print_value(self.count[phase] + self.count[phase + 1]);
98 } else {
99 self.print_value(self.count[phase]);
100 }
101 }
102
103 fn get_total(&self, other: Option<bool>) -> u64 {
104 match other {
105 None => {
106 let mut total = 0;
107 for p in 0..=self.stats.get_phase() {
108 total += self.count[p];
109 }
110 total
111 }
112 Some(m) => {
113 let mut total = 0;
114 let mut p = !m as usize;
115 while p <= self.stats.get_phase() {
116 total += self.count[p];
117 p += 2;
118 }
119 total
120 }
121 }
122 }
123
124 fn print_total(&self, other: Option<bool>) {
125 self.print_value(self.get_total(other));
126 }
127
128 fn print_min(&self, other: bool) {
129 let mut p = !other as usize;
130 let mut min = self.count[p];
131 while p < self.stats.get_phase() {
132 if self.count[p] < min {
133 min = self.count[p];
134 p += 2;
135 }
136 }
137 self.print_value(min);
138 }
139
140 fn print_max(&self, other: bool) {
141 let mut p = !other as usize;
142 let mut max = self.count[p];
143 while p < self.stats.get_phase() {
144 if self.count[p] > max {
145 max = self.count[p];
146 p += 2;
147 }
148 }
149 self.print_value(max);
150 }
151
152 fn print_last(&self) {
153 let phase = self.stats.get_phase();
154 if phase > 0 {
155 self.print_count(phase - 1);
156 }
157 }
158
159 fn merge_phases(&self) -> bool {
160 self.merge_phases
161 }
162
163 fn implicitly_start(&self) -> bool {
164 self.implicitly_start
165 }
166
167 fn name(&self) -> &String {
168 &self.name
169 }
170}