xref: /aosp_15_r20/frameworks/native/libs/binder/tests/binderRpcBenchmark.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <BnBinderRpcBenchmark.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <android-base/logging.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/Binder.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcCertificateFormat.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcCertificateVerifier.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcServer.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcSession.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTlsTestUtils.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTlsUtils.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTransportRaw.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <binder/RpcTransportTls.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <openssl/ssl.h>
33*38e8c45fSAndroid Build Coastguard Worker 
34*38e8c45fSAndroid Build Coastguard Worker #include <thread>
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker #include <signal.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <sys/prctl.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker using android::BBinder;
42*38e8c45fSAndroid Build Coastguard Worker using android::defaultServiceManager;
43*38e8c45fSAndroid Build Coastguard Worker using android::IBinder;
44*38e8c45fSAndroid Build Coastguard Worker using android::interface_cast;
45*38e8c45fSAndroid Build Coastguard Worker using android::IPCThreadState;
46*38e8c45fSAndroid Build Coastguard Worker using android::IServiceManager;
47*38e8c45fSAndroid Build Coastguard Worker using android::OK;
48*38e8c45fSAndroid Build Coastguard Worker using android::ProcessState;
49*38e8c45fSAndroid Build Coastguard Worker using android::RpcAuthPreSigned;
50*38e8c45fSAndroid Build Coastguard Worker using android::RpcCertificateFormat;
51*38e8c45fSAndroid Build Coastguard Worker using android::RpcCertificateVerifier;
52*38e8c45fSAndroid Build Coastguard Worker using android::RpcCertificateVerifierNoOp;
53*38e8c45fSAndroid Build Coastguard Worker using android::RpcServer;
54*38e8c45fSAndroid Build Coastguard Worker using android::RpcSession;
55*38e8c45fSAndroid Build Coastguard Worker using android::RpcTransportCtxFactory;
56*38e8c45fSAndroid Build Coastguard Worker using android::RpcTransportCtxFactoryRaw;
57*38e8c45fSAndroid Build Coastguard Worker using android::RpcTransportCtxFactoryTls;
58*38e8c45fSAndroid Build Coastguard Worker using android::sp;
59*38e8c45fSAndroid Build Coastguard Worker using android::status_t;
60*38e8c45fSAndroid Build Coastguard Worker using android::statusToString;
61*38e8c45fSAndroid Build Coastguard Worker using android::String16;
62*38e8c45fSAndroid Build Coastguard Worker using android::binder::Status;
63*38e8c45fSAndroid Build Coastguard Worker 
64*38e8c45fSAndroid Build Coastguard Worker class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
repeatString(const std::string & str,std::string * out)65*38e8c45fSAndroid Build Coastguard Worker     Status repeatString(const std::string& str, std::string* out) override {
66*38e8c45fSAndroid Build Coastguard Worker         *out = str;
67*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
68*38e8c45fSAndroid Build Coastguard Worker     }
repeatBinder(const sp<IBinder> & binder,sp<IBinder> * out)69*38e8c45fSAndroid Build Coastguard Worker     Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
70*38e8c45fSAndroid Build Coastguard Worker         *out = binder;
71*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
72*38e8c45fSAndroid Build Coastguard Worker     }
repeatBytes(const std::vector<uint8_t> & bytes,std::vector<uint8_t> * out)73*38e8c45fSAndroid Build Coastguard Worker     Status repeatBytes(const std::vector<uint8_t>& bytes, std::vector<uint8_t>* out) override {
74*38e8c45fSAndroid Build Coastguard Worker         *out = bytes;
75*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
76*38e8c45fSAndroid Build Coastguard Worker     }
77*38e8c45fSAndroid Build Coastguard Worker 
78*38e8c45fSAndroid Build Coastguard Worker     class CountedBinder : public BBinder {
79*38e8c45fSAndroid Build Coastguard Worker     public:
CountedBinder(const sp<MyBinderRpcBenchmark> & parent)80*38e8c45fSAndroid Build Coastguard Worker         CountedBinder(const sp<MyBinderRpcBenchmark>& parent) : mParent(parent) {
81*38e8c45fSAndroid Build Coastguard Worker             std::lock_guard<std::mutex> l(mParent->mCountMutex);
82*38e8c45fSAndroid Build Coastguard Worker             mParent->mBinderCount++;
83*38e8c45fSAndroid Build Coastguard Worker             // std::cout << "Count + is now " << mParent->mBinderCount << std::endl;
84*38e8c45fSAndroid Build Coastguard Worker         }
~CountedBinder()85*38e8c45fSAndroid Build Coastguard Worker         ~CountedBinder() {
86*38e8c45fSAndroid Build Coastguard Worker             {
87*38e8c45fSAndroid Build Coastguard Worker                 std::lock_guard<std::mutex> l(mParent->mCountMutex);
88*38e8c45fSAndroid Build Coastguard Worker                 mParent->mBinderCount--;
89*38e8c45fSAndroid Build Coastguard Worker                 // std::cout << "Count - is now " << mParent->mBinderCount << std::endl;
90*38e8c45fSAndroid Build Coastguard Worker 
91*38e8c45fSAndroid Build Coastguard Worker                 // skip notify
92*38e8c45fSAndroid Build Coastguard Worker                 if (mParent->mBinderCount != 0) return;
93*38e8c45fSAndroid Build Coastguard Worker             }
94*38e8c45fSAndroid Build Coastguard Worker             mParent->mCountCv.notify_one();
95*38e8c45fSAndroid Build Coastguard Worker         }
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     private:
98*38e8c45fSAndroid Build Coastguard Worker         sp<MyBinderRpcBenchmark> mParent;
99*38e8c45fSAndroid Build Coastguard Worker     };
100*38e8c45fSAndroid Build Coastguard Worker 
gimmeBinder(sp<IBinder> * out)101*38e8c45fSAndroid Build Coastguard Worker     Status gimmeBinder(sp<IBinder>* out) override {
102*38e8c45fSAndroid Build Coastguard Worker         *out = sp<CountedBinder>::make(sp<MyBinderRpcBenchmark>::fromExisting(this));
103*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
104*38e8c45fSAndroid Build Coastguard Worker     }
waitGimmesDestroyed()105*38e8c45fSAndroid Build Coastguard Worker     Status waitGimmesDestroyed() override {
106*38e8c45fSAndroid Build Coastguard Worker         std::unique_lock<std::mutex> l(mCountMutex);
107*38e8c45fSAndroid Build Coastguard Worker         mCountCv.wait(l, [&] { return mBinderCount == 0; });
108*38e8c45fSAndroid Build Coastguard Worker         return Status::ok();
109*38e8c45fSAndroid Build Coastguard Worker     }
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker     friend class CountedBinder;
112*38e8c45fSAndroid Build Coastguard Worker     std::mutex mCountMutex;
113*38e8c45fSAndroid Build Coastguard Worker     std::condition_variable mCountCv;
114*38e8c45fSAndroid Build Coastguard Worker     size_t mBinderCount;
115*38e8c45fSAndroid Build Coastguard Worker };
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker enum Transport {
118*38e8c45fSAndroid Build Coastguard Worker     KERNEL,
119*38e8c45fSAndroid Build Coastguard Worker     RPC,
120*38e8c45fSAndroid Build Coastguard Worker     RPC_TLS,
121*38e8c45fSAndroid Build Coastguard Worker };
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker static const std::initializer_list<int64_t> kTransportList = {
124*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
125*38e8c45fSAndroid Build Coastguard Worker         Transport::KERNEL,
126*38e8c45fSAndroid Build Coastguard Worker #endif
127*38e8c45fSAndroid Build Coastguard Worker         Transport::RPC,
128*38e8c45fSAndroid Build Coastguard Worker         Transport::RPC_TLS,
129*38e8c45fSAndroid Build Coastguard Worker };
130*38e8c45fSAndroid Build Coastguard Worker 
makeFactoryTls()131*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() {
132*38e8c45fSAndroid Build Coastguard Worker     auto pkey = android::makeKeyPairForSelfSignedCert();
133*38e8c45fSAndroid Build Coastguard Worker     CHECK_NE(pkey.get(), nullptr);
134*38e8c45fSAndroid Build Coastguard Worker     auto cert = android::makeSelfSignedCert(pkey.get(), android::kCertValidSeconds);
135*38e8c45fSAndroid Build Coastguard Worker     CHECK_NE(cert.get(), nullptr);
136*38e8c45fSAndroid Build Coastguard Worker 
137*38e8c45fSAndroid Build Coastguard Worker     auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(OK);
138*38e8c45fSAndroid Build Coastguard Worker     auto auth = std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert));
139*38e8c45fSAndroid Build Coastguard Worker     return RpcTransportCtxFactoryTls::make(verifier, std::move(auth));
140*38e8c45fSAndroid Build Coastguard Worker }
141*38e8c45fSAndroid Build Coastguard Worker 
142*38e8c45fSAndroid Build Coastguard Worker static sp<RpcSession> gSession = RpcSession::make();
143*38e8c45fSAndroid Build Coastguard Worker static sp<IBinder> gRpcBinder;
144*38e8c45fSAndroid Build Coastguard Worker // Certificate validation happens during handshake and does not affect the result of benchmarks.
145*38e8c45fSAndroid Build Coastguard Worker // Skip certificate validation to simplify the setup process.
146*38e8c45fSAndroid Build Coastguard Worker static sp<RpcSession> gSessionTls = RpcSession::make(makeFactoryTls());
147*38e8c45fSAndroid Build Coastguard Worker static sp<IBinder> gRpcTlsBinder;
148*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
149*38e8c45fSAndroid Build Coastguard Worker static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
150*38e8c45fSAndroid Build Coastguard Worker static sp<IBinder> gKernelBinder;
151*38e8c45fSAndroid Build Coastguard Worker #endif
152*38e8c45fSAndroid Build Coastguard Worker 
getBinderForOptions(benchmark::State & state)153*38e8c45fSAndroid Build Coastguard Worker static sp<IBinder> getBinderForOptions(benchmark::State& state) {
154*38e8c45fSAndroid Build Coastguard Worker     Transport transport = static_cast<Transport>(state.range(0));
155*38e8c45fSAndroid Build Coastguard Worker     switch (transport) {
156*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
157*38e8c45fSAndroid Build Coastguard Worker         case KERNEL:
158*38e8c45fSAndroid Build Coastguard Worker             return gKernelBinder;
159*38e8c45fSAndroid Build Coastguard Worker #endif
160*38e8c45fSAndroid Build Coastguard Worker         case RPC:
161*38e8c45fSAndroid Build Coastguard Worker             return gRpcBinder;
162*38e8c45fSAndroid Build Coastguard Worker         case RPC_TLS:
163*38e8c45fSAndroid Build Coastguard Worker             return gRpcTlsBinder;
164*38e8c45fSAndroid Build Coastguard Worker         default:
165*38e8c45fSAndroid Build Coastguard Worker             LOG(FATAL) << "Unknown transport value: " << transport;
166*38e8c45fSAndroid Build Coastguard Worker             return nullptr;
167*38e8c45fSAndroid Build Coastguard Worker     }
168*38e8c45fSAndroid Build Coastguard Worker }
169*38e8c45fSAndroid Build Coastguard Worker 
SetLabel(benchmark::State & state)170*38e8c45fSAndroid Build Coastguard Worker static void SetLabel(benchmark::State& state) {
171*38e8c45fSAndroid Build Coastguard Worker     Transport transport = static_cast<Transport>(state.range(0));
172*38e8c45fSAndroid Build Coastguard Worker     switch (transport) {
173*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
174*38e8c45fSAndroid Build Coastguard Worker         case KERNEL:
175*38e8c45fSAndroid Build Coastguard Worker             state.SetLabel("kernel");
176*38e8c45fSAndroid Build Coastguard Worker             break;
177*38e8c45fSAndroid Build Coastguard Worker #endif
178*38e8c45fSAndroid Build Coastguard Worker         case RPC:
179*38e8c45fSAndroid Build Coastguard Worker             state.SetLabel("rpc");
180*38e8c45fSAndroid Build Coastguard Worker             break;
181*38e8c45fSAndroid Build Coastguard Worker         case RPC_TLS:
182*38e8c45fSAndroid Build Coastguard Worker             state.SetLabel("rpc_tls");
183*38e8c45fSAndroid Build Coastguard Worker             break;
184*38e8c45fSAndroid Build Coastguard Worker         default:
185*38e8c45fSAndroid Build Coastguard Worker             LOG(FATAL) << "Unknown transport value: " << transport;
186*38e8c45fSAndroid Build Coastguard Worker     }
187*38e8c45fSAndroid Build Coastguard Worker }
188*38e8c45fSAndroid Build Coastguard Worker 
BM_pingTransaction(benchmark::State & state)189*38e8c45fSAndroid Build Coastguard Worker void BM_pingTransaction(benchmark::State& state) {
190*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder = getBinderForOptions(state);
191*38e8c45fSAndroid Build Coastguard Worker 
192*38e8c45fSAndroid Build Coastguard Worker     while (state.KeepRunning()) {
193*38e8c45fSAndroid Build Coastguard Worker         CHECK_EQ(OK, binder->pingBinder());
194*38e8c45fSAndroid Build Coastguard Worker     }
195*38e8c45fSAndroid Build Coastguard Worker 
196*38e8c45fSAndroid Build Coastguard Worker     SetLabel(state);
197*38e8c45fSAndroid Build Coastguard Worker }
198*38e8c45fSAndroid Build Coastguard Worker BENCHMARK(BM_pingTransaction)->ArgsProduct({kTransportList});
199*38e8c45fSAndroid Build Coastguard Worker 
BM_repeatTwoPageString(benchmark::State & state)200*38e8c45fSAndroid Build Coastguard Worker void BM_repeatTwoPageString(benchmark::State& state) {
201*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder = getBinderForOptions(state);
202*38e8c45fSAndroid Build Coastguard Worker 
203*38e8c45fSAndroid Build Coastguard Worker     sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
204*38e8c45fSAndroid Build Coastguard Worker     CHECK(iface != nullptr);
205*38e8c45fSAndroid Build Coastguard Worker 
206*38e8c45fSAndroid Build Coastguard Worker     // Googlers might see go/another-look-at-aidl-hidl-perf
207*38e8c45fSAndroid Build Coastguard Worker     //
208*38e8c45fSAndroid Build Coastguard Worker     // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
209*38e8c45fSAndroid Build Coastguard Worker     // transactions were less than one page in size (system wide during a test
210*38e8c45fSAndroid Build Coastguard Worker     // involving media and camera). This is why this diverges from
211*38e8c45fSAndroid Build Coastguard Worker     // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
212*38e8c45fSAndroid Build Coastguard Worker     // this data on continuous integration. Here we are testing sending a
213*38e8c45fSAndroid Build Coastguard Worker     // transaction of twice this size. In other cases, we should focus on
214*38e8c45fSAndroid Build Coastguard Worker     // benchmarks of particular usecases. If individual binder transactions like
215*38e8c45fSAndroid Build Coastguard Worker     // the ones tested here are fast, then Android performance will be dominated
216*38e8c45fSAndroid Build Coastguard Worker     // by how many binder calls work together (and by factors like the scheduler,
217*38e8c45fSAndroid Build Coastguard Worker     // thermal throttling, core choice, etc..).
218*38e8c45fSAndroid Build Coastguard Worker     std::string str = std::string(getpagesize() * 2, 'a');
219*38e8c45fSAndroid Build Coastguard Worker     CHECK_EQ(static_cast<ssize_t>(str.size()), getpagesize() * 2);
220*38e8c45fSAndroid Build Coastguard Worker 
221*38e8c45fSAndroid Build Coastguard Worker     while (state.KeepRunning()) {
222*38e8c45fSAndroid Build Coastguard Worker         std::string out;
223*38e8c45fSAndroid Build Coastguard Worker         Status ret = iface->repeatString(str, &out);
224*38e8c45fSAndroid Build Coastguard Worker         CHECK(ret.isOk()) << ret;
225*38e8c45fSAndroid Build Coastguard Worker     }
226*38e8c45fSAndroid Build Coastguard Worker 
227*38e8c45fSAndroid Build Coastguard Worker     SetLabel(state);
228*38e8c45fSAndroid Build Coastguard Worker }
229*38e8c45fSAndroid Build Coastguard Worker BENCHMARK(BM_repeatTwoPageString)->ArgsProduct({kTransportList});
230*38e8c45fSAndroid Build Coastguard Worker 
BM_throughputForTransportAndBytes(benchmark::State & state)231*38e8c45fSAndroid Build Coastguard Worker void BM_throughputForTransportAndBytes(benchmark::State& state) {
232*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder = getBinderForOptions(state);
233*38e8c45fSAndroid Build Coastguard Worker     sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
234*38e8c45fSAndroid Build Coastguard Worker     CHECK(iface != nullptr);
235*38e8c45fSAndroid Build Coastguard Worker 
236*38e8c45fSAndroid Build Coastguard Worker     std::vector<uint8_t> bytes = std::vector<uint8_t>(state.range(1));
237*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < bytes.size(); i++) {
238*38e8c45fSAndroid Build Coastguard Worker         bytes[i] = i % 256;
239*38e8c45fSAndroid Build Coastguard Worker     }
240*38e8c45fSAndroid Build Coastguard Worker 
241*38e8c45fSAndroid Build Coastguard Worker     while (state.KeepRunning()) {
242*38e8c45fSAndroid Build Coastguard Worker         std::vector<uint8_t> out;
243*38e8c45fSAndroid Build Coastguard Worker         Status ret = iface->repeatBytes(bytes, &out);
244*38e8c45fSAndroid Build Coastguard Worker         CHECK(ret.isOk()) << ret;
245*38e8c45fSAndroid Build Coastguard Worker     }
246*38e8c45fSAndroid Build Coastguard Worker 
247*38e8c45fSAndroid Build Coastguard Worker     SetLabel(state);
248*38e8c45fSAndroid Build Coastguard Worker }
249*38e8c45fSAndroid Build Coastguard Worker BENCHMARK(BM_throughputForTransportAndBytes)
250*38e8c45fSAndroid Build Coastguard Worker         ->ArgsProduct({kTransportList,
251*38e8c45fSAndroid Build Coastguard Worker                        {64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}});
252*38e8c45fSAndroid Build Coastguard Worker 
BM_collectProxies(benchmark::State & state)253*38e8c45fSAndroid Build Coastguard Worker void BM_collectProxies(benchmark::State& state) {
254*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder = getBinderForOptions(state);
255*38e8c45fSAndroid Build Coastguard Worker     sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
256*38e8c45fSAndroid Build Coastguard Worker     CHECK(iface != nullptr);
257*38e8c45fSAndroid Build Coastguard Worker 
258*38e8c45fSAndroid Build Coastguard Worker     const size_t kNumIters = state.range(1);
259*38e8c45fSAndroid Build Coastguard Worker 
260*38e8c45fSAndroid Build Coastguard Worker     while (state.KeepRunning()) {
261*38e8c45fSAndroid Build Coastguard Worker         std::vector<sp<IBinder>> out;
262*38e8c45fSAndroid Build Coastguard Worker         out.resize(kNumIters);
263*38e8c45fSAndroid Build Coastguard Worker 
264*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < kNumIters; i++) {
265*38e8c45fSAndroid Build Coastguard Worker             Status ret = iface->gimmeBinder(&out[i]);
266*38e8c45fSAndroid Build Coastguard Worker             CHECK(ret.isOk()) << ret;
267*38e8c45fSAndroid Build Coastguard Worker         }
268*38e8c45fSAndroid Build Coastguard Worker 
269*38e8c45fSAndroid Build Coastguard Worker         out.clear();
270*38e8c45fSAndroid Build Coastguard Worker 
271*38e8c45fSAndroid Build Coastguard Worker         // we are using a thread up to wait, so make a call to
272*38e8c45fSAndroid Build Coastguard Worker         // force all refcounts to be updated first - current
273*38e8c45fSAndroid Build Coastguard Worker         // binder behavior means we really don't need to wait,
274*38e8c45fSAndroid Build Coastguard Worker         // so code which is waiting is really there to protect
275*38e8c45fSAndroid Build Coastguard Worker         // against any future changes that could delay destruction
276*38e8c45fSAndroid Build Coastguard Worker         android::IInterface::asBinder(iface)->pingBinder();
277*38e8c45fSAndroid Build Coastguard Worker 
278*38e8c45fSAndroid Build Coastguard Worker         iface->waitGimmesDestroyed();
279*38e8c45fSAndroid Build Coastguard Worker     }
280*38e8c45fSAndroid Build Coastguard Worker 
281*38e8c45fSAndroid Build Coastguard Worker     SetLabel(state);
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker BENCHMARK(BM_collectProxies)->ArgsProduct({kTransportList, {10, 100, 1000, 5000, 10000, 20000}});
284*38e8c45fSAndroid Build Coastguard Worker 
BM_repeatBinder(benchmark::State & state)285*38e8c45fSAndroid Build Coastguard Worker void BM_repeatBinder(benchmark::State& state) {
286*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder = getBinderForOptions(state);
287*38e8c45fSAndroid Build Coastguard Worker     CHECK(binder != nullptr);
288*38e8c45fSAndroid Build Coastguard Worker     sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
289*38e8c45fSAndroid Build Coastguard Worker     CHECK(iface != nullptr);
290*38e8c45fSAndroid Build Coastguard Worker 
291*38e8c45fSAndroid Build Coastguard Worker     while (state.KeepRunning()) {
292*38e8c45fSAndroid Build Coastguard Worker         // force creation of a new address
293*38e8c45fSAndroid Build Coastguard Worker         sp<IBinder> binder = sp<BBinder>::make();
294*38e8c45fSAndroid Build Coastguard Worker 
295*38e8c45fSAndroid Build Coastguard Worker         sp<IBinder> out;
296*38e8c45fSAndroid Build Coastguard Worker         Status ret = iface->repeatBinder(binder, &out);
297*38e8c45fSAndroid Build Coastguard Worker         CHECK(ret.isOk()) << ret;
298*38e8c45fSAndroid Build Coastguard Worker     }
299*38e8c45fSAndroid Build Coastguard Worker 
300*38e8c45fSAndroid Build Coastguard Worker     SetLabel(state);
301*38e8c45fSAndroid Build Coastguard Worker }
302*38e8c45fSAndroid Build Coastguard Worker BENCHMARK(BM_repeatBinder)->ArgsProduct({kTransportList});
303*38e8c45fSAndroid Build Coastguard Worker 
forkRpcServer(const char * addr,const sp<RpcServer> & server)304*38e8c45fSAndroid Build Coastguard Worker void forkRpcServer(const char* addr, const sp<RpcServer>& server) {
305*38e8c45fSAndroid Build Coastguard Worker     if (0 == fork()) {
306*38e8c45fSAndroid Build Coastguard Worker         prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
307*38e8c45fSAndroid Build Coastguard Worker         server->setRootObject(sp<MyBinderRpcBenchmark>::make());
308*38e8c45fSAndroid Build Coastguard Worker         CHECK_EQ(OK, server->setupUnixDomainServer(addr));
309*38e8c45fSAndroid Build Coastguard Worker         server->join();
310*38e8c45fSAndroid Build Coastguard Worker         exit(1);
311*38e8c45fSAndroid Build Coastguard Worker     }
312*38e8c45fSAndroid Build Coastguard Worker }
313*38e8c45fSAndroid Build Coastguard Worker 
setupClient(const sp<RpcSession> & session,const char * addr)314*38e8c45fSAndroid Build Coastguard Worker void setupClient(const sp<RpcSession>& session, const char* addr) {
315*38e8c45fSAndroid Build Coastguard Worker     status_t status;
316*38e8c45fSAndroid Build Coastguard Worker     for (size_t tries = 0; tries < 5; tries++) {
317*38e8c45fSAndroid Build Coastguard Worker         usleep(10000);
318*38e8c45fSAndroid Build Coastguard Worker         status = session->setupUnixDomainClient(addr);
319*38e8c45fSAndroid Build Coastguard Worker         if (status == OK) break;
320*38e8c45fSAndroid Build Coastguard Worker     }
321*38e8c45fSAndroid Build Coastguard Worker     CHECK_EQ(status, OK) << "Could not connect: " << addr << ": " << statusToString(status).c_str();
322*38e8c45fSAndroid Build Coastguard Worker }
323*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)324*38e8c45fSAndroid Build Coastguard Worker int main(int argc, char** argv) {
325*38e8c45fSAndroid Build Coastguard Worker     ::benchmark::Initialize(&argc, argv);
326*38e8c45fSAndroid Build Coastguard Worker     if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
327*38e8c45fSAndroid Build Coastguard Worker 
328*38e8c45fSAndroid Build Coastguard Worker #ifdef __BIONIC__
329*38e8c45fSAndroid Build Coastguard Worker     if (0 == fork()) {
330*38e8c45fSAndroid Build Coastguard Worker         prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
331*38e8c45fSAndroid Build Coastguard Worker         CHECK_EQ(OK,
332*38e8c45fSAndroid Build Coastguard Worker                  defaultServiceManager()->addService(kKernelBinderInstance,
333*38e8c45fSAndroid Build Coastguard Worker                                                      sp<MyBinderRpcBenchmark>::make()));
334*38e8c45fSAndroid Build Coastguard Worker         IPCThreadState::self()->joinThreadPool();
335*38e8c45fSAndroid Build Coastguard Worker         exit(1);
336*38e8c45fSAndroid Build Coastguard Worker     }
337*38e8c45fSAndroid Build Coastguard Worker 
338*38e8c45fSAndroid Build Coastguard Worker     ProcessState::self()->setThreadPoolMaxThreadCount(1);
339*38e8c45fSAndroid Build Coastguard Worker     ProcessState::self()->startThreadPool();
340*38e8c45fSAndroid Build Coastguard Worker 
341*38e8c45fSAndroid Build Coastguard Worker     gKernelBinder = defaultServiceManager()->waitForService(kKernelBinderInstance);
342*38e8c45fSAndroid Build Coastguard Worker     CHECK_NE(nullptr, gKernelBinder.get());
343*38e8c45fSAndroid Build Coastguard Worker #endif
344*38e8c45fSAndroid Build Coastguard Worker 
345*38e8c45fSAndroid Build Coastguard Worker     std::string tmp = getenv("TMPDIR") ?: "/tmp";
346*38e8c45fSAndroid Build Coastguard Worker 
347*38e8c45fSAndroid Build Coastguard Worker     std::string addr = tmp + "/binderRpcBenchmark";
348*38e8c45fSAndroid Build Coastguard Worker     (void)unlink(addr.c_str());
349*38e8c45fSAndroid Build Coastguard Worker     forkRpcServer(addr.c_str(), RpcServer::make(RpcTransportCtxFactoryRaw::make()));
350*38e8c45fSAndroid Build Coastguard Worker     setupClient(gSession, addr.c_str());
351*38e8c45fSAndroid Build Coastguard Worker     gRpcBinder = gSession->getRootObject();
352*38e8c45fSAndroid Build Coastguard Worker 
353*38e8c45fSAndroid Build Coastguard Worker     std::string tlsAddr = tmp + "/binderRpcTlsBenchmark";
354*38e8c45fSAndroid Build Coastguard Worker     (void)unlink(tlsAddr.c_str());
355*38e8c45fSAndroid Build Coastguard Worker     forkRpcServer(tlsAddr.c_str(), RpcServer::make(makeFactoryTls()));
356*38e8c45fSAndroid Build Coastguard Worker     setupClient(gSessionTls, tlsAddr.c_str());
357*38e8c45fSAndroid Build Coastguard Worker     gRpcTlsBinder = gSessionTls->getRootObject();
358*38e8c45fSAndroid Build Coastguard Worker 
359*38e8c45fSAndroid Build Coastguard Worker     ::benchmark::RunSpecifiedBenchmarks();
360*38e8c45fSAndroid Build Coastguard Worker     return 0;
361*38e8c45fSAndroid Build Coastguard Worker }
362