remotery/
lib.rs

1//! Remotery is a realtime CPU/GPU profiler with a viewer that runs in a web browser.
2//! This lib is a [Rust](https://www.rust-lang.org) wrapper around the C API provided by Remotery and the original
3//! repo over here https://github.com/Celtoys/Remotery
4//!
5pub mod error;
6mod remotery_ffi;
7mod cfixed_string;
8use std::ptr;
9use std::os::raw::c_void;
10use error::RemoteryError;
11use cfixed_string::CFixedString;
12
13/// Holds the main instance for Remotery
14pub struct Remotery {
15    instance: *mut c_void,
16}
17
18#[derive(Clone, Copy)]
19/// Sample flags to decide how profiling info should be handled
20pub enum SampleFlags {
21    /// Default behaviour
22	Default,
23    /// Search parent for same-named samples and merge timing instead of adding a new sample
24	Aggregate,
25}
26
27impl Remotery {
28	/// Creates the global instance (with in the C lib that this code wraps) this code needs to be
29	/// called before any of the other code is being called and the instance will be dropped when
30	/// it goes out of scope so it's suggested to call this early in the main entry point of your
31	/// program (such as ``main``)
32	///
33	/// # Examples
34	///
35	/// ```ignore
36    /// let _remotery = Remotery::create_global_instance().unwrap_or_else(|e| {
37    ///  	panic!(e);
38	/// });
39	/// ```
40	///
41    pub fn create_global_instance() -> Result<Remotery, RemoteryError> {
42        let mut instance = 0 as *mut c_void;
43
44        let res = unsafe {
45            remotery_ffi::_rmt_CreateGlobalInstance(&mut instance)
46        };
47
48        if res != 0 {
49            return Err(error::get_error(res));
50        }
51
52        Ok(Remotery { instance: instance })
53    }
54
55    ///
56    /// Begin a cpu sample. Notice that this call needs to be paired with ``end_cpu_sample``.
57    /// It's also possible to use ```RemoteryScope``` that will call end_cpu_scope when the scop ends.
58    ///
59	/// # Examples
60	/// ```ignore
61    /// Remotery::begin_cpu_sample("my_function", SampleFlags::Default);
62    /// // some code to profile here
63    /// Remotery::end_cpu_sample();
64    /// ```
65    ///
66    pub fn begin_cpu_sample(name: &str, flags: SampleFlags) {
67        // TODO: As we send 0 as last parameter which is hash caching this will always recalculate
68        // the hash which adds some slight overhead. Would be nice if that could be solved somehow.
69        unsafe {
70            let temp_str = CFixedString::from_str(name);
71            remotery_ffi::_rmt_BeginCPUSample(temp_str.as_ptr(), flags as u32, ptr::null_mut());
72        }
73    }
74
75    /// Ends a cpu sample. Notice that this needs to be paired with ``begin_cpu_sample`` as seen above.
76    pub fn end_cpu_sample() {
77        unsafe {
78            remotery_ffi::_rmt_EndCPUSample();
79        }
80    }
81
82    /// Setts the name of the current thread that makes it easier to identify it in the Remotery UI
83    ///
84    /// # Examples
85    ///
86    /// ```ignore
87    /// Remotery::set_current_thread_name("my_thread_name");
88    /// ```
89    ///
90    pub fn set_current_thread_name(name: &str) {
91        unsafe {
92            let temp_str = CFixedString::from_str(name);
93            remotery_ffi::_rmt_SetCurrentThreadName(temp_str.as_ptr());
94        }
95    }
96
97    ///
98    /// Can be used to log text to the remotery ui
99    ///
100    pub fn log_text(text: &str) {
101        unsafe {
102            let temp_str = CFixedString::from_str(text);
103            remotery_ffi::_rmt_LogText(temp_str.as_ptr());
104        }
105    }
106}
107
108/// Scopes allows you to profile a bit of code and the end_cpu_sample will be called once it goes out of scope
109pub struct RemoteryScope;
110
111impl RemoteryScope {
112	///
113	/// Begin a new Scope which auto calls ``end_cpu_scope`` once the scope ends
114	///
115    /// # Examples
116    ///
117    /// ```ignore
118    /// let _scope = RemoteryScope::new("my_function", SampleFlags::Default);
119    /// ```
120    pub fn new(name: &str, flags: SampleFlags) -> RemoteryScope {
121        Remotery::begin_cpu_sample(name, flags);
122        RemoteryScope {}
123    }
124}
125
126impl Drop for RemoteryScope {
127    fn drop(&mut self) {
128        Remotery::end_cpu_sample()
129    }
130}
131
132impl Drop for Remotery {
133    fn drop(&mut self) {
134        if self.instance == ptr::null_mut() {
135            return
136        }
137
138        unsafe {
139            remotery_ffi::_rmt_DestroyGlobalInstance(self.instance);
140        }
141    }
142}
143