diff options
author | Nikita Putikhin <nputikhin@google.com> | 2023-07-25 15:29:32 +0000 |
---|---|---|
committer | Nikita Putikhin <nputikhin@google.com> | 2023-07-26 09:20:58 +0000 |
commit | eeb6a4438a48e9da82d8169a900def4d31cf03bc (patch) | |
tree | e34c9cb2c6d66f920f6e4f501b6e7c3218d5078f /libatrace_rust | |
parent | 9223a04f3b4bc65b83b301423e0a8cca8ee6a40f (diff) | |
download | extras-eeb6a4438a48e9da82d8169a900def4d31cf03bc.tar.gz |
Add readme and owners, improve comments
Finishing touches before the library is more or less ready to use.
Bug: 289989828
Test: atrace
Test: Manually collected trace
Change-Id: I0186bbff1417fefde8056a9e8e39055988d1875a
Diffstat (limited to 'libatrace_rust')
-rw-r--r-- | libatrace_rust/OWNERS | 3 | ||||
-rw-r--r-- | libatrace_rust/README.md | 49 | ||||
-rw-r--r-- | libatrace_rust/example/src/main.rs | 32 | ||||
-rw-r--r-- | libatrace_rust/src/lib.rs | 2 |
4 files changed, 79 insertions, 7 deletions
diff --git a/libatrace_rust/OWNERS b/libatrace_rust/OWNERS new file mode 100644 index 00000000..2830d9f3 --- /dev/null +++ b/libatrace_rust/OWNERS @@ -0,0 +1,3 @@ +nputikhin@google.com +dextero@google.com +vill@google.com
\ No newline at end of file diff --git a/libatrace_rust/README.md b/libatrace_rust/README.md new file mode 100644 index 00000000..73385f61 --- /dev/null +++ b/libatrace_rust/README.md @@ -0,0 +1,49 @@ +# libatrace_rust - ATrace bindings for Rust + +Wrapper library for ATrace methods from libcutils. + +## Quick start + +Add the library to your `rustlibs` in `Android.bp`: + +```text +rustlibs: [ + ... + "libatrace_rust", + ... +], +``` + +Call tracing methods: + +```rust +fn important_function() { + // Use this macro to trace a function. + atrace::trace_method!(AtraceTag::App); + + if condition { + // Use a scoped event to trace inside a scope. + let _event = atrace::begin_scoped_event(AtraceTag::App, "Inside a scope"); + ... + } + + // Or just use the wrapped API directly. + atrace::atrace_begin(AtraceTag::App, "My event"); + ... + atrace::atrace_end(AtraceTag::App) +} +``` + +See more in the [example](./example/src/main.rs). + +You're all set! Now you can collect a trace with your favorite tracing tool like +[Perfetto](https://perfetto.dev/docs/data-sources/atrace). + +## Performance + +When tracing is enabled, you can expect 1-10 us per event - this is a significant cost that may +affect the performance of hot high-frequency methods. When the events are disabled, calling them is +cheap - on the order of 5-10 ns. + +There is 10-20% overhead from the wrapper, mostly caused by string conversion when tracing is +enabled. You can find the numbers in [benchmark/README.md](./benchmark/README.md). diff --git a/libatrace_rust/example/src/main.rs b/libatrace_rust/example/src/main.rs index 80a2e919..84e3e470 100644 --- a/libatrace_rust/example/src/main.rs +++ b/libatrace_rust/example/src/main.rs @@ -19,18 +19,31 @@ use std::thread::JoinHandle; use atrace::AtraceTag; fn spawn_async_event() -> JoinHandle<()> { - atrace::atrace_async_begin(AtraceTag::App, "Async task", 12345); - std::thread::spawn(|| { + // Unlike normal events, async events don't need to be nested. + // You need to use the same name and cookie (the last arg) to close the event. + // The cookie must be unique on the name level. + let unique_cookie = 12345; + atrace::atrace_async_begin(AtraceTag::App, "Async task", unique_cookie); + std::thread::spawn(move || { std::thread::sleep(std::time::Duration::from_millis(500)); - atrace::atrace_async_end(AtraceTag::App, "Async task", 12345); + atrace::atrace_async_end(AtraceTag::App, "Async task", unique_cookie); }) } fn spawn_async_event_with_track() -> JoinHandle<()> { - atrace::atrace_async_for_track_begin(AtraceTag::App, "Async track", "Task with track", 12345); - std::thread::spawn(|| { + // Same as `atrace_async_begin` but per track. + // Track name (not event name) and cookie are used to close the event. + // The cookie must be unique on the track level. + let unique_cookie = 12345; + atrace::atrace_async_for_track_begin( + AtraceTag::App, + "Async track", + "Task with track", + unique_cookie, + ); + std::thread::spawn(move || { std::thread::sleep(std::time::Duration::from_millis(600)); - atrace::atrace_async_for_track_end(AtraceTag::App, "Async track", 12345); + atrace::atrace_async_for_track_end(AtraceTag::App, "Async track", unique_cookie); }) } @@ -38,16 +51,20 @@ fn spawn_counter_thread() -> JoinHandle<()> { std::thread::spawn(|| { for i in 1..=10 { std::thread::sleep(std::time::Duration::from_millis(100)); + // Counter events are available for int and int64 to trace values. atrace::atrace_int(AtraceTag::App, "Count of i", i); } }) } fn main() { + // This macro will create a scoped event with the function name used as the event name. atrace::trace_method!(AtraceTag::App); + // The scoped event will be ended when the returned guard is dropped. let _scoped_event = atrace::begin_scoped_event(AtraceTag::App, "Example main"); + // Methods starting with atrace_* are direct wrappers of libcutils methods. let enabled_tags = atrace::atrace_get_enabled_tags(); println!("Enabled tags: {:?}", enabled_tags); @@ -56,9 +73,12 @@ fn main() { let async_event_with_track_handler = spawn_async_event_with_track(); let counter_thread_handler = spawn_counter_thread(); + // Instant events have no duration and don't need to be closed. atrace::atrace_instant(AtraceTag::App, "Instant event"); println!("Calling atrace_begin and sleeping for 1 sec..."); + // If you begin an event you need to close it with the same tag. If you're calling begin + // manually make sure you have a matching end. Or just use a scoped event. atrace::atrace_begin(AtraceTag::App, "Hello tracing!"); std::thread::sleep(std::time::Duration::from_secs(1)); atrace::atrace_end(AtraceTag::App); diff --git a/libatrace_rust/src/lib.rs b/libatrace_rust/src/lib.rs index 7d144483..7eecbf88 100644 --- a/libatrace_rust/src/lib.rs +++ b/libatrace_rust/src/lib.rs @@ -225,7 +225,7 @@ pub fn atrace_async_end(tag: AtraceTag, name: &str, cookie: i32) { /// In addition to the name and a cookie as in `atrace_async_begin`/`atrace_async_end`, a track name /// argument is provided, which is the name of the row where this async event should be recorded. /// -/// The track name, name, and cookie used to begin an event must be used to end it. +/// The track name and cookie used to begin an event must be used to end it. /// /// The cookie here must be unique on the track_name level, not the name level. pub fn atrace_async_for_track_begin(tag: AtraceTag, track_name: &str, name: &str, cookie: i32) { |