timing.rs (1405B)
1 use std::cell::RefCell; 2 use std::rc::Rc; 3 use std::sync::OnceLock; 4 use std::time::Instant; 5 6 use send_wrapper::SendWrapper; 7 8 pub use crate::scope::Scope; 9 10 static GLOBAL_TIMER: OnceLock<SendWrapper<RefCell<Timer>>> = OnceLock::new(); 11 12 pub struct Timer { 13 scopes: Vec<Scope>, 14 level: usize, 15 } 16 17 pub fn register() { 18 let _ = GLOBAL_TIMER.set(SendWrapper::new(RefCell::new(Timer { 19 scopes: vec![], 20 level: 0, 21 }))); 22 } 23 24 pub fn push_scope<S: ToString>(name: S) -> Option<usize> { 25 if let Some(timer) = GLOBAL_TIMER.get() { 26 let level = timer.borrow().level; 27 let mut timer = timer.borrow_mut(); 28 29 timer.scopes.push(Scope { 30 name: name.to_string(), 31 start: Instant::now(), 32 duration: None, 33 level, 34 }); 35 36 let id = timer.scopes.len() - 1; 37 38 timer.level += 1; 39 40 Some(id) 41 } else { 42 None 43 } 44 } 45 46 pub fn pop_scope(id: Option<usize>) { 47 if let Some(timer) = GLOBAL_TIMER.get() { 48 let mut timer = timer.borrow_mut(); 49 50 if let Some(id) = id { 51 let scope = &mut timer.scopes[id]; 52 53 scope.duration = Some(Instant::now() - scope.start); 54 } 55 56 timer.level -= 1; 57 } 58 } 59 60 pub fn get_scopes() -> Rc<[Scope]> { 61 if let Some(timer) = GLOBAL_TIMER.get() { 62 timer.borrow().scopes.clone().into() 63 } else { 64 Rc::from([]) 65 } 66 }