mmtk 0.32.0

MMTk is a framework for the design and implementation of high-performance and portable memory managers.
Documentation
use super::*;
use crate::util::statistics::stats::{SharedStats, DEFAULT_NUM_PHASES};
use std::fmt;
use std::sync::Arc;

pub struct LongCounter<T: Diffable> {
    name: String,
    pub implicitly_start: bool,
    merge_phases: bool,
    count: Vec<u64>,
    diffable: T,
    start_value: Option<T::Val>,
    total_count: u64,
    running: bool,
    stats: Arc<SharedStats>,
}

impl<T: Diffable> fmt::Debug for LongCounter<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "LongCounter({})", self.name)
    }
}

impl<T: Diffable> Counter for LongCounter<T> {
    fn start(&mut self) {
        if !self.stats.get_gathering_stats() {
            return;
        }
        debug_assert!(!self.running);
        self.running = true;
        self.diffable.start();
        self.start_value = Some(self.diffable.current_value());
    }

    fn stop(&mut self) {
        if !self.stats.get_gathering_stats() {
            return;
        }
        debug_assert!(self.running);
        self.running = false;
        self.diffable.stop();
        let current_value = self.diffable.current_value();
        let delta = T::diff(&current_value, self.start_value.as_ref().unwrap());
        self.count.push(delta);
        debug_assert_eq!(self.count[self.stats.get_phase()], delta);
        self.total_count += delta;
    }

    fn phase_change(&mut self, old_phase: usize) {
        if self.running {
            let now = self.diffable.current_value();
            let delta = T::diff(&now, self.start_value.as_ref().unwrap());
            self.count.push(delta);
            debug_assert_eq!(self.count[old_phase], delta);
            self.total_count += delta;
            self.start_value = Some(now);
        }
    }

    fn print_count(&self, phase: usize) {
        if self.merge_phases() {
            debug_assert!((phase | 1) == (phase + 1));
            self.print_value(self.count[phase] + self.count[phase + 1]);
        } else {
            self.print_value(self.count[phase]);
        }
    }

    fn get_total(&self, other: Option<bool>) -> u64 {
        match other {
            None => self.total_count,
            Some(m) => {
                let mut total = 0;
                let mut p = !m as usize;
                while p <= self.stats.get_phase() {
                    total += self.count[p];
                    p += 2;
                }
                total
            }
        }
    }

    fn print_total(&self, other: Option<bool>) {
        self.print_value(self.get_total(other));
    }

    fn print_min(&self, other: bool) {
        let mut p = !other as usize;
        let mut min = self.count[p];
        while p < self.stats.get_phase() {
            if self.count[p] < min {
                min = self.count[p];
                p += 2;
            }
        }
        self.print_value(min);
    }

    fn print_max(&self, other: bool) {
        let mut p = !other as usize;
        let mut max = self.count[p];
        while p < self.stats.get_phase() {
            if self.count[p] > max {
                max = self.count[p];
                p += 2;
            }
        }
        self.print_value(max);
    }

    fn print_last(&self) {
        let phase = self.stats.get_phase();
        if phase > 0 {
            self.print_count(phase - 1);
        }
    }

    fn merge_phases(&self) -> bool {
        self.merge_phases
    }

    fn implicitly_start(&self) -> bool {
        self.implicitly_start
    }

    fn name(&self) -> &String {
        &self.name
    }
}

impl<T: Diffable> LongCounter<T> {
    pub fn new(
        name: String,
        stats: Arc<SharedStats>,
        implicitly_start: bool,
        merge_phases: bool,
        diffable: T,
    ) -> Self {
        LongCounter {
            name,
            implicitly_start,
            merge_phases,
            count: Vec::with_capacity(DEFAULT_NUM_PHASES),
            diffable,
            start_value: None,
            total_count: 0,
            running: false,
            stats,
        }
    }

    fn print_value(&self, val: u64) {
        T::print_diff(val);
    }
}

pub type Timer = LongCounter<MonotoneNanoTime>;