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