1use std::{mem, sync::Mutex};
2
3
4use crate::*;
5
6pub struct TaskTimer {
7 timers: Arc<Mutex<HashMap<String, Duration>>>,
8}
9
10impl TaskTimer {
11 fn new() -> Self {
12 TaskTimer { timers: Arc::new(Mutex::new(HashMap::new())) }
13 }
14
15 fn start_task(&self, task_name: &str) -> TaskGuard {
16 let task_name = task_name.to_string();
17 let timers = Arc::clone(&self.timers);
18 TaskGuard { task_name, timers, start_time: Instant::now() }
19 }
20
21 fn get_duration(&self, task_name: &str) -> Option<Duration> {
22 let timers = self.timers.lock().unwrap();
23 timers.get(task_name).copied()
24 }
25}
26
27pub struct TaskGuard {
28 task_name: String,
29 timers: Arc<Mutex<HashMap<String, Duration>>>,
30 start_time: Instant,
31}
32
33impl Drop for TaskGuard {
34 fn drop(&mut self) {
35 let elapsed = self.start_time.elapsed();
36 let mut timers = self.timers.lock().unwrap();
37 let entry = timers
38 .entry(mem::take(&mut self.task_name))
39 .or_insert(Duration::ZERO);
40 *entry += elapsed;
41 }
42}
43
44lazy_static! {
45 static ref GLOBAL_TASK_TIMER: TaskTimer = TaskTimer::new();
46}
47
48pub fn start_task(task_name: &str) -> TaskGuard {
49 GLOBAL_TASK_TIMER.start_task(task_name)
50}
51
52pub fn get_duration(task_name: &str) -> Option<Duration> {
53 GLOBAL_TASK_TIMER.get_duration(task_name)
54}