tracy: Experiment with tracy fibers

Jakub Konka created

Change summary

Cargo.lock                            |  9 +++++++
Cargo.toml                            |  3 +
crates/file_finder/Cargo.toml         |  2 +
crates/file_finder/src/file_finder.rs | 12 +++++++++
crates/git/Cargo.toml                 |  3 ++
crates/git/src/repository.rs          | 32 +++++++++++++++++++++++++++++
crates/gpui/Cargo.toml                |  1 
crates/gpui/src/executor.rs           | 12 +++++++++
crates/worktree/Cargo.toml            |  2 +
crates/worktree/src/worktree.rs       | 19 +++++++++++++++-
10 files changed, 89 insertions(+), 6 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1460,7 +1460,6 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "log",
- "profiling",
  "simplelog",
  "windows 0.61.1",
  "winresource",
@@ -5917,6 +5916,7 @@ dependencies = [
  "menu",
  "picker",
  "pretty_assertions",
+ "profiling",
  "project",
  "schemars 1.0.1",
  "search",
@@ -5925,6 +5925,7 @@ dependencies = [
  "settings",
  "text",
  "theme",
+ "tracy-client-sys",
  "ui",
  "util",
  "workspace",
@@ -6797,6 +6798,7 @@ dependencies = [
  "log",
  "parking_lot",
  "pretty_assertions",
+ "profiling",
  "rand 0.9.1",
  "regex",
  "rope",
@@ -6809,6 +6811,8 @@ dependencies = [
  "text",
  "thiserror 2.0.12",
  "time",
+ "tracy-client",
+ "tracy-client-sys",
  "unindent",
  "url",
  "util",
@@ -7108,6 +7112,7 @@ dependencies = [
  "sum_tree",
  "taffy",
  "thiserror 2.0.12",
+ "tracy-client-sys",
  "unicode-segmentation",
  "usvg",
  "util",
@@ -19890,6 +19895,7 @@ dependencies = [
  "paths",
  "postage",
  "pretty_assertions",
+ "profiling",
  "rand 0.9.1",
  "rpc",
  "serde",
@@ -19899,6 +19905,7 @@ dependencies = [
  "smol",
  "sum_tree",
  "text",
+ "tracy-client-sys",
  "util",
  "workspace-hack",
  "zlog",

Cargo.toml 🔗

@@ -667,7 +667,8 @@ tokio = { version = "1" }
 tokio-tungstenite = { version = "0.26", features = ["__rustls-tls"] }
 toml = "0.8"
 tower-http = "0.4.4"
-tracy-client = "0.18.2"
+tracy-client = { version = "0.18.2", features = ["fibers"] }
+tracy-client-sys = { version = "0.26.1", features = ["fibers"] }
 tree-sitter = { version = "0.25.10", features = ["wasm"] }
 tree-sitter-bash = "0.25.0"
 tree-sitter-c = "0.23"

crates/file_finder/Cargo.toml 🔗

@@ -33,6 +33,8 @@ ui.workspace = true
 util.workspace = true
 workspace.workspace = true
 workspace-hack.workspace = true
+profiling.workspace = true
+tracy-client-sys.workspace = true
 
 [dev-dependencies]
 ctor.workspace = true

crates/file_finder/src/file_finder.rs 🔗

@@ -122,6 +122,7 @@ impl FileFinder {
         );
     }
 
+    #[profiling::function]
     fn open(
         workspace: &mut Workspace,
         separate_history: bool,
@@ -151,11 +152,20 @@ impl FileFinder {
                 if project.is_local() {
                     let fs = fs.clone();
                     Some(cx.background_spawn(async move {
-                        if fs.is_file(&abs_path).await {
+                        let name =
+                            std::ffi::CString::new("Fiber: recent navigation history").unwrap();
+                        unsafe {
+                            tracy_client_sys::___tracy_fiber_enter(name.as_ptr());
+                        }
+                        let res = if fs.is_file(&abs_path).await {
                             Some(FoundPath::new(project_path, abs_path))
                         } else {
                             None
+                        };
+                        unsafe {
+                            tracy_client_sys::___tracy_fiber_leave();
                         }
+                        res
                     }))
                 } else {
                     Some(Task::ready(Some(FoundPath::new(project_path, abs_path))))

crates/git/Cargo.toml 🔗

@@ -40,6 +40,9 @@ util.workspace = true
 uuid.workspace = true
 futures.workspace = true
 workspace-hack.workspace = true
+profiling.workspace = true
+tracy-client-sys.workspace = true
+tracy-client.workspace = true
 
 [dev-dependencies]
 pretty_assertions.workspace = true

crates/git/src/repository.rs 🔗

@@ -626,6 +626,18 @@ pub async fn get_git_committer(cx: &AsyncApp) -> GitCommitter {
     .await
 }
 
+#[repr(C)]
+#[derive(Copy, Clone)]
+struct ___tracy_source_location_data {
+    pub name: *const ::std::os::raw::c_char,
+    pub function: *const ::std::os::raw::c_char,
+    pub file: *const ::std::os::raw::c_char,
+    pub line: u32,
+    pub color: u32,
+}
+
+unsafe impl Send for ___tracy_source_location_data {}
+
 impl GitRepository for RealGitRepository {
     fn reload_index(&self) {
         if let Ok(mut index) = self.repository.lock().index() {
@@ -681,13 +693,28 @@ impl GitRepository for RealGitRepository {
             .boxed()
     }
 
+    #[profiling::function]
     fn load_commit(&self, commit: String, cx: AsyncApp) -> BoxFuture<'_, Result<CommitDiff>> {
         let Some(working_directory) = self.repository.lock().workdir().map(ToOwned::to_owned)
         else {
             return future::ready(Err(anyhow!("no working directory"))).boxed();
         };
+        dbg!("Load commit");
         let git_binary_path = self.any_git_binary_path.clone();
         cx.background_spawn(async move {
+            let name = std::ffi::CString::new("fiber_load_bytes").unwrap();
+            let loc = ___tracy_source_location_data {
+                name: name.as_ptr(),
+                function: name.as_ptr(),
+                file: name.as_ptr(),
+                line: 0,
+                color: 0,
+            };
+            let zone = unsafe {
+                // tracy_client_sys::___tracy_fiber_enter(name.as_ptr());
+                tracy_client_sys::___tracy_emit_zone_begin(std::mem::transmute(&loc as *const _), 1)
+            };
+
             let show_output = util::command::new_smol_command(&git_binary_path)
                 .current_dir(&working_directory)
                 .args([
@@ -796,6 +823,11 @@ impl GitRepository for RealGitRepository {
                 })
             }
 
+            unsafe {
+                tracy_client_sys::___tracy_emit_zone_end(zone);
+                // tracy_client_sys::___tracy_fiber_leave();
+            }
+
             Ok(CommitDiff { files })
         })
         .boxed()

crates/gpui/Cargo.toml 🔗

@@ -101,6 +101,7 @@ parking = "2.0.0"
 parking_lot.workspace = true
 postage.workspace = true
 profiling.workspace = true
+tracy-client-sys.workspace = true
 rand = { optional = true, workspace = true }
 raw-window-handle = "0.6"
 refineable.workspace = true

crates/gpui/src/executor.rs 🔗

@@ -103,7 +103,17 @@ impl<T> Future for Task<T> {
     fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
         match unsafe { self.get_unchecked_mut() } {
             Task(TaskState::Ready(val)) => Poll::Ready(val.take().unwrap()),
-            Task(TaskState::Spawned(task)) => task.poll(cx),
+            Task(TaskState::Spawned(task)) => {
+                let name = std::ffi::CString::new("Fiber").unwrap();
+                unsafe {
+                    tracy_client_sys::___tracy_fiber_enter(name.as_ptr());
+                }
+                let res = task.poll(cx);
+                unsafe {
+                    tracy_client_sys::___tracy_fiber_leave();
+                }
+                res
+            }
         }
     }
 }

crates/worktree/Cargo.toml 🔗

@@ -37,6 +37,8 @@ log.workspace = true
 parking_lot.workspace = true
 paths.workspace = true
 postage.workspace = true
+profiling.workspace = true
+tracy-client-sys.workspace = true
 rpc = { workspace = true, features = ["gpui"] }
 serde.workspace = true
 serde_json.workspace = true

crates/worktree/src/worktree.rs 🔗

@@ -48,7 +48,7 @@ use std::{
     cmp::Ordering,
     collections::hash_map,
     convert::TryFrom,
-    ffi::OsStr,
+    ffi::{CString, OsStr},
     fmt,
     future::Future,
     mem::{self},
@@ -3084,12 +3084,27 @@ impl language::LocalFile for File {
     }
 
     fn load(&self, cx: &App) -> Task<Result<String>> {
+        profiling::scope!("File::load outer");
+        dbg!("File::load outer");
         let worktree = self.worktree.read(cx).as_local().unwrap();
         let abs_path = worktree.absolutize(&self.path);
         let fs = worktree.fs.clone();
-        cx.background_spawn(async move { fs.load(&abs_path).await })
+
+        cx.background_spawn(async move {
+            dbg!("File::load inner");
+            let name = CString::new("Fiber: load file").unwrap();
+            unsafe {
+                tracy_client_sys::___tracy_fiber_enter(name.as_ptr());
+            }
+            let content = fs.load(&abs_path).await;
+            unsafe {
+                tracy_client_sys::___tracy_fiber_leave();
+            }
+            content
+        })
     }
 
+    #[profiling::function]
     fn load_bytes(&self, cx: &App) -> Task<Result<Vec<u8>>> {
         let worktree = self.worktree.read(cx).as_local().unwrap();
         let abs_path = worktree.absolutize(&self.path);