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