From 9c59649e0bb7ca85929e075c923af8461665cc8a Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 4 Apr 2018 11:27:24 -0700 Subject: [PATCH] Revert "Revert "adb: add transport benchmark."" This reverts commit 2ef56a1174be8944e3c10ca5a2520f127a890b3b. host_supported is broken in cc_benchmark on Mac, but we probably don't actually too much about the host benchmarks, so just delete the line. Bug: http://b/77585931 Test: treehugger Change-Id: I8898b4037a3faf8e8dee2a99498a6f84e642b92b --- adb/Android.bp | 29 ++++++ adb/transport_benchmark.cpp | 179 ++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 adb/transport_benchmark.cpp diff --git a/adb/Android.bp b/adb/Android.bp index d81bb4b26..46bc02b2b 100644 --- a/adb/Android.bp +++ b/adb/Android.bp @@ -191,6 +191,35 @@ cc_test_host { }, } +cc_benchmark { + name: "adb_benchmark", + defaults: ["adb_defaults"], + + srcs: ["transport_benchmark.cpp"], + target: { + android: { + static_libs: [ + "libadbd", + ], + }, + host: { + static_libs: [ + "libadb_host", + ], + }, + }, + + static_libs: [ + "libbase", + "libcutils", + "libcrypto_utils", + "libcrypto", + "libdiagnose_usb", + "liblog", + "libusb", + ], +} + cc_binary_host { name: "adb", tags: ["debug"], diff --git a/adb/transport_benchmark.cpp b/adb/transport_benchmark.cpp new file mode 100644 index 000000000..ffe4cbc8d --- /dev/null +++ b/adb/transport_benchmark.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include "adb_trace.h" +#include "sysdeps.h" +#include "transport.h" + +#define ADB_CONNECTION_BENCHMARK(benchmark_name, ...) \ + BENCHMARK_TEMPLATE(benchmark_name, FdConnection, ##__VA_ARGS__) \ + ->Arg(1) \ + ->Arg(16384) \ + ->Arg(MAX_PAYLOAD) \ + ->UseRealTime() + +template +std::unique_ptr MakeConnection(unique_fd fd); + +template <> +std::unique_ptr MakeConnection(unique_fd fd) { + auto fd_connection = std::make_unique(std::move(fd)); + return std::make_unique(std::move(fd_connection)); +} + +template +void BM_Connection_Unidirectional(benchmark::State& state) { + int fds[2]; + if (adb_socketpair(fds) != 0) { + LOG(FATAL) << "failed to create socketpair"; + } + + auto client = MakeConnection(unique_fd(fds[0])); + auto server = MakeConnection(unique_fd(fds[1])); + + std::atomic received_bytes; + + client->SetReadCallback([](Connection*, std::unique_ptr) -> bool { return true; }); + server->SetReadCallback([&received_bytes](Connection*, std::unique_ptr packet) -> bool { + received_bytes += packet->payload.size(); + return true; + }); + + client->SetErrorCallback( + [](Connection*, const std::string& error) { LOG(INFO) << "client closed: " << error; }); + server->SetErrorCallback( + [](Connection*, const std::string& error) { LOG(INFO) << "server closed: " << error; }); + + client->Start(); + server->Start(); + + for (auto _ : state) { + size_t data_size = state.range(0); + std::unique_ptr packet = std::make_unique(); + memset(&packet->msg, 0, sizeof(packet->msg)); + packet->msg.command = A_WRTE; + packet->msg.data_length = data_size; + packet->payload.resize(data_size); + + memset(&packet->payload[0], 0xff, data_size); + + received_bytes = 0; + client->Write(std::move(packet)); + while (received_bytes < data_size) { + continue; + } + } + state.SetBytesProcessed(static_cast(state.iterations()) * state.range(0)); + + client->Stop(); + server->Stop(); +} + +ADB_CONNECTION_BENCHMARK(BM_Connection_Unidirectional); + +enum class ThreadPolicy { + MainThread, + SameThread, +}; + +template +void BM_Connection_Echo(benchmark::State& state) { + int fds[2]; + if (adb_socketpair(fds) != 0) { + LOG(FATAL) << "failed to create socketpair"; + } + + auto client = MakeConnection(unique_fd(fds[0])); + auto server = MakeConnection(unique_fd(fds[1])); + + std::atomic received_bytes; + + fdevent_reset(); + std::thread fdevent_thread([]() { fdevent_loop(); }); + + client->SetReadCallback([&received_bytes](Connection*, std::unique_ptr packet) -> bool { + received_bytes += packet->payload.size(); + return true; + }); + + static const auto handle_packet = [](Connection* connection, std::unique_ptr packet) { + connection->Write(std::move(packet)); + }; + + server->SetReadCallback([](Connection* connection, std::unique_ptr packet) -> bool { + if (Policy == ThreadPolicy::MainThread) { + auto raw_packet = packet.release(); + fdevent_run_on_main_thread([connection, raw_packet]() { + std::unique_ptr packet(raw_packet); + handle_packet(connection, std::move(packet)); + }); + } else { + handle_packet(connection, std::move(packet)); + } + return true; + }); + + client->SetErrorCallback( + [](Connection*, const std::string& error) { LOG(INFO) << "client closed: " << error; }); + server->SetErrorCallback( + [](Connection*, const std::string& error) { LOG(INFO) << "server closed: " << error; }); + + client->Start(); + server->Start(); + + for (auto _ : state) { + size_t data_size = state.range(0); + std::unique_ptr packet = std::make_unique(); + memset(&packet->msg, 0, sizeof(packet->msg)); + packet->msg.command = A_WRTE; + packet->msg.data_length = data_size; + packet->payload.resize(data_size); + + memset(&packet->payload[0], 0xff, data_size); + + received_bytes = 0; + client->Write(std::move(packet)); + while (received_bytes < data_size) { + continue; + } + } + state.SetBytesProcessed(static_cast(state.iterations()) * state.range(0)); + + client->Stop(); + server->Stop(); + + // TODO: Make it so that you don't need to poke the fdevent loop to make it terminate? + fdevent_terminate_loop(); + fdevent_run_on_main_thread([]() {}); + + fdevent_thread.join(); +} + +ADB_CONNECTION_BENCHMARK(BM_Connection_Echo, ThreadPolicy::SameThread); +ADB_CONNECTION_BENCHMARK(BM_Connection_Echo, ThreadPolicy::MainThread); + +int main(int argc, char** argv) { + android::base::SetMinimumLogSeverity(android::base::WARNING); + adb_trace_init(argv); + ::benchmark::Initialize(&argc, argv); + if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; + ::benchmark::RunSpecifiedBenchmarks(); +}