use core::sync::atomic::{AtomicU64, AtomicU8, Ordering};
#[derive(Debug)]
pub struct Metrics {
pub major_collections: AtomicU64,
pub minor_collections: AtomicU64,
pub major_collect_avg_time: AtomicU64,
pub minor_collect_avg_time: AtomicU64,
pub max_old_objects: AtomicU64,
pub old_objects_count: AtomicU64,
pub arena_size: AtomicU64,
pub prev_arena_size: AtomicU64,
pub state: AtomicU8,
pub max_yield_time: AtomicU64,
pub avg_yield_time: AtomicU64,
pub monitor_is_on: bool,
}
impl Metrics {
pub fn new() -> Self {
Self {
major_collections: AtomicU64::new(0),
minor_collections: AtomicU64::new(0),
major_collect_avg_time: AtomicU64::new(0),
minor_collect_avg_time: AtomicU64::new(0),
max_yield_time: AtomicU64::new(0),
avg_yield_time: AtomicU64::new(0),
max_old_objects: AtomicU64::new(0),
old_objects_count: AtomicU64::new(0),
arena_size: AtomicU64::new(0),
prev_arena_size: AtomicU64::new(0),
state: AtomicU8::new(GC_STATE_SLEEPING),
monitor_is_on: true,
}
}
pub fn get_major_collections(&self) -> u64 {
self.major_collections.load(Ordering::Relaxed)
}
pub fn get_minor_collections(&self) -> u64 {
self.minor_collections.load(Ordering::Relaxed)
}
pub fn update_minor_collection_avg_time(&self, new_value: u64) {
update_avg_u64(
&self.minor_collect_avg_time,
new_value,
self.minor_collections.load(Ordering::Relaxed),
);
}
pub fn update_major_collection_avg_time(&self, new_value: u64) {
update_avg_u64(
&self.major_collect_avg_time,
new_value,
self.major_collections.load(Ordering::Relaxed),
);
}
pub fn get_major_collect_avg_time(&self) -> u64 {
self.major_collect_avg_time.load(Ordering::Relaxed)
}
pub fn get_minor_collect_avg_time(&self) -> u64 {
self.minor_collect_avg_time.load(Ordering::Relaxed)
}
pub fn get_max_old_objects(&self) -> u64 {
self.max_old_objects.load(Ordering::Relaxed)
}
pub fn get_old_objects_count(&self) -> u64 {
self.old_objects_count.load(Ordering::Relaxed)
}
pub fn get_arena_size(&self) -> u64 {
self.arena_size.load(Ordering::Relaxed)
}
pub fn get_prev_arena_size(&self) -> u64 {
self.prev_arena_size.load(Ordering::Relaxed)
}
pub fn get_state(&self) -> u8 {
self.state.load(Ordering::Relaxed)
}
pub fn get_max_yield_time(&self) -> u64 {
self.max_yield_time.load(Ordering::Relaxed)
}
pub fn get_avg_yield_time(&self) -> u64 {
self.avg_yield_time.load(Ordering::Relaxed)
}
}
pub fn update_avg_u64(running_avg: &AtomicU64, new_value: u64, sample_size: u64) {
let avg = running_avg.load(Ordering::Relaxed);
let update = new_value.abs_diff(avg) / (sample_size + 1);
let new_avg = if new_value > avg {
avg.saturating_add(update)
} else {
avg.saturating_sub(update)
};
running_avg.store(new_avg, Ordering::Relaxed);
}
pub const GC_STATE_SLEEPING: u8 = 0;
pub const GC_STATE_TRACING: u8 = 1;
pub const GC_STATE_SWEEPING: u8 = 2;
#[cfg(feature = "multi_threaded")]
pub const GC_STATE_WAITING_ON_MUTATORS: u8 = 3;