xref: /aosp_15_r20/external/cronet/ipc/ipc_mojo_perftest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker #include <tuple>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/test/perf_time_logger.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
23*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
24*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_mojo.h"
25*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_perftest_messages.h"
26*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_perftest_util.h"
27*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_sync_channel.h"
28*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test.mojom.h"
29*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test_base.h"
30*6777b538SAndroid Build Coastguard Worker #include "mojo/core/embedder/embedder.h"
31*6777b538SAndroid Build Coastguard Worker #include "mojo/core/test/mojo_test_base.h"
32*6777b538SAndroid Build Coastguard Worker #include "mojo/core/test/multiprocess_test_helper.h"
33*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_receiver_set.h"
34*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/associated_remote.h"
35*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
36*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_receiver.h"
37*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_remote.h"
38*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/receiver.h"
39*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/receiver_set.h"
40*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/remote.h"
41*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/message_pipe.h"
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker namespace IPC {
44*6777b538SAndroid Build Coastguard Worker namespace {
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker class PerformanceChannelListener : public Listener {
47*6777b538SAndroid Build Coastguard Worker  public:
PerformanceChannelListener(const std::string & label)48*6777b538SAndroid Build Coastguard Worker   explicit PerformanceChannelListener(const std::string& label)
49*6777b538SAndroid Build Coastguard Worker       : label_(label),
50*6777b538SAndroid Build Coastguard Worker         sender_(nullptr),
51*6777b538SAndroid Build Coastguard Worker         msg_count_(0),
52*6777b538SAndroid Build Coastguard Worker         msg_size_(0),
53*6777b538SAndroid Build Coastguard Worker         sync_(false),
54*6777b538SAndroid Build Coastguard Worker         count_down_(0) {
55*6777b538SAndroid Build Coastguard Worker     VLOG(1) << "Server listener up";
56*6777b538SAndroid Build Coastguard Worker   }
57*6777b538SAndroid Build Coastguard Worker 
~PerformanceChannelListener()58*6777b538SAndroid Build Coastguard Worker   ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; }
59*6777b538SAndroid Build Coastguard Worker 
Init(Sender * sender)60*6777b538SAndroid Build Coastguard Worker   void Init(Sender* sender) {
61*6777b538SAndroid Build Coastguard Worker     DCHECK(!sender_);
62*6777b538SAndroid Build Coastguard Worker     sender_ = sender;
63*6777b538SAndroid Build Coastguard Worker   }
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   // Call this before running the message loop.
SetTestParams(int msg_count,size_t msg_size,bool sync)66*6777b538SAndroid Build Coastguard Worker   void SetTestParams(int msg_count, size_t msg_size, bool sync) {
67*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(0, count_down_);
68*6777b538SAndroid Build Coastguard Worker     msg_count_ = msg_count;
69*6777b538SAndroid Build Coastguard Worker     msg_size_ = msg_size;
70*6777b538SAndroid Build Coastguard Worker     sync_ = sync;
71*6777b538SAndroid Build Coastguard Worker     count_down_ = msg_count_;
72*6777b538SAndroid Build Coastguard Worker     payload_ = std::string(msg_size_, 'a');
73*6777b538SAndroid Build Coastguard Worker   }
74*6777b538SAndroid Build Coastguard Worker 
OnMessageReceived(const Message & message)75*6777b538SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
76*6777b538SAndroid Build Coastguard Worker     CHECK(sender_);
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker     bool handled = true;
79*6777b538SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(PerformanceChannelListener, message)
80*6777b538SAndroid Build Coastguard Worker       IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
81*6777b538SAndroid Build Coastguard Worker       IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
82*6777b538SAndroid Build Coastguard Worker       IPC_MESSAGE_UNHANDLED(handled = false)
83*6777b538SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
84*6777b538SAndroid Build Coastguard Worker     return handled;
85*6777b538SAndroid Build Coastguard Worker   }
86*6777b538SAndroid Build Coastguard Worker 
OnHello()87*6777b538SAndroid Build Coastguard Worker   void OnHello() {
88*6777b538SAndroid Build Coastguard Worker     // Start timing on hello.
89*6777b538SAndroid Build Coastguard Worker     DCHECK(!perf_logger_.get());
90*6777b538SAndroid Build Coastguard Worker     std::string test_name =
91*6777b538SAndroid Build Coastguard Worker         base::StringPrintf("IPC_%s_Perf_%dx_%u", label_.c_str(), msg_count_,
92*6777b538SAndroid Build Coastguard Worker                            static_cast<unsigned>(msg_size_));
93*6777b538SAndroid Build Coastguard Worker     perf_logger_ = std::make_unique<base::PerfTimeLogger>(test_name.c_str());
94*6777b538SAndroid Build Coastguard Worker     if (sync_) {
95*6777b538SAndroid Build Coastguard Worker       for (; count_down_ > 0; --count_down_) {
96*6777b538SAndroid Build Coastguard Worker         std::string response;
97*6777b538SAndroid Build Coastguard Worker         sender_->Send(new TestMsg_SyncPing(payload_, &response));
98*6777b538SAndroid Build Coastguard Worker         DCHECK_EQ(response, payload_);
99*6777b538SAndroid Build Coastguard Worker       }
100*6777b538SAndroid Build Coastguard Worker       perf_logger_.reset();
101*6777b538SAndroid Build Coastguard Worker       if (!quit_closure_.is_null()) {
102*6777b538SAndroid Build Coastguard Worker         std::move(quit_closure_).Run();
103*6777b538SAndroid Build Coastguard Worker       }
104*6777b538SAndroid Build Coastguard Worker     } else {
105*6777b538SAndroid Build Coastguard Worker       SendPong();
106*6777b538SAndroid Build Coastguard Worker     }
107*6777b538SAndroid Build Coastguard Worker   }
108*6777b538SAndroid Build Coastguard Worker 
OnPing(const std::string & payload)109*6777b538SAndroid Build Coastguard Worker   void OnPing(const std::string& payload) {
110*6777b538SAndroid Build Coastguard Worker     // Include message deserialization in latency.
111*6777b538SAndroid Build Coastguard Worker     DCHECK_EQ(payload_.size(), payload.size());
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker     CHECK(count_down_ > 0);
114*6777b538SAndroid Build Coastguard Worker     count_down_--;
115*6777b538SAndroid Build Coastguard Worker     if (count_down_ == 0) {
116*6777b538SAndroid Build Coastguard Worker       perf_logger_.reset();  // Stop the perf timer now.
117*6777b538SAndroid Build Coastguard Worker       if (!quit_closure_.is_null()) {
118*6777b538SAndroid Build Coastguard Worker         std::move(quit_closure_).Run();
119*6777b538SAndroid Build Coastguard Worker       }
120*6777b538SAndroid Build Coastguard Worker       return;
121*6777b538SAndroid Build Coastguard Worker     }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker     SendPong();
124*6777b538SAndroid Build Coastguard Worker   }
125*6777b538SAndroid Build Coastguard Worker 
SendPong()126*6777b538SAndroid Build Coastguard Worker   void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); }
127*6777b538SAndroid Build Coastguard Worker 
set_quit_closure(base::OnceClosure quit_closure)128*6777b538SAndroid Build Coastguard Worker   void set_quit_closure(base::OnceClosure quit_closure) {
129*6777b538SAndroid Build Coastguard Worker     quit_closure_ = std::move(quit_closure);
130*6777b538SAndroid Build Coastguard Worker   }
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker  private:
133*6777b538SAndroid Build Coastguard Worker   std::string label_;
134*6777b538SAndroid Build Coastguard Worker   raw_ptr<Sender> sender_;
135*6777b538SAndroid Build Coastguard Worker   int msg_count_;
136*6777b538SAndroid Build Coastguard Worker   size_t msg_size_;
137*6777b538SAndroid Build Coastguard Worker   bool sync_;
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker   int count_down_;
140*6777b538SAndroid Build Coastguard Worker   std::string payload_;
141*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::PerfTimeLogger> perf_logger_;
142*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
143*6777b538SAndroid Build Coastguard Worker };
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker class PingPongTestParams {
146*6777b538SAndroid Build Coastguard Worker  public:
PingPongTestParams(size_t size,int count)147*6777b538SAndroid Build Coastguard Worker   PingPongTestParams(size_t size, int count)
148*6777b538SAndroid Build Coastguard Worker       : message_size_(size), message_count_(count) {}
149*6777b538SAndroid Build Coastguard Worker 
message_size() const150*6777b538SAndroid Build Coastguard Worker   size_t message_size() const { return message_size_; }
message_count() const151*6777b538SAndroid Build Coastguard Worker   int message_count() const { return message_count_; }
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker  private:
154*6777b538SAndroid Build Coastguard Worker   size_t message_size_;
155*6777b538SAndroid Build Coastguard Worker   int message_count_;
156*6777b538SAndroid Build Coastguard Worker };
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker class InterfacePassingTestParams {
159*6777b538SAndroid Build Coastguard Worker  public:
InterfacePassingTestParams(size_t rounds,size_t num_interfaces)160*6777b538SAndroid Build Coastguard Worker   InterfacePassingTestParams(size_t rounds, size_t num_interfaces)
161*6777b538SAndroid Build Coastguard Worker       : rounds_(rounds), num_interfaces_(num_interfaces) {}
162*6777b538SAndroid Build Coastguard Worker 
rounds() const163*6777b538SAndroid Build Coastguard Worker   size_t rounds() const { return rounds_; }
num_interfaces() const164*6777b538SAndroid Build Coastguard Worker   size_t num_interfaces() const { return num_interfaces_; }
165*6777b538SAndroid Build Coastguard Worker 
166*6777b538SAndroid Build Coastguard Worker  private:
167*6777b538SAndroid Build Coastguard Worker   size_t rounds_;
168*6777b538SAndroid Build Coastguard Worker   size_t num_interfaces_;
169*6777b538SAndroid Build Coastguard Worker };
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker #ifdef NDEBUG
172*6777b538SAndroid Build Coastguard Worker const int kMultiplier = 100;
173*6777b538SAndroid Build Coastguard Worker #else
174*6777b538SAndroid Build Coastguard Worker   // Debug builds on Windows run these tests orders of magnitude more slowly.
175*6777b538SAndroid Build Coastguard Worker const int kMultiplier = 1;
176*6777b538SAndroid Build Coastguard Worker #endif
177*6777b538SAndroid Build Coastguard Worker 
GetDefaultTestParams()178*6777b538SAndroid Build Coastguard Worker std::vector<PingPongTestParams> GetDefaultTestParams() {
179*6777b538SAndroid Build Coastguard Worker   // Test several sizes. We use 12^N for message size, and limit the message
180*6777b538SAndroid Build Coastguard Worker   // count to keep the test duration reasonable.
181*6777b538SAndroid Build Coastguard Worker   std::vector<PingPongTestParams> list;
182*6777b538SAndroid Build Coastguard Worker   list.push_back(PingPongTestParams(12, 500 * kMultiplier));
183*6777b538SAndroid Build Coastguard Worker   list.push_back(PingPongTestParams(144, 500 * kMultiplier));
184*6777b538SAndroid Build Coastguard Worker   list.push_back(PingPongTestParams(1728, 500 * kMultiplier));
185*6777b538SAndroid Build Coastguard Worker   list.push_back(PingPongTestParams(20736, 120 * kMultiplier));
186*6777b538SAndroid Build Coastguard Worker   list.push_back(PingPongTestParams(248832, 10 * kMultiplier));
187*6777b538SAndroid Build Coastguard Worker   return list;
188*6777b538SAndroid Build Coastguard Worker }
189*6777b538SAndroid Build Coastguard Worker 
GetDefaultInterfacePassingTestParams()190*6777b538SAndroid Build Coastguard Worker std::vector<InterfacePassingTestParams> GetDefaultInterfacePassingTestParams() {
191*6777b538SAndroid Build Coastguard Worker   std::vector<InterfacePassingTestParams> list;
192*6777b538SAndroid Build Coastguard Worker   list.push_back({500 * kMultiplier, 0});
193*6777b538SAndroid Build Coastguard Worker   list.push_back({500 * kMultiplier, 1});
194*6777b538SAndroid Build Coastguard Worker   list.push_back({500 * kMultiplier, 2});
195*6777b538SAndroid Build Coastguard Worker   list.push_back({500 * kMultiplier, 4});
196*6777b538SAndroid Build Coastguard Worker   list.push_back({500 * kMultiplier, 8});
197*6777b538SAndroid Build Coastguard Worker   return list;
198*6777b538SAndroid Build Coastguard Worker }
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker class MojoChannelPerfTest : public IPCChannelMojoTestBase {
201*6777b538SAndroid Build Coastguard Worker  public:
202*6777b538SAndroid Build Coastguard Worker   MojoChannelPerfTest() = default;
203*6777b538SAndroid Build Coastguard Worker   ~MojoChannelPerfTest() override = default;
204*6777b538SAndroid Build Coastguard Worker 
RunTestChannelProxyPingPong()205*6777b538SAndroid Build Coastguard Worker   void RunTestChannelProxyPingPong() {
206*6777b538SAndroid Build Coastguard Worker     Init("MojoPerfTestClient");
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker     // Set up IPC channel and start client.
209*6777b538SAndroid Build Coastguard Worker     PerformanceChannelListener listener("ChannelProxy");
210*6777b538SAndroid Build Coastguard Worker     auto channel_proxy = IPC::ChannelProxy::Create(
211*6777b538SAndroid Build Coastguard Worker         TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
212*6777b538SAndroid Build Coastguard Worker         GetIOThreadTaskRunner(),
213*6777b538SAndroid Build Coastguard Worker         base::SingleThreadTaskRunner::GetCurrentDefault());
214*6777b538SAndroid Build Coastguard Worker     listener.Init(channel_proxy.get());
215*6777b538SAndroid Build Coastguard Worker 
216*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
217*6777b538SAndroid Build Coastguard Worker     std::vector<PingPongTestParams> params = GetDefaultTestParams();
218*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); i++) {
219*6777b538SAndroid Build Coastguard Worker       listener.SetTestParams(params[i].message_count(),
220*6777b538SAndroid Build Coastguard Worker                              params[i].message_size(), false);
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker       // This initial message will kick-start the ping-pong of messages.
223*6777b538SAndroid Build Coastguard Worker       channel_proxy->Send(new TestMsg_Hello);
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker       // Run message loop.
226*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
227*6777b538SAndroid Build Coastguard Worker       listener.set_quit_closure(loop.QuitWhenIdleClosure());
228*6777b538SAndroid Build Coastguard Worker       loop.Run();
229*6777b538SAndroid Build Coastguard Worker     }
230*6777b538SAndroid Build Coastguard Worker 
231*6777b538SAndroid Build Coastguard Worker     // Send quit message.
232*6777b538SAndroid Build Coastguard Worker     channel_proxy->Send(new TestMsg_Quit);
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(WaitForClientShutdown());
235*6777b538SAndroid Build Coastguard Worker     channel_proxy.reset();
236*6777b538SAndroid Build Coastguard Worker   }
237*6777b538SAndroid Build Coastguard Worker 
RunTestChannelProxySyncPing()238*6777b538SAndroid Build Coastguard Worker   void RunTestChannelProxySyncPing() {
239*6777b538SAndroid Build Coastguard Worker     Init("MojoPerfTestClient");
240*6777b538SAndroid Build Coastguard Worker 
241*6777b538SAndroid Build Coastguard Worker     // Set up IPC channel and start client.
242*6777b538SAndroid Build Coastguard Worker     PerformanceChannelListener listener("ChannelProxy");
243*6777b538SAndroid Build Coastguard Worker     base::WaitableEvent shutdown_event(
244*6777b538SAndroid Build Coastguard Worker         base::WaitableEvent::ResetPolicy::MANUAL,
245*6777b538SAndroid Build Coastguard Worker         base::WaitableEvent::InitialState::NOT_SIGNALED);
246*6777b538SAndroid Build Coastguard Worker     auto channel_proxy = IPC::SyncChannel::Create(
247*6777b538SAndroid Build Coastguard Worker         TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
248*6777b538SAndroid Build Coastguard Worker         GetIOThreadTaskRunner(),
249*6777b538SAndroid Build Coastguard Worker         base::SingleThreadTaskRunner::GetCurrentDefault(), false,
250*6777b538SAndroid Build Coastguard Worker         &shutdown_event);
251*6777b538SAndroid Build Coastguard Worker     listener.Init(channel_proxy.get());
252*6777b538SAndroid Build Coastguard Worker 
253*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
254*6777b538SAndroid Build Coastguard Worker     std::vector<PingPongTestParams> params = GetDefaultTestParams();
255*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); i++) {
256*6777b538SAndroid Build Coastguard Worker       listener.SetTestParams(params[i].message_count(),
257*6777b538SAndroid Build Coastguard Worker                              params[i].message_size(), true);
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker       // This initial message will kick-start the ping-pong of messages.
260*6777b538SAndroid Build Coastguard Worker       channel_proxy->Send(new TestMsg_Hello);
261*6777b538SAndroid Build Coastguard Worker 
262*6777b538SAndroid Build Coastguard Worker       // Run message loop.
263*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
264*6777b538SAndroid Build Coastguard Worker       listener.set_quit_closure(loop.QuitWhenIdleClosure());
265*6777b538SAndroid Build Coastguard Worker       loop.Run();
266*6777b538SAndroid Build Coastguard Worker     }
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker     // Send quit message.
269*6777b538SAndroid Build Coastguard Worker     channel_proxy->Send(new TestMsg_Quit);
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(WaitForClientShutdown());
272*6777b538SAndroid Build Coastguard Worker     channel_proxy.reset();
273*6777b538SAndroid Build Coastguard Worker   }
274*6777b538SAndroid Build Coastguard Worker };
275*6777b538SAndroid Build Coastguard Worker 
TEST_F(MojoChannelPerfTest,ChannelProxyPingPong)276*6777b538SAndroid Build Coastguard Worker TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) {
277*6777b538SAndroid Build Coastguard Worker   RunTestChannelProxyPingPong();
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
280*6777b538SAndroid Build Coastguard Worker   run_loop.RunUntilIdle();
281*6777b538SAndroid Build Coastguard Worker }
282*6777b538SAndroid Build Coastguard Worker 
TEST_F(MojoChannelPerfTest,ChannelProxySyncPing)283*6777b538SAndroid Build Coastguard Worker TEST_F(MojoChannelPerfTest, ChannelProxySyncPing) {
284*6777b538SAndroid Build Coastguard Worker   RunTestChannelProxySyncPing();
285*6777b538SAndroid Build Coastguard Worker 
286*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
287*6777b538SAndroid Build Coastguard Worker   run_loop.RunUntilIdle();
288*6777b538SAndroid Build Coastguard Worker }
289*6777b538SAndroid Build Coastguard Worker 
MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain)290*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {
291*6777b538SAndroid Build Coastguard Worker   MojoPerfTestClient client;
292*6777b538SAndroid Build Coastguard Worker   int rv = mojo::core::test::MultiprocessTestHelper::RunClientMain(
293*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&MojoPerfTestClient::Run, base::Unretained(&client)),
294*6777b538SAndroid Build Coastguard Worker       true /* pass_pipe_ownership_to_main */);
295*6777b538SAndroid Build Coastguard Worker 
296*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
297*6777b538SAndroid Build Coastguard Worker   run_loop.RunUntilIdle();
298*6777b538SAndroid Build Coastguard Worker 
299*6777b538SAndroid Build Coastguard Worker   return rv;
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker class MojoInterfacePerfTest : public mojo::core::test::MojoTestBase {
303*6777b538SAndroid Build Coastguard Worker  public:
MojoInterfacePerfTest()304*6777b538SAndroid Build Coastguard Worker   MojoInterfacePerfTest() : message_count_(0), count_down_(0) {}
305*6777b538SAndroid Build Coastguard Worker 
306*6777b538SAndroid Build Coastguard Worker   MojoInterfacePerfTest(const MojoInterfacePerfTest&) = delete;
307*6777b538SAndroid Build Coastguard Worker   MojoInterfacePerfTest& operator=(const MojoInterfacePerfTest&) = delete;
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker  protected:
RunPingPongServer(MojoHandle mp,const std::string & label)310*6777b538SAndroid Build Coastguard Worker   void RunPingPongServer(MojoHandle mp, const std::string& label) {
311*6777b538SAndroid Build Coastguard Worker     label_ = label;
312*6777b538SAndroid Build Coastguard Worker 
313*6777b538SAndroid Build Coastguard Worker     mojo::MessagePipeHandle mp_handle(mp);
314*6777b538SAndroid Build Coastguard Worker     mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
315*6777b538SAndroid Build Coastguard Worker     ping_receiver_.Bind(
316*6777b538SAndroid Build Coastguard Worker         mojo::PendingRemote<IPC::mojom::Reflector>(std::move(scoped_mp), 0u));
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
319*6777b538SAndroid Build Coastguard Worker     std::vector<PingPongTestParams> params = GetDefaultTestParams();
320*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); i++) {
321*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
322*6777b538SAndroid Build Coastguard Worker       ping_receiver_->Ping(
323*6777b538SAndroid Build Coastguard Worker           "hello",
324*6777b538SAndroid Build Coastguard Worker           base::BindOnce(&MojoInterfacePerfTest::OnPong, base::Unretained(this),
325*6777b538SAndroid Build Coastguard Worker                          loop.QuitWhenIdleClosure()));
326*6777b538SAndroid Build Coastguard Worker       message_count_ = count_down_ = params[i].message_count();
327*6777b538SAndroid Build Coastguard Worker       payload_ = std::string(params[i].message_size(), 'a');
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker       loop.Run();
330*6777b538SAndroid Build Coastguard Worker     }
331*6777b538SAndroid Build Coastguard Worker 
332*6777b538SAndroid Build Coastguard Worker     ping_receiver_->Quit();
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker     std::ignore = ping_receiver_.Unbind().PassPipe().release();
335*6777b538SAndroid Build Coastguard Worker   }
336*6777b538SAndroid Build Coastguard Worker 
OnPong(base::OnceClosure quit_closure,const std::string & value)337*6777b538SAndroid Build Coastguard Worker   void OnPong(base::OnceClosure quit_closure, const std::string& value) {
338*6777b538SAndroid Build Coastguard Worker     if (value == "hello") {
339*6777b538SAndroid Build Coastguard Worker       DCHECK(!perf_logger_.get());
340*6777b538SAndroid Build Coastguard Worker       std::string test_name =
341*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("IPC_%s_Perf_%dx_%zu", label_.c_str(),
342*6777b538SAndroid Build Coastguard Worker                              message_count_, payload_.size());
343*6777b538SAndroid Build Coastguard Worker       perf_logger_ = std::make_unique<base::PerfTimeLogger>(test_name.c_str());
344*6777b538SAndroid Build Coastguard Worker     } else {
345*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(payload_.size(), value.size());
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker       CHECK(count_down_ > 0);
348*6777b538SAndroid Build Coastguard Worker       count_down_--;
349*6777b538SAndroid Build Coastguard Worker       if (count_down_ == 0) {
350*6777b538SAndroid Build Coastguard Worker         perf_logger_.reset();
351*6777b538SAndroid Build Coastguard Worker         if (!quit_closure.is_null()) {
352*6777b538SAndroid Build Coastguard Worker           std::move(quit_closure).Run();
353*6777b538SAndroid Build Coastguard Worker         }
354*6777b538SAndroid Build Coastguard Worker         return;
355*6777b538SAndroid Build Coastguard Worker       }
356*6777b538SAndroid Build Coastguard Worker     }
357*6777b538SAndroid Build Coastguard Worker 
358*6777b538SAndroid Build Coastguard Worker     if (sync_) {
359*6777b538SAndroid Build Coastguard Worker       for (int i = 0; i < count_down_; ++i) {
360*6777b538SAndroid Build Coastguard Worker         std::string response;
361*6777b538SAndroid Build Coastguard Worker         ping_receiver_->SyncPing(payload_, &response);
362*6777b538SAndroid Build Coastguard Worker         DCHECK_EQ(response, payload_);
363*6777b538SAndroid Build Coastguard Worker       }
364*6777b538SAndroid Build Coastguard Worker       perf_logger_.reset();
365*6777b538SAndroid Build Coastguard Worker       if (!quit_closure.is_null()) {
366*6777b538SAndroid Build Coastguard Worker         std::move(quit_closure).Run();
367*6777b538SAndroid Build Coastguard Worker       }
368*6777b538SAndroid Build Coastguard Worker     } else {
369*6777b538SAndroid Build Coastguard Worker       ping_receiver_->Ping(
370*6777b538SAndroid Build Coastguard Worker           payload_,
371*6777b538SAndroid Build Coastguard Worker           base::BindOnce(&MojoInterfacePerfTest::OnPong, base::Unretained(this),
372*6777b538SAndroid Build Coastguard Worker                          std::move(quit_closure)));
373*6777b538SAndroid Build Coastguard Worker     }
374*6777b538SAndroid Build Coastguard Worker   }
375*6777b538SAndroid Build Coastguard Worker 
RunPingPongClient(MojoHandle mp)376*6777b538SAndroid Build Coastguard Worker   static int RunPingPongClient(MojoHandle mp) {
377*6777b538SAndroid Build Coastguard Worker     mojo::MessagePipeHandle mp_handle(mp);
378*6777b538SAndroid Build Coastguard Worker     mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
379*6777b538SAndroid Build Coastguard Worker 
380*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
381*6777b538SAndroid Build Coastguard Worker     // In single process mode, this is running in a task and by default other
382*6777b538SAndroid Build Coastguard Worker     // tasks (in particular, the binding) won't run. To keep the single process
383*6777b538SAndroid Build Coastguard Worker     // and multi-process code paths the same, enable nestable tasks.
384*6777b538SAndroid Build Coastguard Worker     base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
385*6777b538SAndroid Build Coastguard Worker     ReflectorImpl impl(std::move(scoped_mp), run_loop.QuitWhenIdleClosure());
386*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
387*6777b538SAndroid Build Coastguard Worker     return 0;
388*6777b538SAndroid Build Coastguard Worker   }
389*6777b538SAndroid Build Coastguard Worker 
390*6777b538SAndroid Build Coastguard Worker   bool sync_ = false;
391*6777b538SAndroid Build Coastguard Worker 
392*6777b538SAndroid Build Coastguard Worker  private:
393*6777b538SAndroid Build Coastguard Worker   int message_count_;
394*6777b538SAndroid Build Coastguard Worker   int count_down_;
395*6777b538SAndroid Build Coastguard Worker   std::string label_;
396*6777b538SAndroid Build Coastguard Worker   std::string payload_;
397*6777b538SAndroid Build Coastguard Worker   mojo::Remote<IPC::mojom::Reflector> ping_receiver_;
398*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::PerfTimeLogger> perf_logger_;
399*6777b538SAndroid Build Coastguard Worker };
400*6777b538SAndroid Build Coastguard Worker 
401*6777b538SAndroid Build Coastguard Worker class InterfacePassingTestDriverImpl : public mojom::InterfacePassingTestDriver,
402*6777b538SAndroid Build Coastguard Worker                                        public mojom::PingReceiver {
403*6777b538SAndroid Build Coastguard Worker  public:
InterfacePassingTestDriverImpl(mojo::ScopedMessagePipeHandle handle,base::OnceClosure quit_closure)404*6777b538SAndroid Build Coastguard Worker   InterfacePassingTestDriverImpl(mojo::ScopedMessagePipeHandle handle,
405*6777b538SAndroid Build Coastguard Worker                                  base::OnceClosure quit_closure)
406*6777b538SAndroid Build Coastguard Worker       : receiver_(this,
407*6777b538SAndroid Build Coastguard Worker                   mojo::PendingReceiver<mojom::InterfacePassingTestDriver>(
408*6777b538SAndroid Build Coastguard Worker                       std::move(handle))),
409*6777b538SAndroid Build Coastguard Worker         quit_closure_(std::move(quit_closure)) {}
~InterfacePassingTestDriverImpl()410*6777b538SAndroid Build Coastguard Worker   ~InterfacePassingTestDriverImpl() override {
411*6777b538SAndroid Build Coastguard Worker     std::ignore = receiver_.Unbind().PassPipe().release();
412*6777b538SAndroid Build Coastguard Worker   }
413*6777b538SAndroid Build Coastguard Worker 
414*6777b538SAndroid Build Coastguard Worker  private:
415*6777b538SAndroid Build Coastguard Worker   // mojom::InterfacePassingTestDriver implementation:
Init(InitCallback callback)416*6777b538SAndroid Build Coastguard Worker   void Init(InitCallback callback) override { std::move(callback).Run(); }
417*6777b538SAndroid Build Coastguard Worker 
GetPingReceiver(std::vector<mojo::PendingReceiver<mojom::PingReceiver>> receivers,GetPingReceiverCallback callback)418*6777b538SAndroid Build Coastguard Worker   void GetPingReceiver(
419*6777b538SAndroid Build Coastguard Worker       std::vector<mojo::PendingReceiver<mojom::PingReceiver>> receivers,
420*6777b538SAndroid Build Coastguard Worker       GetPingReceiverCallback callback) override {
421*6777b538SAndroid Build Coastguard Worker     for (auto& receiver : receivers)
422*6777b538SAndroid Build Coastguard Worker       ping_receiver_receivers_.Add(this, std::move(receiver));
423*6777b538SAndroid Build Coastguard Worker     ping_receiver_receivers_.Clear();
424*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
425*6777b538SAndroid Build Coastguard Worker   }
426*6777b538SAndroid Build Coastguard Worker 
GetAssociatedPingReceiver(std::vector<mojo::PendingAssociatedReceiver<mojom::PingReceiver>> receivers,GetAssociatedPingReceiverCallback callback)427*6777b538SAndroid Build Coastguard Worker   void GetAssociatedPingReceiver(
428*6777b538SAndroid Build Coastguard Worker       std::vector<mojo::PendingAssociatedReceiver<mojom::PingReceiver>>
429*6777b538SAndroid Build Coastguard Worker           receivers,
430*6777b538SAndroid Build Coastguard Worker       GetAssociatedPingReceiverCallback callback) override {
431*6777b538SAndroid Build Coastguard Worker     for (auto& receiver : receivers)
432*6777b538SAndroid Build Coastguard Worker       ping_receiver_associated_receivers_.Add(this, std::move(receiver));
433*6777b538SAndroid Build Coastguard Worker     ping_receiver_associated_receivers_.Clear();
434*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run();
435*6777b538SAndroid Build Coastguard Worker   }
436*6777b538SAndroid Build Coastguard Worker 
Quit()437*6777b538SAndroid Build Coastguard Worker   void Quit() override {
438*6777b538SAndroid Build Coastguard Worker     if (!quit_closure_.is_null()) {
439*6777b538SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
440*6777b538SAndroid Build Coastguard Worker     }
441*6777b538SAndroid Build Coastguard Worker   }
442*6777b538SAndroid Build Coastguard Worker 
443*6777b538SAndroid Build Coastguard Worker   // mojom::PingReceiver implementation:
Ping(PingCallback callback)444*6777b538SAndroid Build Coastguard Worker   void Ping(PingCallback callback) override { std::move(callback).Run(); }
445*6777b538SAndroid Build Coastguard Worker 
446*6777b538SAndroid Build Coastguard Worker   mojo::ReceiverSet<mojom::PingReceiver> ping_receiver_receivers_;
447*6777b538SAndroid Build Coastguard Worker   mojo::AssociatedReceiverSet<mojom::PingReceiver>
448*6777b538SAndroid Build Coastguard Worker       ping_receiver_associated_receivers_;
449*6777b538SAndroid Build Coastguard Worker   mojo::Receiver<mojom::InterfacePassingTestDriver> receiver_;
450*6777b538SAndroid Build Coastguard Worker 
451*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
452*6777b538SAndroid Build Coastguard Worker };
453*6777b538SAndroid Build Coastguard Worker 
454*6777b538SAndroid Build Coastguard Worker class MojoInterfacePassingPerfTest : public mojo::core::test::MojoTestBase {
455*6777b538SAndroid Build Coastguard Worker  public:
456*6777b538SAndroid Build Coastguard Worker   MojoInterfacePassingPerfTest() = default;
457*6777b538SAndroid Build Coastguard Worker 
458*6777b538SAndroid Build Coastguard Worker   MojoInterfacePassingPerfTest(const MojoInterfacePassingPerfTest&) = delete;
459*6777b538SAndroid Build Coastguard Worker   MojoInterfacePassingPerfTest& operator=(const MojoInterfacePassingPerfTest&) =
460*6777b538SAndroid Build Coastguard Worker       delete;
461*6777b538SAndroid Build Coastguard Worker 
462*6777b538SAndroid Build Coastguard Worker  protected:
RunInterfacePassingServer(MojoHandle mp,const std::string & label,bool associated)463*6777b538SAndroid Build Coastguard Worker   void RunInterfacePassingServer(MojoHandle mp,
464*6777b538SAndroid Build Coastguard Worker                                  const std::string& label,
465*6777b538SAndroid Build Coastguard Worker                                  bool associated) {
466*6777b538SAndroid Build Coastguard Worker     label_ = label;
467*6777b538SAndroid Build Coastguard Worker     associated_ = associated;
468*6777b538SAndroid Build Coastguard Worker 
469*6777b538SAndroid Build Coastguard Worker     mojo::MessagePipeHandle mp_handle(mp);
470*6777b538SAndroid Build Coastguard Worker     mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
471*6777b538SAndroid Build Coastguard Worker     driver_remote_.Bind(mojo::PendingRemote<mojom::InterfacePassingTestDriver>(
472*6777b538SAndroid Build Coastguard Worker         std::move(scoped_mp), 0u));
473*6777b538SAndroid Build Coastguard Worker 
474*6777b538SAndroid Build Coastguard Worker     auto params = GetDefaultInterfacePassingTestParams();
475*6777b538SAndroid Build Coastguard Worker 
476*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
477*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); ++i) {
478*6777b538SAndroid Build Coastguard Worker       driver_remote_->Init(
479*6777b538SAndroid Build Coastguard Worker           base::BindOnce(&MojoInterfacePassingPerfTest::OnInitCallback,
480*6777b538SAndroid Build Coastguard Worker                          base::Unretained(this)));
481*6777b538SAndroid Build Coastguard Worker       rounds_ = count_down_ = params[i].rounds();
482*6777b538SAndroid Build Coastguard Worker       num_interfaces_ = params[i].num_interfaces();
483*6777b538SAndroid Build Coastguard Worker 
484*6777b538SAndroid Build Coastguard Worker       base::RunLoop run_loop;
485*6777b538SAndroid Build Coastguard Worker       quit_closure_ = run_loop.QuitWhenIdleClosure();
486*6777b538SAndroid Build Coastguard Worker       run_loop.Run();
487*6777b538SAndroid Build Coastguard Worker     }
488*6777b538SAndroid Build Coastguard Worker 
489*6777b538SAndroid Build Coastguard Worker     driver_remote_->Quit();
490*6777b538SAndroid Build Coastguard Worker 
491*6777b538SAndroid Build Coastguard Worker     std::ignore = driver_remote_.Unbind().PassPipe().release();
492*6777b538SAndroid Build Coastguard Worker   }
493*6777b538SAndroid Build Coastguard Worker 
OnInitCallback()494*6777b538SAndroid Build Coastguard Worker   void OnInitCallback() {
495*6777b538SAndroid Build Coastguard Worker     DCHECK(!perf_logger_.get());
496*6777b538SAndroid Build Coastguard Worker     std::string test_name = base::StringPrintf(
497*6777b538SAndroid Build Coastguard Worker         "IPC_%s_Perf_%zux_%zu", label_.c_str(), rounds_, num_interfaces_);
498*6777b538SAndroid Build Coastguard Worker     perf_logger_ = std::make_unique<base::PerfTimeLogger>(test_name.c_str());
499*6777b538SAndroid Build Coastguard Worker 
500*6777b538SAndroid Build Coastguard Worker     DoNextRound();
501*6777b538SAndroid Build Coastguard Worker   }
502*6777b538SAndroid Build Coastguard Worker 
DoNextRound()503*6777b538SAndroid Build Coastguard Worker   void DoNextRound() {
504*6777b538SAndroid Build Coastguard Worker     if (associated_) {
505*6777b538SAndroid Build Coastguard Worker       std::vector<mojo::AssociatedRemote<mojom::PingReceiver>>
506*6777b538SAndroid Build Coastguard Worker           associated_remotes(num_interfaces_);
507*6777b538SAndroid Build Coastguard Worker 
508*6777b538SAndroid Build Coastguard Worker       std::vector<mojo::PendingAssociatedReceiver<mojom::PingReceiver>>
509*6777b538SAndroid Build Coastguard Worker           receivers(num_interfaces_);
510*6777b538SAndroid Build Coastguard Worker       for (size_t i = 0; i < num_interfaces_; ++i) {
511*6777b538SAndroid Build Coastguard Worker         receivers[i] = associated_remotes[i].BindNewEndpointAndPassReceiver();
512*6777b538SAndroid Build Coastguard Worker         // Force the interface pointer to do full initialization.
513*6777b538SAndroid Build Coastguard Worker         associated_remotes[i].get();
514*6777b538SAndroid Build Coastguard Worker       }
515*6777b538SAndroid Build Coastguard Worker 
516*6777b538SAndroid Build Coastguard Worker       driver_remote_->GetAssociatedPingReceiver(
517*6777b538SAndroid Build Coastguard Worker           std::move(receivers),
518*6777b538SAndroid Build Coastguard Worker           base::BindOnce(&MojoInterfacePassingPerfTest::OnGetReceiverCallback,
519*6777b538SAndroid Build Coastguard Worker                          base::Unretained(this)));
520*6777b538SAndroid Build Coastguard Worker     } else {
521*6777b538SAndroid Build Coastguard Worker       std::vector<mojo::Remote<mojom::PingReceiver>> remotes(num_interfaces_);
522*6777b538SAndroid Build Coastguard Worker 
523*6777b538SAndroid Build Coastguard Worker       std::vector<mojo::PendingReceiver<mojom::PingReceiver>> receivers(
524*6777b538SAndroid Build Coastguard Worker           num_interfaces_);
525*6777b538SAndroid Build Coastguard Worker       for (size_t i = 0; i < num_interfaces_; ++i) {
526*6777b538SAndroid Build Coastguard Worker         receivers[i] = remotes[i].BindNewPipeAndPassReceiver();
527*6777b538SAndroid Build Coastguard Worker         // Force the interface pointer to do full initialization.
528*6777b538SAndroid Build Coastguard Worker         remotes[i].get();
529*6777b538SAndroid Build Coastguard Worker       }
530*6777b538SAndroid Build Coastguard Worker 
531*6777b538SAndroid Build Coastguard Worker       driver_remote_->GetPingReceiver(
532*6777b538SAndroid Build Coastguard Worker           std::move(receivers),
533*6777b538SAndroid Build Coastguard Worker           base::BindOnce(&MojoInterfacePassingPerfTest::OnGetReceiverCallback,
534*6777b538SAndroid Build Coastguard Worker                          base::Unretained(this)));
535*6777b538SAndroid Build Coastguard Worker     }
536*6777b538SAndroid Build Coastguard Worker   }
537*6777b538SAndroid Build Coastguard Worker 
OnGetReceiverCallback()538*6777b538SAndroid Build Coastguard Worker   void OnGetReceiverCallback() {
539*6777b538SAndroid Build Coastguard Worker     CHECK_GT(count_down_, 0u);
540*6777b538SAndroid Build Coastguard Worker     count_down_--;
541*6777b538SAndroid Build Coastguard Worker 
542*6777b538SAndroid Build Coastguard Worker     if (count_down_ == 0) {
543*6777b538SAndroid Build Coastguard Worker       perf_logger_.reset();
544*6777b538SAndroid Build Coastguard Worker       if (!quit_closure_.is_null()) {
545*6777b538SAndroid Build Coastguard Worker         std::move(quit_closure_).Run();
546*6777b538SAndroid Build Coastguard Worker       }
547*6777b538SAndroid Build Coastguard Worker       return;
548*6777b538SAndroid Build Coastguard Worker     }
549*6777b538SAndroid Build Coastguard Worker 
550*6777b538SAndroid Build Coastguard Worker     DoNextRound();
551*6777b538SAndroid Build Coastguard Worker   }
552*6777b538SAndroid Build Coastguard Worker 
RunInterfacePassingClient(MojoHandle mp)553*6777b538SAndroid Build Coastguard Worker   static int RunInterfacePassingClient(MojoHandle mp) {
554*6777b538SAndroid Build Coastguard Worker     mojo::MessagePipeHandle mp_handle(mp);
555*6777b538SAndroid Build Coastguard Worker     mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
558*6777b538SAndroid Build Coastguard Worker     // In single process mode, this is running in a task and by default other
559*6777b538SAndroid Build Coastguard Worker     // tasks (in particular, the binding) won't run. To keep the single process
560*6777b538SAndroid Build Coastguard Worker     // and multi-process code paths the same, enable nestable tasks.
561*6777b538SAndroid Build Coastguard Worker     base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
562*6777b538SAndroid Build Coastguard Worker     InterfacePassingTestDriverImpl impl(std::move(scoped_mp),
563*6777b538SAndroid Build Coastguard Worker                                         run_loop.QuitWhenIdleClosure());
564*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
565*6777b538SAndroid Build Coastguard Worker     return 0;
566*6777b538SAndroid Build Coastguard Worker   }
567*6777b538SAndroid Build Coastguard Worker 
568*6777b538SAndroid Build Coastguard Worker  private:
569*6777b538SAndroid Build Coastguard Worker   size_t rounds_ = 0;
570*6777b538SAndroid Build Coastguard Worker   size_t count_down_ = 0;
571*6777b538SAndroid Build Coastguard Worker   size_t num_interfaces_ = 0;
572*6777b538SAndroid Build Coastguard Worker   std::string label_;
573*6777b538SAndroid Build Coastguard Worker   bool associated_ = false;
574*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::PerfTimeLogger> perf_logger_;
575*6777b538SAndroid Build Coastguard Worker 
576*6777b538SAndroid Build Coastguard Worker   mojo::Remote<mojom::InterfacePassingTestDriver> driver_remote_;
577*6777b538SAndroid Build Coastguard Worker 
578*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
579*6777b538SAndroid Build Coastguard Worker };
580*6777b538SAndroid Build Coastguard Worker 
DEFINE_TEST_CLIENT_WITH_PIPE(InterfacePassingClient,MojoInterfacePassingPerfTest,h)581*6777b538SAndroid Build Coastguard Worker DEFINE_TEST_CLIENT_WITH_PIPE(InterfacePassingClient,
582*6777b538SAndroid Build Coastguard Worker                              MojoInterfacePassingPerfTest,
583*6777b538SAndroid Build Coastguard Worker                              h) {
584*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
585*6777b538SAndroid Build Coastguard Worker   return RunInterfacePassingClient(h);
586*6777b538SAndroid Build Coastguard Worker }
587*6777b538SAndroid Build Coastguard Worker 
588*6777b538SAndroid Build Coastguard Worker enum class InProcessMessageMode {
589*6777b538SAndroid Build Coastguard Worker   kSerialized,
590*6777b538SAndroid Build Coastguard Worker   kUnserialized,
591*6777b538SAndroid Build Coastguard Worker };
592*6777b538SAndroid Build Coastguard Worker 
593*6777b538SAndroid Build Coastguard Worker template <class TestBase>
594*6777b538SAndroid Build Coastguard Worker class InProcessPerfTest
595*6777b538SAndroid Build Coastguard Worker     : public TestBase,
596*6777b538SAndroid Build Coastguard Worker       public testing::WithParamInterface<InProcessMessageMode> {
597*6777b538SAndroid Build Coastguard Worker  public:
InProcessPerfTest()598*6777b538SAndroid Build Coastguard Worker   InProcessPerfTest() {
599*6777b538SAndroid Build Coastguard Worker     switch (GetParam()) {
600*6777b538SAndroid Build Coastguard Worker       case InProcessMessageMode::kSerialized:
601*6777b538SAndroid Build Coastguard Worker         mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(
602*6777b538SAndroid Build Coastguard Worker             mojo::Connector::OutgoingSerializationMode::kEager,
603*6777b538SAndroid Build Coastguard Worker             mojo::Connector::IncomingSerializationMode::kDispatchAsIs);
604*6777b538SAndroid Build Coastguard Worker         break;
605*6777b538SAndroid Build Coastguard Worker       case InProcessMessageMode::kUnserialized:
606*6777b538SAndroid Build Coastguard Worker         mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(
607*6777b538SAndroid Build Coastguard Worker             mojo::Connector::OutgoingSerializationMode::kLazy,
608*6777b538SAndroid Build Coastguard Worker             mojo::Connector::IncomingSerializationMode::kDispatchAsIs);
609*6777b538SAndroid Build Coastguard Worker         break;
610*6777b538SAndroid Build Coastguard Worker     }
611*6777b538SAndroid Build Coastguard Worker   }
612*6777b538SAndroid Build Coastguard Worker };
613*6777b538SAndroid Build Coastguard Worker 
614*6777b538SAndroid Build Coastguard Worker using MojoInProcessInterfacePerfTest = InProcessPerfTest<MojoInterfacePerfTest>;
615*6777b538SAndroid Build Coastguard Worker using MojoInProcessInterfacePassingPerfTest =
616*6777b538SAndroid Build Coastguard Worker     InProcessPerfTest<MojoInterfacePassingPerfTest>;
617*6777b538SAndroid Build Coastguard Worker 
DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient,MojoInterfacePerfTest,h)618*6777b538SAndroid Build Coastguard Worker DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) {
619*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
620*6777b538SAndroid Build Coastguard Worker   return RunPingPongClient(h);
621*6777b538SAndroid Build Coastguard Worker }
622*6777b538SAndroid Build Coastguard Worker 
623*6777b538SAndroid Build Coastguard Worker // Similar to MojoChannelPerfTest above, but uses a Mojo interface instead of
624*6777b538SAndroid Build Coastguard Worker // raw IPC::Messages.
TEST_F(MojoInterfacePerfTest,MultiprocessPingPong)625*6777b538SAndroid Build Coastguard Worker TEST_F(MojoInterfacePerfTest, MultiprocessPingPong) {
626*6777b538SAndroid Build Coastguard Worker   RunTestClient("PingPongClient", [&](MojoHandle h) {
627*6777b538SAndroid Build Coastguard Worker     base::test::SingleThreadTaskEnvironment task_environment;
628*6777b538SAndroid Build Coastguard Worker     RunPingPongServer(h, "Multiprocess");
629*6777b538SAndroid Build Coastguard Worker   });
630*6777b538SAndroid Build Coastguard Worker }
631*6777b538SAndroid Build Coastguard Worker 
TEST_F(MojoInterfacePerfTest,MultiprocessSyncPing)632*6777b538SAndroid Build Coastguard Worker TEST_F(MojoInterfacePerfTest, MultiprocessSyncPing) {
633*6777b538SAndroid Build Coastguard Worker   sync_ = true;
634*6777b538SAndroid Build Coastguard Worker   RunTestClient("PingPongClient", [&](MojoHandle h) {
635*6777b538SAndroid Build Coastguard Worker     base::test::SingleThreadTaskEnvironment task_environment;
636*6777b538SAndroid Build Coastguard Worker     RunPingPongServer(h, "MultiprocessSync");
637*6777b538SAndroid Build Coastguard Worker   });
638*6777b538SAndroid Build Coastguard Worker }
639*6777b538SAndroid Build Coastguard Worker 
TEST_F(MojoInterfacePassingPerfTest,MultiprocessInterfacePassing)640*6777b538SAndroid Build Coastguard Worker TEST_F(MojoInterfacePassingPerfTest, MultiprocessInterfacePassing) {
641*6777b538SAndroid Build Coastguard Worker   RunTestClient("InterfacePassingClient", [&](MojoHandle h) {
642*6777b538SAndroid Build Coastguard Worker     base::test::SingleThreadTaskEnvironment task_environment;
643*6777b538SAndroid Build Coastguard Worker     RunInterfacePassingServer(h, "InterfacePassing", false /* associated */);
644*6777b538SAndroid Build Coastguard Worker   });
645*6777b538SAndroid Build Coastguard Worker }
646*6777b538SAndroid Build Coastguard Worker 
TEST_F(MojoInterfacePassingPerfTest,MultiprocessAssociatedInterfacePassing)647*6777b538SAndroid Build Coastguard Worker TEST_F(MojoInterfacePassingPerfTest, MultiprocessAssociatedInterfacePassing) {
648*6777b538SAndroid Build Coastguard Worker   RunTestClient("InterfacePassingClient", [&](MojoHandle h) {
649*6777b538SAndroid Build Coastguard Worker     base::test::SingleThreadTaskEnvironment task_environment;
650*6777b538SAndroid Build Coastguard Worker     RunInterfacePassingServer(h, "AssociatedInterfacePassing",
651*6777b538SAndroid Build Coastguard Worker                               true /* associated*/);
652*6777b538SAndroid Build Coastguard Worker   });
653*6777b538SAndroid Build Coastguard Worker }
654*6777b538SAndroid Build Coastguard Worker 
655*6777b538SAndroid Build Coastguard Worker // A single process version of the above test.
TEST_P(MojoInProcessInterfacePerfTest,MultiThreadPingPong)656*6777b538SAndroid Build Coastguard Worker TEST_P(MojoInProcessInterfacePerfTest, MultiThreadPingPong) {
657*6777b538SAndroid Build Coastguard Worker   MojoHandle server_handle, client_handle;
658*6777b538SAndroid Build Coastguard Worker   CreateMessagePipe(&server_handle, &client_handle);
659*6777b538SAndroid Build Coastguard Worker 
660*6777b538SAndroid Build Coastguard Worker   base::Thread client_thread("PingPongClient");
661*6777b538SAndroid Build Coastguard Worker   client_thread.Start();
662*6777b538SAndroid Build Coastguard Worker   client_thread.task_runner()->PostTask(
663*6777b538SAndroid Build Coastguard Worker       FROM_HERE,
664*6777b538SAndroid Build Coastguard Worker       base::BindOnce(base::IgnoreResult(&RunPingPongClient), client_handle));
665*6777b538SAndroid Build Coastguard Worker 
666*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
667*6777b538SAndroid Build Coastguard Worker   RunPingPongServer(server_handle, "SingleProcess");
668*6777b538SAndroid Build Coastguard Worker }
669*6777b538SAndroid Build Coastguard Worker 
TEST_P(MojoInProcessInterfacePerfTest,SingleThreadPingPong)670*6777b538SAndroid Build Coastguard Worker TEST_P(MojoInProcessInterfacePerfTest, SingleThreadPingPong) {
671*6777b538SAndroid Build Coastguard Worker   MojoHandle server_handle, client_handle;
672*6777b538SAndroid Build Coastguard Worker   CreateMessagePipe(&server_handle, &client_handle);
673*6777b538SAndroid Build Coastguard Worker 
674*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
675*6777b538SAndroid Build Coastguard Worker   mojo::MessagePipeHandle mp_handle(client_handle);
676*6777b538SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
677*6777b538SAndroid Build Coastguard Worker   LockThreadAffinity thread_locker(kSharedCore);
678*6777b538SAndroid Build Coastguard Worker   ReflectorImpl impl(std::move(scoped_mp), base::OnceClosure());
679*6777b538SAndroid Build Coastguard Worker 
680*6777b538SAndroid Build Coastguard Worker   RunPingPongServer(server_handle, "SingleProcess");
681*6777b538SAndroid Build Coastguard Worker }
682*6777b538SAndroid Build Coastguard Worker 
683*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
684*6777b538SAndroid Build Coastguard Worker                          MojoInProcessInterfacePerfTest,
685*6777b538SAndroid Build Coastguard Worker                          testing::Values(InProcessMessageMode::kSerialized,
686*6777b538SAndroid Build Coastguard Worker                                          InProcessMessageMode::kUnserialized));
687*6777b538SAndroid Build Coastguard Worker 
TEST_P(MojoInProcessInterfacePassingPerfTest,MultiThreadInterfacePassing)688*6777b538SAndroid Build Coastguard Worker TEST_P(MojoInProcessInterfacePassingPerfTest, MultiThreadInterfacePassing) {
689*6777b538SAndroid Build Coastguard Worker   MojoHandle server_handle, client_handle;
690*6777b538SAndroid Build Coastguard Worker   CreateMessagePipe(&server_handle, &client_handle);
691*6777b538SAndroid Build Coastguard Worker 
692*6777b538SAndroid Build Coastguard Worker   base::Thread client_thread("InterfacePassingClient");
693*6777b538SAndroid Build Coastguard Worker   client_thread.Start();
694*6777b538SAndroid Build Coastguard Worker   client_thread.task_runner()->PostTask(
695*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(base::IgnoreResult(&RunInterfacePassingClient),
696*6777b538SAndroid Build Coastguard Worker                                 client_handle));
697*6777b538SAndroid Build Coastguard Worker 
698*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
699*6777b538SAndroid Build Coastguard Worker   RunInterfacePassingServer(server_handle, "SingleProcess",
700*6777b538SAndroid Build Coastguard Worker                             false /* associated */);
701*6777b538SAndroid Build Coastguard Worker }
702*6777b538SAndroid Build Coastguard Worker 
TEST_P(MojoInProcessInterfacePassingPerfTest,MultiThreadAssociatedInterfacePassing)703*6777b538SAndroid Build Coastguard Worker TEST_P(MojoInProcessInterfacePassingPerfTest,
704*6777b538SAndroid Build Coastguard Worker        MultiThreadAssociatedInterfacePassing) {
705*6777b538SAndroid Build Coastguard Worker   MojoHandle server_handle, client_handle;
706*6777b538SAndroid Build Coastguard Worker   CreateMessagePipe(&server_handle, &client_handle);
707*6777b538SAndroid Build Coastguard Worker 
708*6777b538SAndroid Build Coastguard Worker   base::Thread client_thread("InterfacePassingClient");
709*6777b538SAndroid Build Coastguard Worker   client_thread.Start();
710*6777b538SAndroid Build Coastguard Worker   client_thread.task_runner()->PostTask(
711*6777b538SAndroid Build Coastguard Worker       FROM_HERE, base::BindOnce(base::IgnoreResult(&RunInterfacePassingClient),
712*6777b538SAndroid Build Coastguard Worker                                 client_handle));
713*6777b538SAndroid Build Coastguard Worker 
714*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
715*6777b538SAndroid Build Coastguard Worker   RunInterfacePassingServer(server_handle, "SingleProcess",
716*6777b538SAndroid Build Coastguard Worker                             true /* associated */);
717*6777b538SAndroid Build Coastguard Worker }
718*6777b538SAndroid Build Coastguard Worker 
TEST_P(MojoInProcessInterfacePassingPerfTest,SingleThreadInterfacePassing)719*6777b538SAndroid Build Coastguard Worker TEST_P(MojoInProcessInterfacePassingPerfTest, SingleThreadInterfacePassing) {
720*6777b538SAndroid Build Coastguard Worker   MojoHandle server_handle, client_handle;
721*6777b538SAndroid Build Coastguard Worker   CreateMessagePipe(&server_handle, &client_handle);
722*6777b538SAndroid Build Coastguard Worker 
723*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
724*6777b538SAndroid Build Coastguard Worker   mojo::MessagePipeHandle mp_handle(client_handle);
725*6777b538SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
726*6777b538SAndroid Build Coastguard Worker   LockThreadAffinity thread_locker(kSharedCore);
727*6777b538SAndroid Build Coastguard Worker   InterfacePassingTestDriverImpl impl(std::move(scoped_mp),
728*6777b538SAndroid Build Coastguard Worker                                       base::OnceClosure());
729*6777b538SAndroid Build Coastguard Worker 
730*6777b538SAndroid Build Coastguard Worker   RunInterfacePassingServer(server_handle, "SingleProcess",
731*6777b538SAndroid Build Coastguard Worker                             false /* associated */);
732*6777b538SAndroid Build Coastguard Worker }
733*6777b538SAndroid Build Coastguard Worker 
TEST_P(MojoInProcessInterfacePassingPerfTest,SingleThreadAssociatedInterfacePassing)734*6777b538SAndroid Build Coastguard Worker TEST_P(MojoInProcessInterfacePassingPerfTest,
735*6777b538SAndroid Build Coastguard Worker        SingleThreadAssociatedInterfacePassing) {
736*6777b538SAndroid Build Coastguard Worker   MojoHandle server_handle, client_handle;
737*6777b538SAndroid Build Coastguard Worker   CreateMessagePipe(&server_handle, &client_handle);
738*6777b538SAndroid Build Coastguard Worker 
739*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment;
740*6777b538SAndroid Build Coastguard Worker   mojo::MessagePipeHandle mp_handle(client_handle);
741*6777b538SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
742*6777b538SAndroid Build Coastguard Worker   LockThreadAffinity thread_locker(kSharedCore);
743*6777b538SAndroid Build Coastguard Worker   InterfacePassingTestDriverImpl impl(std::move(scoped_mp),
744*6777b538SAndroid Build Coastguard Worker                                       base::OnceClosure());
745*6777b538SAndroid Build Coastguard Worker 
746*6777b538SAndroid Build Coastguard Worker   RunInterfacePassingServer(server_handle, "SingleProcess",
747*6777b538SAndroid Build Coastguard Worker                             true /* associated */);
748*6777b538SAndroid Build Coastguard Worker }
749*6777b538SAndroid Build Coastguard Worker 
750*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
751*6777b538SAndroid Build Coastguard Worker                          MojoInProcessInterfacePassingPerfTest,
752*6777b538SAndroid Build Coastguard Worker                          testing::Values(InProcessMessageMode::kSerialized,
753*6777b538SAndroid Build Coastguard Worker                                          InProcessMessageMode::kUnserialized));
754*6777b538SAndroid Build Coastguard Worker 
755*6777b538SAndroid Build Coastguard Worker class CallbackPerfTest : public testing::Test {
756*6777b538SAndroid Build Coastguard Worker  public:
CallbackPerfTest()757*6777b538SAndroid Build Coastguard Worker   CallbackPerfTest()
758*6777b538SAndroid Build Coastguard Worker       : client_thread_("PingPongClient"), message_count_(0), count_down_(0) {}
759*6777b538SAndroid Build Coastguard Worker 
760*6777b538SAndroid Build Coastguard Worker   CallbackPerfTest(const CallbackPerfTest&) = delete;
761*6777b538SAndroid Build Coastguard Worker   CallbackPerfTest& operator=(const CallbackPerfTest&) = delete;
762*6777b538SAndroid Build Coastguard Worker 
763*6777b538SAndroid Build Coastguard Worker  protected:
RunMultiThreadPingPongServer()764*6777b538SAndroid Build Coastguard Worker   void RunMultiThreadPingPongServer() {
765*6777b538SAndroid Build Coastguard Worker     client_thread_.Start();
766*6777b538SAndroid Build Coastguard Worker 
767*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
768*6777b538SAndroid Build Coastguard Worker     std::vector<PingPongTestParams> params = GetDefaultTestParams();
769*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); i++) {
770*6777b538SAndroid Build Coastguard Worker       std::string hello("hello");
771*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
772*6777b538SAndroid Build Coastguard Worker       client_thread_.task_runner()->PostTask(
773*6777b538SAndroid Build Coastguard Worker           FROM_HERE,
774*6777b538SAndroid Build Coastguard Worker           base::BindOnce(&CallbackPerfTest::Ping, base::Unretained(this), hello,
775*6777b538SAndroid Build Coastguard Worker                          loop.QuitWhenIdleClosure()));
776*6777b538SAndroid Build Coastguard Worker       message_count_ = count_down_ = params[i].message_count();
777*6777b538SAndroid Build Coastguard Worker       payload_ = std::string(params[i].message_size(), 'a');
778*6777b538SAndroid Build Coastguard Worker 
779*6777b538SAndroid Build Coastguard Worker       loop.Run();
780*6777b538SAndroid Build Coastguard Worker     }
781*6777b538SAndroid Build Coastguard Worker   }
782*6777b538SAndroid Build Coastguard Worker 
Ping(const std::string & value,base::OnceClosure quit_closure)783*6777b538SAndroid Build Coastguard Worker   void Ping(const std::string& value, base::OnceClosure quit_closure) {
784*6777b538SAndroid Build Coastguard Worker     task_environment_.GetMainThreadTaskRunner()->PostTask(
785*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
786*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&CallbackPerfTest::OnPong, base::Unretained(this), value,
787*6777b538SAndroid Build Coastguard Worker                        std::move(quit_closure)));
788*6777b538SAndroid Build Coastguard Worker   }
789*6777b538SAndroid Build Coastguard Worker 
OnPong(const std::string & value,base::OnceClosure quit_closure)790*6777b538SAndroid Build Coastguard Worker   void OnPong(const std::string& value, base::OnceClosure quit_closure) {
791*6777b538SAndroid Build Coastguard Worker     if (value == "hello") {
792*6777b538SAndroid Build Coastguard Worker       DCHECK(!perf_logger_.get());
793*6777b538SAndroid Build Coastguard Worker       std::string test_name =
794*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("Callback_MultiProcess_Perf_%dx_%zu",
795*6777b538SAndroid Build Coastguard Worker                              message_count_, payload_.size());
796*6777b538SAndroid Build Coastguard Worker       perf_logger_ = std::make_unique<base::PerfTimeLogger>(test_name.c_str());
797*6777b538SAndroid Build Coastguard Worker     } else {
798*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(payload_.size(), value.size());
799*6777b538SAndroid Build Coastguard Worker 
800*6777b538SAndroid Build Coastguard Worker       CHECK(count_down_ > 0);
801*6777b538SAndroid Build Coastguard Worker       count_down_--;
802*6777b538SAndroid Build Coastguard Worker       if (count_down_ == 0) {
803*6777b538SAndroid Build Coastguard Worker         perf_logger_.reset();
804*6777b538SAndroid Build Coastguard Worker         if (!quit_closure.is_null()) {
805*6777b538SAndroid Build Coastguard Worker           std::move(quit_closure).Run();
806*6777b538SAndroid Build Coastguard Worker         }
807*6777b538SAndroid Build Coastguard Worker         return;
808*6777b538SAndroid Build Coastguard Worker       }
809*6777b538SAndroid Build Coastguard Worker     }
810*6777b538SAndroid Build Coastguard Worker 
811*6777b538SAndroid Build Coastguard Worker     client_thread_.task_runner()->PostTask(
812*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
813*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&CallbackPerfTest::Ping, base::Unretained(this),
814*6777b538SAndroid Build Coastguard Worker                        payload_, std::move(quit_closure)));
815*6777b538SAndroid Build Coastguard Worker   }
816*6777b538SAndroid Build Coastguard Worker 
RunSingleThreadNoPostTaskPingPongServer()817*6777b538SAndroid Build Coastguard Worker   void RunSingleThreadNoPostTaskPingPongServer() {
818*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
819*6777b538SAndroid Build Coastguard Worker     std::vector<PingPongTestParams> params = GetDefaultTestParams();
820*6777b538SAndroid Build Coastguard Worker     base::RepeatingCallback<void(
821*6777b538SAndroid Build Coastguard Worker         const std::string&, int,
822*6777b538SAndroid Build Coastguard Worker         base::OnceCallback<void(const std::string&, int)>)>
823*6777b538SAndroid Build Coastguard Worker         ping =
824*6777b538SAndroid Build Coastguard Worker             base::BindRepeating(&CallbackPerfTest::SingleThreadPingNoPostTask,
825*6777b538SAndroid Build Coastguard Worker                                 base::Unretained(this));
826*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); i++) {
827*6777b538SAndroid Build Coastguard Worker       payload_ = std::string(params[i].message_size(), 'a');
828*6777b538SAndroid Build Coastguard Worker       std::string test_name =
829*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("Callback_SingleThreadNoPostTask_Perf_%dx_%zu",
830*6777b538SAndroid Build Coastguard Worker                              params[i].message_count(), payload_.size());
831*6777b538SAndroid Build Coastguard Worker       perf_logger_ = std::make_unique<base::PerfTimeLogger>(test_name.c_str());
832*6777b538SAndroid Build Coastguard Worker       for (int j = 0; j < params[i].message_count(); ++j) {
833*6777b538SAndroid Build Coastguard Worker         ping.Run(payload_, j,
834*6777b538SAndroid Build Coastguard Worker                  base::BindOnce(&CallbackPerfTest::SingleThreadPongNoPostTask,
835*6777b538SAndroid Build Coastguard Worker                                 base::Unretained(this)));
836*6777b538SAndroid Build Coastguard Worker       }
837*6777b538SAndroid Build Coastguard Worker       perf_logger_.reset();
838*6777b538SAndroid Build Coastguard Worker     }
839*6777b538SAndroid Build Coastguard Worker   }
840*6777b538SAndroid Build Coastguard Worker 
SingleThreadPingNoPostTask(const std::string & value,int i,base::OnceCallback<void (const std::string &,int)> pong)841*6777b538SAndroid Build Coastguard Worker   void SingleThreadPingNoPostTask(
842*6777b538SAndroid Build Coastguard Worker       const std::string& value,
843*6777b538SAndroid Build Coastguard Worker       int i,
844*6777b538SAndroid Build Coastguard Worker       base::OnceCallback<void(const std::string&, int)> pong) {
845*6777b538SAndroid Build Coastguard Worker     std::move(pong).Run(value, i);
846*6777b538SAndroid Build Coastguard Worker   }
847*6777b538SAndroid Build Coastguard Worker 
SingleThreadPongNoPostTask(const std::string & value,int i)848*6777b538SAndroid Build Coastguard Worker   void SingleThreadPongNoPostTask(const std::string& value, int i) {}
849*6777b538SAndroid Build Coastguard Worker 
RunSingleThreadPostTaskPingPongServer()850*6777b538SAndroid Build Coastguard Worker   void RunSingleThreadPostTaskPingPongServer() {
851*6777b538SAndroid Build Coastguard Worker     LockThreadAffinity thread_locker(kSharedCore);
852*6777b538SAndroid Build Coastguard Worker     std::vector<PingPongTestParams> params = GetDefaultTestParams();
853*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < params.size(); i++) {
854*6777b538SAndroid Build Coastguard Worker       std::string hello("hello");
855*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
856*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
857*6777b538SAndroid Build Coastguard Worker           FROM_HERE, base::BindOnce(&CallbackPerfTest::SingleThreadPingPostTask,
858*6777b538SAndroid Build Coastguard Worker                                     base::Unretained(this), hello,
859*6777b538SAndroid Build Coastguard Worker                                     loop.QuitWhenIdleClosure()));
860*6777b538SAndroid Build Coastguard Worker       message_count_ = count_down_ = params[i].message_count();
861*6777b538SAndroid Build Coastguard Worker       payload_ = std::string(params[i].message_size(), 'a');
862*6777b538SAndroid Build Coastguard Worker 
863*6777b538SAndroid Build Coastguard Worker       loop.Run();
864*6777b538SAndroid Build Coastguard Worker     }
865*6777b538SAndroid Build Coastguard Worker   }
866*6777b538SAndroid Build Coastguard Worker 
SingleThreadPingPostTask(const std::string & value,base::OnceClosure quit_closure)867*6777b538SAndroid Build Coastguard Worker   void SingleThreadPingPostTask(const std::string& value,
868*6777b538SAndroid Build Coastguard Worker                                 base::OnceClosure quit_closure) {
869*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
870*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
871*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&CallbackPerfTest::SingleThreadPongPostTask,
872*6777b538SAndroid Build Coastguard Worker                        base::Unretained(this), value, std::move(quit_closure)));
873*6777b538SAndroid Build Coastguard Worker   }
874*6777b538SAndroid Build Coastguard Worker 
SingleThreadPongPostTask(const std::string & value,base::OnceClosure quit_closure)875*6777b538SAndroid Build Coastguard Worker   void SingleThreadPongPostTask(const std::string& value,
876*6777b538SAndroid Build Coastguard Worker                                 base::OnceClosure quit_closure) {
877*6777b538SAndroid Build Coastguard Worker     if (value == "hello") {
878*6777b538SAndroid Build Coastguard Worker       DCHECK(!perf_logger_.get());
879*6777b538SAndroid Build Coastguard Worker       std::string test_name =
880*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("Callback_SingleThreadPostTask_Perf_%dx_%zu",
881*6777b538SAndroid Build Coastguard Worker                              message_count_, payload_.size());
882*6777b538SAndroid Build Coastguard Worker       perf_logger_ = std::make_unique<base::PerfTimeLogger>(test_name.c_str());
883*6777b538SAndroid Build Coastguard Worker     } else {
884*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(payload_.size(), value.size());
885*6777b538SAndroid Build Coastguard Worker 
886*6777b538SAndroid Build Coastguard Worker       CHECK(count_down_ > 0);
887*6777b538SAndroid Build Coastguard Worker       count_down_--;
888*6777b538SAndroid Build Coastguard Worker       if (count_down_ == 0) {
889*6777b538SAndroid Build Coastguard Worker         perf_logger_.reset();
890*6777b538SAndroid Build Coastguard Worker         if (!quit_closure.is_null()) {
891*6777b538SAndroid Build Coastguard Worker           std::move(quit_closure).Run();
892*6777b538SAndroid Build Coastguard Worker         }
893*6777b538SAndroid Build Coastguard Worker         return;
894*6777b538SAndroid Build Coastguard Worker       }
895*6777b538SAndroid Build Coastguard Worker     }
896*6777b538SAndroid Build Coastguard Worker 
897*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
898*6777b538SAndroid Build Coastguard Worker         FROM_HERE, base::BindOnce(&CallbackPerfTest::SingleThreadPingPostTask,
899*6777b538SAndroid Build Coastguard Worker                                   base::Unretained(this), payload_,
900*6777b538SAndroid Build Coastguard Worker                                   std::move(quit_closure)));
901*6777b538SAndroid Build Coastguard Worker   }
902*6777b538SAndroid Build Coastguard Worker 
903*6777b538SAndroid Build Coastguard Worker  private:
904*6777b538SAndroid Build Coastguard Worker   base::Thread client_thread_;
905*6777b538SAndroid Build Coastguard Worker   base::test::SingleThreadTaskEnvironment task_environment_;
906*6777b538SAndroid Build Coastguard Worker   int message_count_;
907*6777b538SAndroid Build Coastguard Worker   int count_down_;
908*6777b538SAndroid Build Coastguard Worker   std::string payload_;
909*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::PerfTimeLogger> perf_logger_;
910*6777b538SAndroid Build Coastguard Worker };
911*6777b538SAndroid Build Coastguard Worker 
912*6777b538SAndroid Build Coastguard Worker // Sends the same data as above using PostTask to a different thread instead of
913*6777b538SAndroid Build Coastguard Worker // IPCs for comparison.
TEST_F(CallbackPerfTest,MultiThreadPingPong)914*6777b538SAndroid Build Coastguard Worker TEST_F(CallbackPerfTest, MultiThreadPingPong) {
915*6777b538SAndroid Build Coastguard Worker   RunMultiThreadPingPongServer();
916*6777b538SAndroid Build Coastguard Worker }
917*6777b538SAndroid Build Coastguard Worker 
918*6777b538SAndroid Build Coastguard Worker // Sends the same data as above using PostTask to the same thread.
TEST_F(CallbackPerfTest,SingleThreadPostTaskPingPong)919*6777b538SAndroid Build Coastguard Worker TEST_F(CallbackPerfTest, SingleThreadPostTaskPingPong) {
920*6777b538SAndroid Build Coastguard Worker   RunSingleThreadPostTaskPingPongServer();
921*6777b538SAndroid Build Coastguard Worker }
922*6777b538SAndroid Build Coastguard Worker 
923*6777b538SAndroid Build Coastguard Worker // Sends the same data as above without using PostTask to the same thread.
TEST_F(CallbackPerfTest,SingleThreadNoPostTaskPingPong)924*6777b538SAndroid Build Coastguard Worker TEST_F(CallbackPerfTest, SingleThreadNoPostTaskPingPong) {
925*6777b538SAndroid Build Coastguard Worker   RunSingleThreadNoPostTaskPingPongServer();
926*6777b538SAndroid Build Coastguard Worker }
927*6777b538SAndroid Build Coastguard Worker 
928*6777b538SAndroid Build Coastguard Worker }  // namespace
929*6777b538SAndroid Build Coastguard Worker }  // namespace IPC
930