summaryrefslogtreecommitdiff
path: root/libunwindstack/benchmarks
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/benchmarks')
-rw-r--r--libunwindstack/benchmarks/local_unwind_benchmarks.cpp49
-rw-r--r--libunwindstack/benchmarks/remote_unwind_benchmarks.cpp68
2 files changed, 98 insertions, 19 deletions
diff --git a/libunwindstack/benchmarks/local_unwind_benchmarks.cpp b/libunwindstack/benchmarks/local_unwind_benchmarks.cpp
index dd12ab5..78c8c13 100644
--- a/libunwindstack/benchmarks/local_unwind_benchmarks.cpp
+++ b/libunwindstack/benchmarks/local_unwind_benchmarks.cpp
@@ -22,6 +22,7 @@
#include <android-base/strings.h>
+#include <unwindstack/AndroidUnwinder.h>
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>
#include <unwindstack/Regs.h>
@@ -99,6 +100,54 @@ static void BM_local_unwind_cached_process_memory(benchmark::State& state) {
}
BENCHMARK(BM_local_unwind_cached_process_memory);
+static void BM_local_android_unwind_uncached_process_memory(benchmark::State& state) {
+ auto process_memory = unwindstack::Memory::CreateProcessMemory(getpid());
+ unwindstack::AndroidLocalUnwinder unwinder(process_memory);
+ unwindstack::ErrorData error;
+ if (!unwinder.Initialize(error)) {
+ state.SkipWithError("Failed to initialize.");
+ }
+
+ for (auto _ : state) {
+ if (LocalCall1(
+ [](void* u) -> size_t {
+ unwindstack::AndroidLocalUnwinder* unwinder =
+ reinterpret_cast<unwindstack::AndroidLocalUnwinder*>(u);
+ unwindstack::AndroidUnwinderData data;
+ unwinder->Unwind(data);
+ return data.frames.size();
+ },
+ &unwinder) < 5) {
+ state.SkipWithError("Failed to unwind.");
+ }
+ }
+}
+BENCHMARK(BM_local_android_unwind_uncached_process_memory);
+
+static void BM_local_android_unwind_cached_process_memory(benchmark::State& state) {
+ auto process_memory = unwindstack::Memory::CreateProcessMemoryCached(getpid());
+ unwindstack::AndroidLocalUnwinder unwinder(process_memory);
+ unwindstack::ErrorData error;
+ if (!unwinder.Initialize(error)) {
+ state.SkipWithError("Failed to initialize.");
+ }
+
+ for (auto _ : state) {
+ if (LocalCall1(
+ [](void* u) -> size_t {
+ unwindstack::AndroidLocalUnwinder* unwinder =
+ reinterpret_cast<unwindstack::AndroidLocalUnwinder*>(u);
+ unwindstack::AndroidUnwinderData data;
+ unwinder->Unwind(data);
+ return data.frames.size();
+ },
+ &unwinder) < 5) {
+ state.SkipWithError("Failed to unwind.");
+ }
+ }
+}
+BENCHMARK(BM_local_android_unwind_cached_process_memory);
+
static void BM_local_unwind_local_updatable_maps_uncached(benchmark::State& state) {
auto process_memory = unwindstack::Memory::CreateProcessMemory(getpid());
unwindstack::LocalUpdatableMaps maps;
diff --git a/libunwindstack/benchmarks/remote_unwind_benchmarks.cpp b/libunwindstack/benchmarks/remote_unwind_benchmarks.cpp
index ef07e39..29c416d 100644
--- a/libunwindstack/benchmarks/remote_unwind_benchmarks.cpp
+++ b/libunwindstack/benchmarks/remote_unwind_benchmarks.cpp
@@ -24,35 +24,26 @@
#include <benchmark/benchmark.h>
+#include <unwindstack/AndroidUnwinder.h>
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>
#include <unwindstack/Regs.h>
#include <unwindstack/Unwinder.h>
#include "MemoryRemote.h"
+#include "PidUtils.h"
#include "tests/TestUtils.h"
static bool WaitForRemote(pid_t pid, volatile bool* ready_ptr) {
- usleep(1000);
- for (size_t i = 0; i < 1000; i++) {
- if (ptrace(PTRACE_ATTACH, pid, 0, 0) == 0) {
- unwindstack::TestQuiescePid(pid);
-
- unwindstack::MemoryRemote memory(pid);
- bool ready;
- uint64_t ready_addr = reinterpret_cast<uint64_t>(ready_ptr);
- if (memory.ReadFully(ready_addr, &ready, sizeof(ready)) && ready) {
- return true;
- }
- } else if (errno != ESRCH) {
- // Attach failed with unknown error.
- perror("Ptrace failed:");
- return false;
+ return unwindstack::RunWhenQuiesced(pid, true, [pid, ready_ptr]() {
+ unwindstack::MemoryRemote memory(pid);
+ bool ready;
+ uint64_t ready_addr = reinterpret_cast<uint64_t>(ready_ptr);
+ if (memory.ReadFully(ready_addr, &ready, sizeof(ready)) && ready) {
+ return unwindstack::PID_RUN_PASS;
}
- usleep(5000);
- }
- printf("Pid %d did not quiesce in a timely fashion.\n", pid);
- return false;
+ return unwindstack::PID_RUN_KEEP_GOING;
+ });
}
size_t RemoteCall6(volatile bool* ready) {
@@ -141,3 +132,42 @@ static void BM_remote_unwind_cached(benchmark::State& state) {
RemoteUnwind(state, true);
}
BENCHMARK(BM_remote_unwind_cached);
+
+static void RemoteAndroidUnwind(benchmark::State& state, bool cached) {
+ pid_t pid = StartRemoteRun();
+ if (pid == -1) {
+ state.SkipWithError("Failed to start remote process.");
+ }
+ unwindstack::TestScopedPidReaper reap(pid);
+
+ std::shared_ptr<unwindstack::Memory> process_memory;
+ if (cached) {
+ process_memory = unwindstack::Memory::CreateProcessMemoryCached(pid);
+ } else {
+ process_memory = unwindstack::Memory::CreateProcessMemory(pid);
+ }
+ unwindstack::AndroidRemoteUnwinder unwinder(pid, process_memory);
+ unwindstack::ErrorData error;
+ if (!unwinder.Initialize(error)) {
+ state.SkipWithError("Failed to initialize unwinder.");
+ }
+
+ for (auto _ : state) {
+ unwindstack::AndroidUnwinderData data;
+ if (!unwinder.Unwind(data) || data.frames.size() < 5) {
+ state.SkipWithError("Failed to unwind properly.");
+ }
+ }
+
+ ptrace(PTRACE_DETACH, pid, 0, 0);
+}
+
+static void BM_remote_android_unwind_uncached(benchmark::State& state) {
+ RemoteAndroidUnwind(state, true);
+}
+BENCHMARK(BM_remote_android_unwind_uncached);
+
+static void BM_remote_android_unwind_cached(benchmark::State& state) {
+ RemoteAndroidUnwind(state, true);
+}
+BENCHMARK(BM_remote_android_unwind_cached);