blob: e430c28a3b41eeb03d8136b15a103be7fece7736 [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 Moreland1ebdc702021-07-28 18:46:15 -070021#include <binder/IPCThreadState.h>
22#include <binder/IServiceManager.h>
23#include <binder/ProcessState.h>
Steven Morelandcda60852021-04-14 23:45:32 +000024#include <binder/RpcServer.h>
Steven Morelandbdb53ab2021-05-05 17:57:41 +000025#include <binder/RpcSession.h>
Steven Morelandcda60852021-04-14 23:45:32 +000026
27#include <thread>
28
Steven Moreland656e9d12021-07-29 17:33:53 -070029#include <signal.h>
Steven Moreland1ebdc702021-07-28 18:46:15 -070030#include <sys/prctl.h>
Steven Morelandcda60852021-04-14 23:45:32 +000031#include <sys/types.h>
32#include <unistd.h>
33
34using android::BBinder;
Steven Moreland1ebdc702021-07-28 18:46:15 -070035using android::defaultServiceManager;
Steven Morelandcda60852021-04-14 23:45:32 +000036using android::IBinder;
37using android::interface_cast;
Steven Moreland1ebdc702021-07-28 18:46:15 -070038using android::IPCThreadState;
39using android::IServiceManager;
Steven Morelandcda60852021-04-14 23:45:32 +000040using android::OK;
Steven Moreland1ebdc702021-07-28 18:46:15 -070041using android::ProcessState;
Steven Morelandcda60852021-04-14 23:45:32 +000042using android::RpcServer;
Steven Morelandbdb53ab2021-05-05 17:57:41 +000043using android::RpcSession;
Steven Morelandcda60852021-04-14 23:45:32 +000044using android::sp;
Steven Moreland2372f9d2021-08-05 15:42:01 -070045using android::status_t;
46using android::statusToString;
Steven Moreland1ebdc702021-07-28 18:46:15 -070047using android::String16;
Steven Morelandcda60852021-04-14 23:45:32 +000048using android::binder::Status;
49
50class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
51 Status repeatString(const std::string& str, std::string* out) override {
52 *out = str;
53 return Status::ok();
54 }
Steven Morelandce240ce2021-08-05 13:02:37 -070055 Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
56 *out = binder;
57 return Status::ok();
58 }
59 Status repeatBytes(const std::vector<uint8_t>& bytes, std::vector<uint8_t>* out) override {
60 *out = bytes;
Steven Morelandcda60852021-04-14 23:45:32 +000061 return Status::ok();
62 }
63};
64
Steven Moreland1ebdc702021-07-28 18:46:15 -070065enum Transport {
66 KERNEL,
67 RPC,
68};
Steven Morelandcda60852021-04-14 23:45:32 +000069
Steven Morelandce240ce2021-08-05 13:02:37 -070070static const std::initializer_list<int64_t> kTransportList = {
Steven Moreland1ebdc702021-07-28 18:46:15 -070071#ifdef __BIONIC__
Steven Morelandce240ce2021-08-05 13:02:37 -070072 Transport::KERNEL,
Steven Moreland1ebdc702021-07-28 18:46:15 -070073#endif
Steven Morelandce240ce2021-08-05 13:02:37 -070074 Transport::RPC};
Steven Moreland1ebdc702021-07-28 18:46:15 -070075
76static sp<RpcSession> gSession = RpcSession::make();
77#ifdef __BIONIC__
78static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
79static sp<IBinder> gKernelBinder;
80#endif
81
82static sp<IBinder> getBinderForOptions(benchmark::State& state) {
83 Transport transport = static_cast<Transport>(state.range(0));
84 switch (transport) {
85#ifdef __BIONIC__
86 case KERNEL:
87 return gKernelBinder;
88#endif
89 case RPC:
90 return gSession->getRootObject();
91 default:
92 LOG(FATAL) << "Unknown transport value: " << transport;
93 return nullptr;
Steven Morelandcda60852021-04-14 23:45:32 +000094 }
95}
Steven Morelandcda60852021-04-14 23:45:32 +000096
97void BM_pingTransaction(benchmark::State& state) {
Steven Moreland1ebdc702021-07-28 18:46:15 -070098 sp<IBinder> binder = getBinderForOptions(state);
Steven Morelandcda60852021-04-14 23:45:32 +000099
100 while (state.KeepRunning()) {
101 CHECK_EQ(OK, binder->pingBinder());
102 }
103}
Steven Morelandce240ce2021-08-05 13:02:37 -0700104BENCHMARK(BM_pingTransaction)->ArgsProduct({kTransportList});
Steven Morelandcda60852021-04-14 23:45:32 +0000105
Steven Morelandce240ce2021-08-05 13:02:37 -0700106void BM_repeatTwoPageString(benchmark::State& state) {
Steven Moreland1ebdc702021-07-28 18:46:15 -0700107 sp<IBinder> binder = getBinderForOptions(state);
108
Steven Morelandcda60852021-04-14 23:45:32 +0000109 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
110 CHECK(iface != nullptr);
111
112 // Googlers might see go/another-look-at-aidl-hidl-perf
113 //
114 // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
115 // transactions were less than one page in size (system wide during a test
116 // involving media and camera). This is why this diverges from
117 // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
118 // this data on continuous integration. Here we are testing sending a
119 // transaction of twice this size. In other cases, we should focus on
120 // benchmarks of particular usecases. If individual binder transactions like
121 // the ones tested here are fast, then Android performance will be dominated
122 // by how many binder calls work together (and by factors like the scheduler,
123 // thermal throttling, core choice, etc..).
124 std::string str = std::string(getpagesize() * 2, 'a');
125 CHECK_EQ(str.size(), getpagesize() * 2);
126
127 while (state.KeepRunning()) {
128 std::string out;
129 Status ret = iface->repeatString(str, &out);
130 CHECK(ret.isOk()) << ret;
131 }
132}
Steven Morelandce240ce2021-08-05 13:02:37 -0700133BENCHMARK(BM_repeatTwoPageString)->ArgsProduct({kTransportList});
134
135void BM_throughputForTransportAndBytes(benchmark::State& state) {
136 sp<IBinder> binder = getBinderForOptions(state);
137 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
138 CHECK(iface != nullptr);
139
140 std::vector<uint8_t> bytes = std::vector<uint8_t>(state.range(1));
141 for (size_t i = 0; i < bytes.size(); i++) {
142 bytes[i] = i % 256;
143 }
144
145 while (state.KeepRunning()) {
146 std::vector<uint8_t> out;
147 Status ret = iface->repeatBytes(bytes, &out);
148 CHECK(ret.isOk()) << ret;
149 }
150}
151BENCHMARK(BM_throughputForTransportAndBytes)
152 ->ArgsProduct({kTransportList,
153 {64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}});
Steven Morelandcda60852021-04-14 23:45:32 +0000154
155void BM_repeatBinder(benchmark::State& state) {
Steven Morelandb9c49622021-08-10 17:39:10 -0700156 sp<IBinder> binder = getBinderForOptions(state);
Steven Morelandcda60852021-04-14 23:45:32 +0000157 CHECK(binder != nullptr);
158 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
159 CHECK(iface != nullptr);
160
161 while (state.KeepRunning()) {
162 // force creation of a new address
163 sp<IBinder> binder = sp<BBinder>::make();
164
165 sp<IBinder> out;
166 Status ret = iface->repeatBinder(binder, &out);
167 CHECK(ret.isOk()) << ret;
168 }
169}
Steven Morelandce240ce2021-08-05 13:02:37 -0700170BENCHMARK(BM_repeatBinder)->ArgsProduct({kTransportList});
Steven Morelandcda60852021-04-14 23:45:32 +0000171
172int main(int argc, char** argv) {
173 ::benchmark::Initialize(&argc, argv);
174 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
175
176 std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
177 (void)unlink(addr.c_str());
178
Steven Moreland1ebdc702021-07-28 18:46:15 -0700179 std::cerr << "Tests suffixes:" << std::endl;
Steven Morelandce240ce2021-08-05 13:02:37 -0700180 std::cerr << "\t.../" << Transport::KERNEL << " is KERNEL" << std::endl;
181 std::cerr << "\t.../" << Transport::RPC << " is RPC" << std::endl;
Steven Moreland1ebdc702021-07-28 18:46:15 -0700182
Steven Moreland656e9d12021-07-29 17:33:53 -0700183 if (0 == fork()) {
184 prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
185 sp<RpcServer> server = RpcServer::make();
186 server->setRootObject(sp<MyBinderRpcBenchmark>::make());
187 server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
Steven Moreland2372f9d2021-08-05 15:42:01 -0700188 CHECK_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
Steven Moreland656e9d12021-07-29 17:33:53 -0700189 server->join();
190 exit(1);
191 }
192
Steven Moreland1ebdc702021-07-28 18:46:15 -0700193#ifdef __BIONIC__
194 if (0 == fork()) {
195 prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
196 CHECK_EQ(OK,
197 defaultServiceManager()->addService(kKernelBinderInstance,
198 sp<MyBinderRpcBenchmark>::make()));
199 IPCThreadState::self()->joinThreadPool();
Steven Moreland656e9d12021-07-29 17:33:53 -0700200 exit(1);
Steven Moreland1ebdc702021-07-28 18:46:15 -0700201 }
202
203 ProcessState::self()->setThreadPoolMaxThreadCount(1);
204 ProcessState::self()->startThreadPool();
205
206 gKernelBinder = defaultServiceManager()->waitForService(kKernelBinderInstance);
207 CHECK_NE(nullptr, gKernelBinder.get());
208#endif
209
Steven Moreland2372f9d2021-08-05 15:42:01 -0700210 status_t status;
Steven Morelandcda60852021-04-14 23:45:32 +0000211 for (size_t tries = 0; tries < 5; tries++) {
212 usleep(10000);
Steven Moreland2372f9d2021-08-05 15:42:01 -0700213 status = gSession->setupUnixDomainClient(addr.c_str());
214 if (status == OK) goto success;
Steven Morelandcda60852021-04-14 23:45:32 +0000215 }
Steven Moreland2372f9d2021-08-05 15:42:01 -0700216 LOG(FATAL) << "Could not connect: " << statusToString(status).c_str();
Steven Morelandcda60852021-04-14 23:45:32 +0000217success:
218
219 ::benchmark::RunSpecifiedBenchmarks();
Steven Moreland3ae982a2021-05-05 18:16:11 +0000220 return 0;
Steven Morelandcda60852021-04-14 23:45:32 +0000221}