summaryrefslogtreecommitdiff
path: root/libatrace_rust
diff options
context:
space:
mode:
authorNikita Putikhin <nputikhin@google.com>2023-07-25 15:29:32 +0000
committerNikita Putikhin <nputikhin@google.com>2023-07-26 09:20:58 +0000
commiteeb6a4438a48e9da82d8169a900def4d31cf03bc (patch)
treee34c9cb2c6d66f920f6e4f501b6e7c3218d5078f /libatrace_rust
parent9223a04f3b4bc65b83b301423e0a8cca8ee6a40f (diff)
downloadextras-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/OWNERS3
-rw-r--r--libatrace_rust/README.md49
-rw-r--r--libatrace_rust/example/src/main.rs32
-rw-r--r--libatrace_rust/src/lib.rs2
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) {