mmtk/util/statistics/counter/
event_counter.rs

1use super::*;
2use crate::util::statistics::stats::{SharedStats, DEFAULT_NUM_PHASES};
3use std::sync::Arc;
4
5/**
6 * This file implements a simple event counter (counting number
7 * events that occur for each phase).
8 */
9pub 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    /**
38     * Increment the event counter
39     */
40    pub fn inc(&mut self) {
41        if self.running {
42            self.inc_by(1);
43        }
44    }
45
46    /**
47     * Increment the event counter by provided value
48     */
49    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}