blob: a457e677352ada4bd49909eda3912c7471dc596a [file] [log] [blame]
Steven Morelandcda60852021-04-14 23:45:32 +00001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <BnBinderRpcBenchmark.h>
18#include <android-base/logging.h>
19#include <benchmark/benchmark.h>
20#include <binder/Binder.h>
Steven Morelandcda60852021-04-14 23:45:32 +000021#include <binder/RpcServer.h>
Steven Morelandbdb53ab2021-05-05 17:57:41 +000022#include <binder/RpcSession.h>
Steven Morelandcda60852021-04-14 23:45:32 +000023
24#include <thread>
25
26#include <sys/types.h>
27#include <unistd.h>
28
29using android::BBinder;
30using android::IBinder;
31using android::interface_cast;
32using android::OK;
Steven Morelandcda60852021-04-14 23:45:32 +000033using android::RpcServer;
Steven Morelandbdb53ab2021-05-05 17:57:41 +000034using android::RpcSession;
Steven Morelandcda60852021-04-14 23:45:32 +000035using android::sp;
36using android::binder::Status;
37
38class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
39 Status repeatString(const std::string& str, std::string* out) override {
40 *out = str;
41 return Status::ok();
42 }
43 Status repeatBinder(const sp<IBinder>& str, sp<IBinder>* out) override {
44 *out = str;
45 return Status::ok();
46 }
47};
48
Steven Morelandbdb53ab2021-05-05 17:57:41 +000049static sp<RpcSession> gSession = RpcSession::make();
Steven Morelandcda60852021-04-14 23:45:32 +000050
51void BM_getRootObject(benchmark::State& state) {
52 while (state.KeepRunning()) {
Steven Morelandbdb53ab2021-05-05 17:57:41 +000053 CHECK(gSession->getRootObject() != nullptr);
Steven Morelandcda60852021-04-14 23:45:32 +000054 }
55}
56BENCHMARK(BM_getRootObject);
57
58void BM_pingTransaction(benchmark::State& state) {
Steven Morelandbdb53ab2021-05-05 17:57:41 +000059 sp<IBinder> binder = gSession->getRootObject();
Steven Morelandcda60852021-04-14 23:45:32 +000060 CHECK(binder != nullptr);
61
62 while (state.KeepRunning()) {
63 CHECK_EQ(OK, binder->pingBinder());
64 }
65}
66BENCHMARK(BM_pingTransaction);
67
68void BM_repeatString(benchmark::State& state) {
Steven Morelandbdb53ab2021-05-05 17:57:41 +000069 sp<IBinder> binder = gSession->getRootObject();
Steven Morelandcda60852021-04-14 23:45:32 +000070 CHECK(binder != nullptr);
71 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
72 CHECK(iface != nullptr);
73
74 // Googlers might see go/another-look-at-aidl-hidl-perf
75 //
76 // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
77 // transactions were less than one page in size (system wide during a test
78 // involving media and camera). This is why this diverges from
79 // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
80 // this data on continuous integration. Here we are testing sending a
81 // transaction of twice this size. In other cases, we should focus on
82 // benchmarks of particular usecases. If individual binder transactions like
83 // the ones tested here are fast, then Android performance will be dominated
84 // by how many binder calls work together (and by factors like the scheduler,
85 // thermal throttling, core choice, etc..).
86 std::string str = std::string(getpagesize() * 2, 'a');
87 CHECK_EQ(str.size(), getpagesize() * 2);
88
89 while (state.KeepRunning()) {
90 std::string out;
91 Status ret = iface->repeatString(str, &out);
92 CHECK(ret.isOk()) << ret;
93 }
94}
95BENCHMARK(BM_repeatString);
96
97void BM_repeatBinder(benchmark::State& state) {
Steven Morelandbdb53ab2021-05-05 17:57:41 +000098 sp<IBinder> binder = gSession->getRootObject();
Steven Morelandcda60852021-04-14 23:45:32 +000099 CHECK(binder != nullptr);
100 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
101 CHECK(iface != nullptr);
102
103 while (state.KeepRunning()) {
104 // force creation of a new address
105 sp<IBinder> binder = sp<BBinder>::make();
106
107 sp<IBinder> out;
108 Status ret = iface->repeatBinder(binder, &out);
109 CHECK(ret.isOk()) << ret;
110 }
111}
112BENCHMARK(BM_repeatBinder);
113
114int main(int argc, char** argv) {
115 ::benchmark::Initialize(&argc, argv);
116 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
117
118 std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
119 (void)unlink(addr.c_str());
120
121 std::thread([addr]() {
122 sp<RpcServer> server = RpcServer::make();
123 server->setRootObject(sp<MyBinderRpcBenchmark>::make());
Steven Morelandcda60852021-04-14 23:45:32 +0000124 server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
Steven Moreland611d15f2021-05-01 01:28:27 +0000125 CHECK(server->setupUnixDomainServer(addr.c_str()));
Steven Morelandf137de92021-04-24 01:54:26 +0000126 server->join();
Steven Morelandcda60852021-04-14 23:45:32 +0000127 }).detach();
128
129 for (size_t tries = 0; tries < 5; tries++) {
130 usleep(10000);
Steven Morelandbdb53ab2021-05-05 17:57:41 +0000131 if (gSession->setupUnixDomainClient(addr.c_str())) goto success;
Steven Morelandcda60852021-04-14 23:45:32 +0000132 }
133 LOG(FATAL) << "Could not connect.";
134success:
135
136 ::benchmark::RunSpecifiedBenchmarks();
Steven Moreland3ae982a2021-05-05 18:16:11 +0000137 return 0;
Steven Morelandcda60852021-04-14 23:45:32 +0000138}