superluminal_perf/
lib.rs

1//! [Superluminal Performance](https://superluminal.eu/) profiler Rust API for adding user events to captures.
2//!
3//! ## How to use
4//!
5//! In `Cargo.toml` add:
6//!
7//! ```toml
8//! [dependencies]
9//! superluminal-perf = "0.3.0"
10//! ```
11//!
12//! Example usage:
13//!
14//! ```rust
15//! superluminal_perf::begin_event("my-event");
16//! calc();
17//! superluminal_perf::end_event();
18//!
19//! superluminal_perf::begin_event("my-event2");
20//! calc2();
21//! superluminal_perf::end_event();
22//! ```
23//!
24//! On non-Windows platforms the events will be compiled out.
25//!
26//! ## Feature flags
27//!
28//! - `enable` - this flag is used by default and enables calling the Superluminal Performance API. This can be useful to only enable the events only for specific application features
29
30#![allow(unused_variables)]
31#![allow(unsafe_code)]
32
33#[cfg(test)]
34mod test;
35
36#[cfg(all(feature = "enable", target_os = "windows"))]
37use superluminal_perf_sys as ffi;
38
39/// Check if the API is enabled
40pub const fn enabled() -> bool {
41    cfg!(all(feature = "enable", target_os = "windows"))
42}
43
44/// Begin an instrumentation event with the specified ID
45pub fn begin_event(id: &'static str) {
46    #[cfg(all(feature = "enable", target_os = "windows"))]
47    unsafe {
48        ffi::PerformanceAPI_BeginEvent_N(
49            id.as_ptr().cast::<i8>(),
50            id.len() as u16,
51            std::ptr::null(),
52            0,
53            ffi::DEFAULT_COLOR,
54        );
55    }
56}
57
58/// Begin an instrumentation event with the specified ID and color
59pub fn begin_event_with_color(id: &'static str, color: u32) {
60    #[cfg(all(feature = "enable", target_os = "windows"))]
61    unsafe {
62        ffi::PerformanceAPI_BeginEvent_N(
63            id.as_ptr().cast::<i8>(),
64            id.len() as u16,
65            std::ptr::null(),
66            0,
67            color,
68        );
69    }
70}
71
72/// Begin an instrumentation event with the specified ID, runtime data, and color
73///
74/// The data can vary for each invocation of this scope and is intended to hold information that is only available at runtime.
75pub fn begin_event_with_data(id: &'static str, data: &str, color: u32) {
76    #[cfg(all(feature = "enable", target_os = "windows"))]
77    unsafe {
78        ffi::PerformanceAPI_BeginEvent_N(
79            id.as_ptr().cast::<i8>(),
80            id.len() as u16,
81            data.as_ptr().cast::<i8>(),
82            data.len() as u16,
83            color,
84        );
85    }
86}
87
88/// End an instrumentation event.
89///
90/// Must be matched with a call to `begin_event` within the same function
91pub fn end_event() {
92    #[cfg(all(feature = "enable", target_os = "windows"))]
93    unsafe {
94        // PerformanceAPI_EndEvent returns a struct which is only used to prevent calls to it from being tail-call optimized.
95        // We ignore the return value here so the caller of end_event doesn't need to deal with it.
96        let _ = ffi::PerformanceAPI_EndEvent();
97    }
98}
99
100/// Set the name of the current thread
101pub fn set_current_thread_name(name: &str) {
102    #[cfg(all(feature = "enable", target_os = "windows"))]
103    unsafe {
104        ffi::PerformanceAPI_SetCurrentThreadName_N(name.as_ptr().cast::<i8>(), name.len() as u16);
105    }
106}
107
108/// Register a Windows Fiber
109pub fn register_fiber(in_fiber_id: u64) {
110    #[cfg(all(feature = "enable", target_os = "windows"))]
111    unsafe {
112        ffi::PerformanceAPI_RegisterFiber(in_fiber_id);
113    }
114}
115
116/// Unregister a Windows Fiber
117pub fn unregister_fiber(in_fiber_id: u64) {
118    #[cfg(all(feature = "enable", target_os = "windows"))]
119    unsafe {
120        ffi::PerformanceAPI_UnregisterFiber(in_fiber_id);
121    }
122}
123
124/// Begin a Windows Fiber Switch
125///
126/// Must be called before `SwitchToFiber`.
127pub fn begin_fiber_switch(in_current_fiber_id: u64, in_new_fiber_id: u64) {
128    #[cfg(all(feature = "enable", target_os = "windows"))]
129    unsafe {
130        ffi::PerformanceAPI_BeginFiberSwitch(in_current_fiber_id, in_new_fiber_id);
131    }
132}
133
134/// End a Windows Fiber Switch
135///
136/// Must be called after `SwitchToFiber`.
137pub fn end_fiber_switch(in_fiber_id: u64) {
138    #[cfg(all(feature = "enable", target_os = "windows"))]
139    unsafe {
140        ffi::PerformanceAPI_EndFiberSwitch(in_fiber_id);
141    }
142}