Loading libs/binder/tests/IBinderRpcBenchmark.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -18,4 +18,7 @@ interface IBinderRpcBenchmark { @utf8InCpp String repeatString(@utf8InCpp String str); IBinder repeatBinder(IBinder binder); byte[] repeatBytes(in byte[] bytes); IBinder gimmeBinder(); void waitGimmesDestroyed(); } libs/binder/tests/binderRpcBenchmark.cpp +70 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,44 @@ class MyBinderRpcBenchmark : public BnBinderRpcBenchmark { *out = bytes; return Status::ok(); } class CountedBinder : public BBinder { public: CountedBinder(const sp<MyBinderRpcBenchmark>& parent) : mParent(parent) { std::lock_guard<std::mutex> l(mParent->mCountMutex); mParent->mBinderCount++; // std::cout << "Count + is now " << mParent->mBinderCount << std::endl; } ~CountedBinder() { { std::lock_guard<std::mutex> l(mParent->mCountMutex); mParent->mBinderCount--; // std::cout << "Count - is now " << mParent->mBinderCount << std::endl; // skip notify if (mParent->mBinderCount != 0) return; } mParent->mCountCv.notify_one(); } private: sp<MyBinderRpcBenchmark> mParent; }; Status gimmeBinder(sp<IBinder>* out) override { *out = sp<CountedBinder>::make(sp<MyBinderRpcBenchmark>::fromExisting(this)); return Status::ok(); } Status waitGimmesDestroyed() override { std::unique_lock<std::mutex> l(mCountMutex); mCountCv.wait(l, [&] { return mBinderCount == 0; }); return Status::ok(); } friend class CountedBinder; std::mutex mCountMutex; std::condition_variable mCountCv; size_t mBinderCount; }; enum Transport { Loading Loading @@ -212,6 +250,38 @@ BENCHMARK(BM_throughputForTransportAndBytes) ->ArgsProduct({kTransportList, {64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}}); void BM_collectProxies(benchmark::State& state) { sp<IBinder> binder = getBinderForOptions(state); sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder); CHECK(iface != nullptr); const size_t kNumIters = state.range(1); while (state.KeepRunning()) { std::vector<sp<IBinder>> out; out.resize(kNumIters); for (size_t i = 0; i < kNumIters; i++) { Status ret = iface->gimmeBinder(&out[i]); CHECK(ret.isOk()) << ret; } out.clear(); // we are using a thread up to wait, so make a call to // force all refcounts to be updated first - current // binder behavior means we really don't need to wait, // so code which is waiting is really there to protect // against any future changes that could delay destruction android::IInterface::asBinder(iface)->pingBinder(); iface->waitGimmesDestroyed(); } SetLabel(state); } BENCHMARK(BM_collectProxies)->ArgsProduct({kTransportList, {10, 100, 1000, 5000, 10000, 20000}}); void BM_repeatBinder(benchmark::State& state) { sp<IBinder> binder = getBinderForOptions(state); CHECK(binder != nullptr); Loading Loading
libs/binder/tests/IBinderRpcBenchmark.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -18,4 +18,7 @@ interface IBinderRpcBenchmark { @utf8InCpp String repeatString(@utf8InCpp String str); IBinder repeatBinder(IBinder binder); byte[] repeatBytes(in byte[] bytes); IBinder gimmeBinder(); void waitGimmesDestroyed(); }
libs/binder/tests/binderRpcBenchmark.cpp +70 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,44 @@ class MyBinderRpcBenchmark : public BnBinderRpcBenchmark { *out = bytes; return Status::ok(); } class CountedBinder : public BBinder { public: CountedBinder(const sp<MyBinderRpcBenchmark>& parent) : mParent(parent) { std::lock_guard<std::mutex> l(mParent->mCountMutex); mParent->mBinderCount++; // std::cout << "Count + is now " << mParent->mBinderCount << std::endl; } ~CountedBinder() { { std::lock_guard<std::mutex> l(mParent->mCountMutex); mParent->mBinderCount--; // std::cout << "Count - is now " << mParent->mBinderCount << std::endl; // skip notify if (mParent->mBinderCount != 0) return; } mParent->mCountCv.notify_one(); } private: sp<MyBinderRpcBenchmark> mParent; }; Status gimmeBinder(sp<IBinder>* out) override { *out = sp<CountedBinder>::make(sp<MyBinderRpcBenchmark>::fromExisting(this)); return Status::ok(); } Status waitGimmesDestroyed() override { std::unique_lock<std::mutex> l(mCountMutex); mCountCv.wait(l, [&] { return mBinderCount == 0; }); return Status::ok(); } friend class CountedBinder; std::mutex mCountMutex; std::condition_variable mCountCv; size_t mBinderCount; }; enum Transport { Loading Loading @@ -212,6 +250,38 @@ BENCHMARK(BM_throughputForTransportAndBytes) ->ArgsProduct({kTransportList, {64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}}); void BM_collectProxies(benchmark::State& state) { sp<IBinder> binder = getBinderForOptions(state); sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder); CHECK(iface != nullptr); const size_t kNumIters = state.range(1); while (state.KeepRunning()) { std::vector<sp<IBinder>> out; out.resize(kNumIters); for (size_t i = 0; i < kNumIters; i++) { Status ret = iface->gimmeBinder(&out[i]); CHECK(ret.isOk()) << ret; } out.clear(); // we are using a thread up to wait, so make a call to // force all refcounts to be updated first - current // binder behavior means we really don't need to wait, // so code which is waiting is really there to protect // against any future changes that could delay destruction android::IInterface::asBinder(iface)->pingBinder(); iface->waitGimmesDestroyed(); } SetLabel(state); } BENCHMARK(BM_collectProxies)->ArgsProduct({kTransportList, {10, 100, 1000, 5000, 10000, 20000}}); void BM_repeatBinder(benchmark::State& state) { sp<IBinder> binder = getBinderForOptions(state); CHECK(binder != nullptr); Loading