blob: 26a0b90977ede11095a63c207658ee287e16313f [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 Moreland1ebdc702021-07-28 18:46:15 -070029#include <sys/prctl.h>
Steven Morelandcda60852021-04-14 23:45:32 +000030#include <sys/types.h>
31#include <unistd.h>
32
33using android::BBinder;
Steven Moreland1ebdc702021-07-28 18:46:15 -070034using android::defaultServiceManager;
Steven Morelandcda60852021-04-14 23:45:32 +000035using android::IBinder;
36using android::interface_cast;
Steven Moreland1ebdc702021-07-28 18:46:15 -070037using android::IPCThreadState;
38using android::IServiceManager;
Steven Morelandcda60852021-04-14 23:45:32 +000039using android::OK;
Steven Moreland1ebdc702021-07-28 18:46:15 -070040using android::ProcessState;
Steven Morelandcda60852021-04-14 23:45:32 +000041using android::RpcServer;
Steven Morelandbdb53ab2021-05-05 17:57:41 +000042using android::RpcSession;
Steven Morelandcda60852021-04-14 23:45:32 +000043using android::sp;
Steven Moreland1ebdc702021-07-28 18:46:15 -070044using android::String16;
Steven Morelandcda60852021-04-14 23:45:32 +000045using android::binder::Status;
46
47class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
48 Status repeatString(const std::string& str, std::string* out) override {
49 *out = str;
50 return Status::ok();
51 }
52 Status repeatBinder(const sp<IBinder>& str, sp<IBinder>* out) override {
53 *out = str;
54 return Status::ok();
55 }
56};
57
Steven Moreland1ebdc702021-07-28 18:46:15 -070058enum Transport {
59 KERNEL,
60 RPC,
61};
Steven Morelandcda60852021-04-14 23:45:32 +000062
Steven Moreland1ebdc702021-07-28 18:46:15 -070063static void EachTransport(benchmark::internal::Benchmark* b) {
64#ifdef __BIONIC__
65 b->Args({Transport::KERNEL});
66#endif
67 b->Args({Transport::RPC});
68}
69
70static sp<RpcSession> gSession = RpcSession::make();
71#ifdef __BIONIC__
72static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
73static sp<IBinder> gKernelBinder;
74#endif
75
76static sp<IBinder> getBinderForOptions(benchmark::State& state) {
77 Transport transport = static_cast<Transport>(state.range(0));
78 switch (transport) {
79#ifdef __BIONIC__
80 case KERNEL:
81 return gKernelBinder;
82#endif
83 case RPC:
84 return gSession->getRootObject();
85 default:
86 LOG(FATAL) << "Unknown transport value: " << transport;
87 return nullptr;
Steven Morelandcda60852021-04-14 23:45:32 +000088 }
89}
Steven Morelandcda60852021-04-14 23:45:32 +000090
91void BM_pingTransaction(benchmark::State& state) {
Steven Moreland1ebdc702021-07-28 18:46:15 -070092 sp<IBinder> binder = getBinderForOptions(state);
Steven Morelandcda60852021-04-14 23:45:32 +000093
94 while (state.KeepRunning()) {
95 CHECK_EQ(OK, binder->pingBinder());
96 }
97}
Steven Moreland1ebdc702021-07-28 18:46:15 -070098BENCHMARK(BM_pingTransaction)->Apply(EachTransport);
Steven Morelandcda60852021-04-14 23:45:32 +000099
100void BM_repeatString(benchmark::State& state) {
Steven Moreland1ebdc702021-07-28 18:46:15 -0700101 sp<IBinder> binder = getBinderForOptions(state);
102
Steven Morelandcda60852021-04-14 23:45:32 +0000103 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
104 CHECK(iface != nullptr);
105
106 // Googlers might see go/another-look-at-aidl-hidl-perf
107 //
108 // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
109 // transactions were less than one page in size (system wide during a test
110 // involving media and camera). This is why this diverges from
111 // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
112 // this data on continuous integration. Here we are testing sending a
113 // transaction of twice this size. In other cases, we should focus on
114 // benchmarks of particular usecases. If individual binder transactions like
115 // the ones tested here are fast, then Android performance will be dominated
116 // by how many binder calls work together (and by factors like the scheduler,
117 // thermal throttling, core choice, etc..).
118 std::string str = std::string(getpagesize() * 2, 'a');
119 CHECK_EQ(str.size(), getpagesize() * 2);
120
121 while (state.KeepRunning()) {
122 std::string out;
123 Status ret = iface->repeatString(str, &out);
124 CHECK(ret.isOk()) << ret;
125 }
126}
Steven Moreland1ebdc702021-07-28 18:46:15 -0700127BENCHMARK(BM_repeatString)->Apply(EachTransport);
Steven Morelandcda60852021-04-14 23:45:32 +0000128
129void BM_repeatBinder(benchmark::State& state) {
Steven Morelandbdb53ab2021-05-05 17:57:41 +0000130 sp<IBinder> binder = gSession->getRootObject();
Steven Morelandcda60852021-04-14 23:45:32 +0000131 CHECK(binder != nullptr);
132 sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
133 CHECK(iface != nullptr);
134
135 while (state.KeepRunning()) {
136 // force creation of a new address
137 sp<IBinder> binder = sp<BBinder>::make();
138
139 sp<IBinder> out;
140 Status ret = iface->repeatBinder(binder, &out);
141 CHECK(ret.isOk()) << ret;
142 }
143}
Steven Moreland1ebdc702021-07-28 18:46:15 -0700144BENCHMARK(BM_repeatBinder)->Apply(EachTransport);
Steven Morelandcda60852021-04-14 23:45:32 +0000145
146int main(int argc, char** argv) {
147 ::benchmark::Initialize(&argc, argv);
148 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
149
150 std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
151 (void)unlink(addr.c_str());
152
Steven Moreland1ebdc702021-07-28 18:46:15 -0700153 std::cerr << "Tests suffixes:" << std::endl;
154 std::cerr << "\t\\" << Transport::KERNEL << " is KERNEL" << std::endl;
155 std::cerr << "\t\\" << Transport::RPC << " is RPC" << std::endl;
156
157#ifdef __BIONIC__
158 if (0 == fork()) {
159 prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
160 CHECK_EQ(OK,
161 defaultServiceManager()->addService(kKernelBinderInstance,
162 sp<MyBinderRpcBenchmark>::make()));
163 IPCThreadState::self()->joinThreadPool();
164 }
165
166 ProcessState::self()->setThreadPoolMaxThreadCount(1);
167 ProcessState::self()->startThreadPool();
168
169 gKernelBinder = defaultServiceManager()->waitForService(kKernelBinderInstance);
170 CHECK_NE(nullptr, gKernelBinder.get());
171#endif
172
Steven Morelandcda60852021-04-14 23:45:32 +0000173 std::thread([addr]() {
174 sp<RpcServer> server = RpcServer::make();
175 server->setRootObject(sp<MyBinderRpcBenchmark>::make());
Steven Morelandcda60852021-04-14 23:45:32 +0000176 server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
Steven Moreland611d15f2021-05-01 01:28:27 +0000177 CHECK(server->setupUnixDomainServer(addr.c_str()));
Steven Morelandf137de92021-04-24 01:54:26 +0000178 server->join();
Steven Morelandcda60852021-04-14 23:45:32 +0000179 }).detach();
180
181 for (size_t tries = 0; tries < 5; tries++) {
182 usleep(10000);
Steven Morelandbdb53ab2021-05-05 17:57:41 +0000183 if (gSession->setupUnixDomainClient(addr.c_str())) goto success;
Steven Morelandcda60852021-04-14 23:45:32 +0000184 }
185 LOG(FATAL) << "Could not connect.";
186success:
187
188 ::benchmark::RunSpecifiedBenchmarks();
Steven Moreland3ae982a2021-05-05 18:16:11 +0000189 return 0;
Steven Morelandcda60852021-04-14 23:45:32 +0000190}