scirs2_core/profiling/
memory.rs1use crate::profiling::profiler::Profiler;
4
5pub struct MemoryTracker {
7 name: String,
9 start_memory: usize,
11 running: bool,
13 auto_report: bool,
15}
16
17impl MemoryTracker {
18 pub fn start(name: &str) -> Self {
20 let current_memory = Self::current_memory_usage();
21 let tracker = Self {
22 name: name.to_string(),
23 start_memory: current_memory,
24 running: true,
25 auto_report: true,
26 };
27 if let Ok(mut profiler) = Profiler::global().lock() {
28 profiler.register_memory_tracker_start(&tracker);
29 }
30 tracker
31 }
32
33 pub fn stop(&self) {
35 if !self.running {
36 return;
37 }
38
39 let current_memory = Self::current_memory_usage();
40 let memory_delta = current_memory.saturating_sub(self.start_memory);
41 if let Ok(mut profiler) = Profiler::global().lock() {
42 profiler.register_memory_tracker_stop(&self.name, memory_delta);
43 }
44 }
45
46 pub fn track_function<F, R>(name: &str, f: F) -> R
48 where
49 F: FnOnce() -> R,
50 {
51 let tracker = Self::start(name);
52 let result = f();
53 tracker.stop();
54 result
55 }
56
57 pub fn memory_delta(&self) -> isize {
59 let current_memory = Self::current_memory_usage();
60 current_memory as isize - self.start_memory as isize
61 }
62
63 pub fn without_auto_report(mut self) -> Self {
65 self.auto_report = false;
66 self
67 }
68
69 pub fn name(&self) -> &str {
71 &self.name
72 }
73
74 pub fn start_memory(&self) -> usize {
76 self.start_memory
77 }
78
79 pub fn is_running(&self) -> bool {
81 self.running
82 }
83
84 fn current_memory_usage() -> usize {
86 #[cfg(target_os = "linux")]
89 {
90 0
92 }
93
94 #[cfg(target_os = "macos")]
95 {
96 0
98 }
99
100 #[cfg(target_os = "windows")]
101 {
102 0
104 }
105
106 #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
107 {
108 0
110 }
111 }
112}
113
114impl Drop for MemoryTracker {
115 fn drop(&mut self) {
116 if self.running && self.auto_report {
117 let current_memory = Self::current_memory_usage();
118 let memory_delta = current_memory.saturating_sub(self.start_memory);
119 if let Ok(mut profiler) = Profiler::global().lock() {
120 profiler.register_memory_tracker_stop(&self.name, memory_delta);
121 }
122 }
123 }
124}
125
126#[allow(dead_code)]
128pub fn profiling_memory_tracker() -> &'static MemoryTracker {
129 static MEMORY_TRACKER: once_cell::sync::Lazy<MemoryTracker> =
131 once_cell::sync::Lazy::new(|| MemoryTracker {
132 name: "global".to_string(),
133 start_memory: 0,
134 running: false,
135 auto_report: false,
136 });
137 &MEMORY_TRACKER
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn test_memory_tracker_basic() {
146 let tracker = MemoryTracker::start("test_memory");
147 tracker.stop();
148 }
150}