turbo_tasks/
task_statistics.rs1use std::sync::{Arc, OnceLock};
2
3use serde::{Serialize, Serializer, ser::SerializeMap};
4
5use crate::{FxDashMap, macro_helpers::NativeFunction};
6
7#[derive(Default)]
9pub struct TaskStatisticsApi {
10 inner: OnceLock<Arc<TaskStatistics>>,
11}
12
13impl TaskStatisticsApi {
14 pub fn enable(&self) -> &Arc<TaskStatistics> {
15 self.inner.get_or_init(|| {
16 Arc::new(TaskStatistics {
17 inner: FxDashMap::with_hasher(Default::default()),
18 })
19 })
20 }
21
22 pub fn map<T>(&self, func: impl FnOnce(&Arc<TaskStatistics>) -> T) -> Option<T> {
25 self.get().map(func)
26 }
27
28 pub fn get(&self) -> Option<&Arc<TaskStatistics>> {
31 self.inner.get()
32 }
33}
34
35pub struct TaskStatistics {
37 inner: FxDashMap<&'static NativeFunction, TaskFunctionStatistics>,
38}
39
40impl TaskStatistics {
41 pub fn increment_cache_hit(&self, native_fn: &'static NativeFunction) {
42 self.with_task_type_statistics(native_fn, |stats| stats.cache_hit += 1)
43 }
44
45 pub fn increment_cache_miss(&self, native_fn: &'static NativeFunction) {
46 self.with_task_type_statistics(native_fn, |stats| stats.cache_miss += 1)
47 }
48
49 pub fn increment_execution_duration(
50 &self,
51 native_fn: &'static NativeFunction,
52 duration: std::time::Duration,
53 ) {
54 self.with_task_type_statistics(native_fn, |stats| {
55 stats.executions += 1;
56 stats.duration += duration
57 })
58 }
59
60 fn with_task_type_statistics(
61 &self,
62 native_fn: &'static NativeFunction,
63 func: impl Fn(&mut TaskFunctionStatistics),
64 ) {
65 func(self.inner.entry(native_fn).or_default().value_mut())
66 }
67
68 pub fn get(&self, f: &'static NativeFunction) -> TaskFunctionStatistics {
69 self.inner.get(f).unwrap().value().clone()
70 }
71}
72
73#[derive(Default, Serialize, Clone)]
75pub struct TaskFunctionStatistics {
76 pub cache_hit: u32,
77 pub cache_miss: u32,
78 pub executions: u32,
81 pub duration: std::time::Duration,
82}
83
84impl Serialize for TaskStatistics {
85 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86 where
87 S: Serializer,
88 {
89 let mut map = serializer.serialize_map(Some(self.inner.len()))?;
90 for entry in &self.inner {
91 map.serialize_entry(entry.key().global_name, entry.value())?;
92 }
93 map.end()
94 }
95}