From f183050b20e621f13eca0f70879dab5a84389e26 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Sat, 2 Apr 2022 17:39:30 -0700 Subject: [PATCH] Non-allocating `span!` macro --- tracy-client/Cargo.toml | 3 ++ tracy-client/src/lib.rs | 96 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/tracy-client/Cargo.toml b/tracy-client/Cargo.toml index ee13e75..4d96295 100644 --- a/tracy-client/Cargo.toml +++ b/tracy-client/Cargo.toml @@ -12,6 +12,9 @@ description = """ High level bindings to the client libraries for the Tracy profiler """ +[dependencies] +once_cell = "1.10" + [dependencies.tracy-client-sys] path = "../tracy-client-sys" version = ">=0.14.0, <0.17.0" # AUTO-UPDATE diff --git a/tracy-client/src/lib.rs b/tracy-client/src/lib.rs index 24d4364..85dcfa2 100644 --- a/tracy-client/src/lib.rs +++ b/tracy-client/src/lib.rs @@ -31,21 +31,66 @@ use tracy_client_sys as sys; #[macro_export] macro_rules! span { ($name:expr) => { - $crate::span!($name, 62) + $crate::span_impl!($name, 62) }; + ($name:expr, $callstack_depth:expr) => { + $crate::span_impl!($name, $callstack_depth) + }; +} + +#[macro_export] +#[doc(hidden)] +#[cfg(feature = "enable")] +macro_rules! span_impl { ($name:expr, $callstack_depth:expr) => {{ + use std::ffi::CString; + use $crate::internal::once_cell::sync::Lazy; + struct S; - let func_name = std::any::type_name::(); - $crate::Span::new( - $name, - &func_name[..func_name.len() - 3], - file!(), - line!(), - $callstack_depth, - ) + static SRC_LOC: Lazy<$crate::internal::SrcLoc> = Lazy::new(|| { + let function_name = std::any::type_name::(); + let function_name = CString::new(&function_name[..function_name.len() - 3]).unwrap(); + $crate::internal::SrcLoc { + data: $crate::internal::sys::___tracy_source_location_data { + name: concat!($name, "\0").as_ptr().cast(), + function: function_name.as_ptr(), + file: concat!(file!(), "\0").as_ptr().cast(), + line: line!(), + color: 0, + }, + _function_name: function_name, + } + }); + unsafe { $crate::Span::from_src_loc(&SRC_LOC.data, $callstack_depth) } }}; } +#[macro_export] +#[doc(hidden)] +#[cfg(not(feature = "enable"))] +macro_rules! span_impl { + ($name:expr, $callstack_depth:expr) => { + $crate::Span::disabled() + }; +} + +#[doc(hidden)] +#[cfg(feature = "enable")] +pub mod internal { + use std::ffi::CString; + + pub use once_cell; + pub use tracy_client_sys as sys; + + pub struct SrcLoc { + pub _function_name: CString, + pub data: sys::___tracy_source_location_data, + } + + unsafe impl Send for SrcLoc {} + unsafe impl Sync for SrcLoc {} +} + /// A handle representing a span of execution. #[cfg(feature="enable")] pub struct Span( @@ -56,8 +101,6 @@ pub struct Span( #[cfg(not(feature="enable"))] pub struct Span(()); - - impl Span { /// Start a new Tracy span. /// @@ -100,6 +143,37 @@ impl Span { } } + #[inline] + #[doc(hidden)] + #[cfg(not(feature = "enable"))] + pub fn disabled() -> Self { + Self(()) + } + + #[inline] + #[doc(hidden)] + #[cfg(feature = "enable")] + pub unsafe fn from_src_loc( + loc: &'static sys::___tracy_source_location_data, + callstack_depth: u16, + ) -> Self { + if callstack_depth == 0 { + Self( + sys::___tracy_emit_zone_begin(loc, 1), + std::marker::PhantomData, + ) + } else { + Self( + sys::___tracy_emit_zone_begin_callstack( + loc, + adjust_stack_depth(callstack_depth).into(), + 1, + ), + std::marker::PhantomData, + ) + } + } + /// Emit a numeric value associated with this span. pub fn emit_value(&self, value: u64) { // SAFE: the only way to construct `Span` is by creating a valid tracy zone context.