1 //! Bindings for the NDK tracing API.
2 //!
3 //! See also [the NDK docs](https://developer.android.com/ndk/reference/group/tracing)
4 #![cfg(feature = "trace")]
5 use std::ffi::{CString, NulError};
6 use std::marker::PhantomData;
7 
is_trace_enabled() -> bool8 pub fn is_trace_enabled() -> bool {
9     unsafe { ffi::ATrace_isEnabled() }
10 }
11 
12 #[derive(Debug)]
13 pub struct Section {
14     // Section is !Sync and !Send
15     _pd: PhantomData<*mut ()>,
16 }
17 
18 impl Section {
new(name: &str) -> Result<Self, NulError>19     pub fn new(name: &str) -> Result<Self, NulError> {
20         let section_name = CString::new(name)?;
21         unsafe { ffi::ATrace_beginSection(section_name.as_ptr()) };
22 
23         Ok(Self { _pd: PhantomData })
24     }
25 
end(self)26     pub fn end(self) {
27         std::mem::drop(self)
28     }
29 }
30 
31 impl Drop for Section {
drop(&mut self)32     fn drop(&mut self) {
33         unsafe { ffi::ATrace_endSection() };
34     }
35 }
36 
37 /// Unique identifier for distinguishing simultaneous events
38 #[derive(Debug)]
39 #[cfg(feature = "api-level-29")]
40 pub struct Cookie(pub i32);
41 
42 #[derive(Debug)]
43 #[cfg(feature = "api-level-29")]
44 pub struct AsyncSection {
45     section_name: CString,
46     cookie: Cookie,
47     // AsyncSection is !Sync
48     _pd: PhantomData<&'static ()>,
49 }
50 
51 #[cfg(feature = "api-level-29")]
52 impl AsyncSection {
new(name: &str, cookie: Cookie) -> Result<Self, NulError>53     pub fn new(name: &str, cookie: Cookie) -> Result<Self, NulError> {
54         let section_name = CString::new(name)?;
55         unsafe { ffi::ATrace_beginAsyncSection(section_name.as_ptr(), cookie.0) };
56 
57         Ok(Self {
58             section_name,
59             cookie,
60             _pd: PhantomData,
61         })
62     }
63 
end(self)64     pub fn end(self) {
65         std::mem::drop(self)
66     }
67 }
68 
69 #[cfg(feature = "api-level-29")]
70 impl Drop for AsyncSection {
drop(&mut self)71     fn drop(&mut self) {
72         unsafe { ffi::ATrace_endAsyncSection(self.section_name.as_ptr(), self.cookie.0) };
73     }
74 }
75 
76 #[cfg(feature = "api-level-29")]
77 #[derive(Debug)]
78 pub struct Counter {
79     name: CString,
80 }
81 
82 #[cfg(feature = "api-level-29")]
83 impl Counter {
new(name: &str) -> Result<Self, NulError>84     pub fn new(name: &str) -> Result<Self, NulError> {
85         let name = CString::new(name)?;
86         Ok(Self { name })
87     }
88 
set_value(&self, value: i64)89     pub fn set_value(&self, value: i64) {
90         unsafe { ffi::ATrace_setCounter(self.name.as_ptr(), value) }
91     }
92 }
93