use std::{
any::Any,
fmt::Debug,
ops::{Add, AddAssign},
sync::{atomic::AtomicU64, Arc},
};
pub trait Metrics: Send + Sync {
fn measure(&mut self, data: &[u64]);
fn as_any(&self) -> &dyn Any;
}
#[derive(Default, Debug, Clone)]
pub struct Counter {
pub inst_count: u64,
pub frops_count: u64,
}
impl Counter {
#[inline(always)]
pub fn update(&mut self, num: u64) {
self.inst_count += num;
}
#[inline(always)]
pub fn update_frops(&mut self, num: u64) {
self.frops_count += num;
}
}
impl Add for &Counter {
type Output = Counter;
fn add(self, other: Self) -> Counter {
Counter {
inst_count: self.inst_count + other.inst_count,
frops_count: self.frops_count + other.frops_count,
}
}
}
impl AddAssign<&Counter> for Counter {
fn add_assign(&mut self, other: &Counter) {
self.inst_count += other.inst_count;
self.frops_count += other.frops_count;
}
}
#[derive(Debug)]
pub struct CounterStats {
pub inst_count: Arc<Vec<AtomicU64>>,
pub end_pc: u64,
pub steps: u64,
}
impl CounterStats {
pub fn new(inst_count: Arc<Vec<AtomicU64>>) -> Self {
CounterStats { inst_count, end_pc: 0, steps: 0 }
}
#[inline(always)]
pub fn update(&mut self, pc: u64, index: u64, step: u64, num: u64, end: bool) {
self.inst_count[index as usize].fetch_add(num, std::sync::atomic::Ordering::Relaxed);
if end {
self.end_pc = pc;
self.steps = step + 1;
}
}
}
impl AddAssign<&CounterStats> for CounterStats {
fn add_assign(&mut self, other: &CounterStats) {
if other.end_pc != 0 {
self.end_pc = other.end_pc;
}
if other.steps != 0 {
self.steps = other.steps;
}
}
}