diff options
Diffstat (limited to 'libunwindstack/benchmarks')
-rw-r--r-- | libunwindstack/benchmarks/local_unwind_benchmarks.cpp | 49 | ||||
-rw-r--r-- | libunwindstack/benchmarks/remote_unwind_benchmarks.cpp | 68 |
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); |