gpui_platform/
profiler.rs1use std::sync::{
10 Arc, OnceLock,
11 atomic::{AtomicUsize, Ordering},
12};
13
14#[derive(Clone)]
20pub struct ForegroundRunnableCounter(Arc<AtomicUsize>);
21
22impl ForegroundRunnableCounter {
23 pub fn new() -> Self {
25 Self(Arc::new(AtomicUsize::new(0)))
26 }
27
28 pub fn queued(&self) {
30 self.0.fetch_add(1, Ordering::Release);
31 }
32
33 pub fn finished(&self) {
35 let _ = self
36 .0
37 .fetch_update(Ordering::AcqRel, Ordering::Acquire, |count| {
38 count.checked_sub(1)
39 });
40 }
41
42 pub fn has_runnables(&self) -> bool {
44 self.0.load(Ordering::Acquire) > 0
45 }
46}
47
48impl Default for ForegroundRunnableCounter {
49 fn default() -> Self {
50 Self::new()
51 }
52}
53
54thread_local! {
55 static FOREGROUND_RUNNABLES: ForegroundRunnableCounter = ForegroundRunnableCounter::new();
56}
57
58pub fn foreground_runnable_counter() -> ForegroundRunnableCounter {
60 FOREGROUND_RUNNABLES.with(Clone::clone)
61}
62
63pub fn foreground_runnable_finished() {
65 FOREGROUND_RUNNABLES.with(ForegroundRunnableCounter::finished);
66}
67
68pub type UpdateRunningTaskFn = fn(scheduler::SpawnTime, &'static std::panic::Location<'static>);
70
71pub type SaveTaskTimingFn = fn();
73
74struct TaskProfilerHooks {
75 update_running_task: UpdateRunningTaskFn,
76 save_task_timing: SaveTaskTimingFn,
77}
78
79static TASK_PROFILER_HOOKS: OnceLock<TaskProfilerHooks> = OnceLock::new();
80
81pub fn set_task_profiler(
86 update_running_task: UpdateRunningTaskFn,
87 save_task_timing: SaveTaskTimingFn,
88) {
89 if TASK_PROFILER_HOOKS
90 .set(TaskProfilerHooks {
91 update_running_task,
92 save_task_timing,
93 })
94 .is_err()
95 {
96 log::debug!("task profiler hooks were already installed");
97 }
98}
99
100#[doc(hidden)]
104#[inline]
105pub fn update_running_task(
106 spawned: scheduler::SpawnTime,
107 location: &'static std::panic::Location<'static>,
108) {
109 if let Some(hooks) = TASK_PROFILER_HOOKS.get() {
110 (hooks.update_running_task)(spawned, location);
111 }
112}
113
114#[doc(hidden)]
118#[inline]
119pub fn save_task_timing() {
120 if let Some(hooks) = TASK_PROFILER_HOOKS.get() {
121 (hooks.save_task_timing)();
122 }
123}