1use core::sync::atomic::{AtomicU64, AtomicU8, Ordering};
2
3#[derive(Debug)]
7pub struct Metrics {
8 pub major_collections: AtomicU64,
10
11 pub minor_collections: AtomicU64,
13
14 pub major_collect_avg_time: AtomicU64,
16
17 pub minor_collect_avg_time: AtomicU64,
19
20 pub max_old_objects: AtomicU64,
23
24 pub old_objects_count: AtomicU64,
27
28 pub arena_size: AtomicU64,
30
31 pub prev_arena_size: AtomicU64,
33
34 pub state: AtomicU8,
36
37 pub max_yield_time: AtomicU64,
38 pub avg_yield_time: AtomicU64,
39 pub max_arena_size: AtomicU64,
40 pub monitor_is_on: bool,
41}
42
43impl Metrics {
44 pub fn new() -> Self {
45 Self {
46 major_collections: AtomicU64::new(0),
47 minor_collections: AtomicU64::new(0),
48 major_collect_avg_time: AtomicU64::new(0),
49 minor_collect_avg_time: AtomicU64::new(0),
50 max_yield_time: AtomicU64::new(0),
51 avg_yield_time: AtomicU64::new(0),
52 max_old_objects: AtomicU64::new(0),
53 old_objects_count: AtomicU64::new(0),
54 arena_size: AtomicU64::new(0),
55 max_arena_size: AtomicU64::new(0),
56 prev_arena_size: AtomicU64::new(0),
57 state: AtomicU8::new(GC_STATE_SLEEPING),
58 monitor_is_on: true,
59 }
60 }
61
62 pub fn get_major_collections(&self) -> u64 {
63 self.major_collections.load(Ordering::Relaxed)
64 }
65
66 pub fn get_minor_collections(&self) -> u64 {
67 self.minor_collections.load(Ordering::Relaxed)
68 }
69
70 pub fn update_minor_collection_avg_time(&self, new_value: u64) {
71 update_avg_u64(
72 &self.minor_collect_avg_time,
73 new_value,
74 self.minor_collections.load(Ordering::Relaxed),
75 );
76 }
77
78 pub fn update_major_collection_avg_time(&self, new_value: u64) {
79 update_avg_u64(
80 &self.major_collect_avg_time,
81 new_value,
82 self.major_collections.load(Ordering::Relaxed),
83 );
84 }
85
86 pub fn get_major_collect_avg_time(&self) -> u64 {
87 self.major_collect_avg_time.load(Ordering::Relaxed)
88 }
89
90 pub fn get_minor_collect_avg_time(&self) -> u64 {
91 self.minor_collect_avg_time.load(Ordering::Relaxed)
92 }
93
94 pub fn get_max_old_objects(&self) -> u64 {
95 self.max_old_objects.load(Ordering::Relaxed)
96 }
97
98 pub fn get_old_objects_count(&self) -> u64 {
99 self.old_objects_count.load(Ordering::Relaxed)
100 }
101
102 pub fn get_arena_size(&self) -> u64 {
103 self.arena_size.load(Ordering::Relaxed)
104 }
105
106 pub fn get_prev_arena_size(&self) -> u64 {
107 self.prev_arena_size.load(Ordering::Relaxed)
108 }
109
110 pub fn get_state(&self) -> u8 {
111 self.state.load(Ordering::Relaxed)
112 }
113
114 pub fn get_max_yield_time(&self) -> u64 {
115 self.max_yield_time.load(Ordering::Relaxed)
116 }
117
118 pub fn get_avg_yield_time(&self) -> u64 {
119 self.avg_yield_time.load(Ordering::Relaxed)
120 }
121
122 pub fn get_max_arena_size(&self) -> u64 {
123 self.max_arena_size.load(Ordering::Relaxed)
124 }
125}
126
127pub fn update_avg_u64(running_avg: &AtomicU64, new_value: u64, sample_size: u64) {
128 let avg = running_avg.load(Ordering::Relaxed);
129 let update = new_value.abs_diff(avg) / (sample_size + 1);
130
131 let new_avg = if new_value > avg {
134 avg.saturating_add(update)
135 } else {
136 avg.saturating_sub(update)
137 };
138
139 running_avg.store(new_avg, Ordering::Relaxed);
140}
141
142pub const GC_STATE_SLEEPING: u8 = 0;
143pub const GC_STATE_TRACING: u8 = 1;
144pub const GC_STATE_SWEEPING: u8 = 2;
145#[cfg(feature = "multi_threaded")]
146pub const GC_STATE_WAITING_ON_MUTATORS: u8 = 3;