1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 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 "ipc/ipc_perftest_util.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <tuple>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
12*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
13*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_proxy.h"
14*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_perftest_messages.h"
15*6777b538SAndroid Build Coastguard Worker #include "mojo/core/embedder/embedder.h"
16*6777b538SAndroid Build Coastguard Worker #include "mojo/core/test/multiprocess_test_helper.h"
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker namespace IPC {
19*6777b538SAndroid Build Coastguard Worker
GetIOThreadTaskRunner()20*6777b538SAndroid Build Coastguard Worker scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() {
21*6777b538SAndroid Build Coastguard Worker scoped_refptr<base::TaskRunner> runner = mojo::core::GetIOTaskRunner();
22*6777b538SAndroid Build Coastguard Worker return scoped_refptr<base::SingleThreadTaskRunner>(
23*6777b538SAndroid Build Coastguard Worker static_cast<base::SingleThreadTaskRunner*>(runner.get()));
24*6777b538SAndroid Build Coastguard Worker }
25*6777b538SAndroid Build Coastguard Worker
ChannelReflectorListener()26*6777b538SAndroid Build Coastguard Worker ChannelReflectorListener::ChannelReflectorListener() : channel_(nullptr) {
27*6777b538SAndroid Build Coastguard Worker VLOG(1) << "Client listener up";
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker
~ChannelReflectorListener()30*6777b538SAndroid Build Coastguard Worker ChannelReflectorListener::~ChannelReflectorListener() {
31*6777b538SAndroid Build Coastguard Worker VLOG(1) << "Client listener down";
32*6777b538SAndroid Build Coastguard Worker }
33*6777b538SAndroid Build Coastguard Worker
Init(Sender * channel,base::OnceClosure quit_closure)34*6777b538SAndroid Build Coastguard Worker void ChannelReflectorListener::Init(Sender* channel,
35*6777b538SAndroid Build Coastguard Worker base::OnceClosure quit_closure) {
36*6777b538SAndroid Build Coastguard Worker DCHECK(!channel_);
37*6777b538SAndroid Build Coastguard Worker channel_ = channel;
38*6777b538SAndroid Build Coastguard Worker quit_closure_ = std::move(quit_closure);
39*6777b538SAndroid Build Coastguard Worker }
40*6777b538SAndroid Build Coastguard Worker
OnMessageReceived(const Message & message)41*6777b538SAndroid Build Coastguard Worker bool ChannelReflectorListener::OnMessageReceived(const Message& message) {
42*6777b538SAndroid Build Coastguard Worker CHECK(channel_);
43*6777b538SAndroid Build Coastguard Worker bool handled = true;
44*6777b538SAndroid Build Coastguard Worker IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
45*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
46*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
47*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing)
48*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit)
49*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_UNHANDLED(handled = false)
50*6777b538SAndroid Build Coastguard Worker IPC_END_MESSAGE_MAP()
51*6777b538SAndroid Build Coastguard Worker return handled;
52*6777b538SAndroid Build Coastguard Worker }
53*6777b538SAndroid Build Coastguard Worker
OnHello()54*6777b538SAndroid Build Coastguard Worker void ChannelReflectorListener::OnHello() {
55*6777b538SAndroid Build Coastguard Worker channel_->Send(new TestMsg_Hello);
56*6777b538SAndroid Build Coastguard Worker }
57*6777b538SAndroid Build Coastguard Worker
OnPing(const std::string & payload)58*6777b538SAndroid Build Coastguard Worker void ChannelReflectorListener::OnPing(const std::string& payload) {
59*6777b538SAndroid Build Coastguard Worker channel_->Send(new TestMsg_Ping(payload));
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker
OnSyncPing(const std::string & payload,std::string * response)62*6777b538SAndroid Build Coastguard Worker void ChannelReflectorListener::OnSyncPing(const std::string& payload,
63*6777b538SAndroid Build Coastguard Worker std::string* response) {
64*6777b538SAndroid Build Coastguard Worker *response = payload;
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker
OnQuit()67*6777b538SAndroid Build Coastguard Worker void ChannelReflectorListener::OnQuit() {
68*6777b538SAndroid Build Coastguard Worker std::move(quit_closure_).Run();
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker
Send(IPC::Message * message)71*6777b538SAndroid Build Coastguard Worker void ChannelReflectorListener::Send(IPC::Message* message) {
72*6777b538SAndroid Build Coastguard Worker channel_->Send(message);
73*6777b538SAndroid Build Coastguard Worker }
74*6777b538SAndroid Build Coastguard Worker
LockThreadAffinity(int cpu_number)75*6777b538SAndroid Build Coastguard Worker LockThreadAffinity::LockThreadAffinity(int cpu_number)
76*6777b538SAndroid Build Coastguard Worker : affinity_set_ok_(false) {
77*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
78*6777b538SAndroid Build Coastguard Worker const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number;
79*6777b538SAndroid Build Coastguard Worker old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask);
80*6777b538SAndroid Build Coastguard Worker affinity_set_ok_ = old_affinity_ != 0;
81*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
82*6777b538SAndroid Build Coastguard Worker cpu_set_t cpuset;
83*6777b538SAndroid Build Coastguard Worker CPU_ZERO(&cpuset);
84*6777b538SAndroid Build Coastguard Worker CPU_SET(cpu_number, &cpuset);
85*6777b538SAndroid Build Coastguard Worker auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
86*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(0, get_result);
87*6777b538SAndroid Build Coastguard Worker auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset);
88*6777b538SAndroid Build Coastguard Worker // Check for get_result failure, even though it should always succeed.
89*6777b538SAndroid Build Coastguard Worker affinity_set_ok_ = (set_result == 0) && (get_result == 0);
90*6777b538SAndroid Build Coastguard Worker #endif
91*6777b538SAndroid Build Coastguard Worker if (!affinity_set_ok_)
92*6777b538SAndroid Build Coastguard Worker LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number;
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker
~LockThreadAffinity()95*6777b538SAndroid Build Coastguard Worker LockThreadAffinity::~LockThreadAffinity() {
96*6777b538SAndroid Build Coastguard Worker if (!affinity_set_ok_)
97*6777b538SAndroid Build Coastguard Worker return;
98*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
99*6777b538SAndroid Build Coastguard Worker auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_);
100*6777b538SAndroid Build Coastguard Worker DCHECK_NE(0u, set_result);
101*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
102*6777b538SAndroid Build Coastguard Worker auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
103*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(0, set_result);
104*6777b538SAndroid Build Coastguard Worker #endif
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker
MojoPerfTestClient()107*6777b538SAndroid Build Coastguard Worker MojoPerfTestClient::MojoPerfTestClient()
108*6777b538SAndroid Build Coastguard Worker : listener_(new ChannelReflectorListener()) {
109*6777b538SAndroid Build Coastguard Worker mojo::core::test::MultiprocessTestHelper::ChildSetup();
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker MojoPerfTestClient::~MojoPerfTestClient() = default;
113*6777b538SAndroid Build Coastguard Worker
Run(MojoHandle handle)114*6777b538SAndroid Build Coastguard Worker int MojoPerfTestClient::Run(MojoHandle handle) {
115*6777b538SAndroid Build Coastguard Worker handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));
116*6777b538SAndroid Build Coastguard Worker LockThreadAffinity thread_locker(kSharedCore);
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
119*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ChannelProxy> channel = IPC::ChannelProxy::Create(
120*6777b538SAndroid Build Coastguard Worker handle_.release(), Channel::MODE_CLIENT, listener_.get(),
121*6777b538SAndroid Build Coastguard Worker GetIOThreadTaskRunner(),
122*6777b538SAndroid Build Coastguard Worker base::SingleThreadTaskRunner::GetCurrentDefault());
123*6777b538SAndroid Build Coastguard Worker listener_->Init(channel.get(), run_loop.QuitWhenIdleClosure());
124*6777b538SAndroid Build Coastguard Worker run_loop.Run();
125*6777b538SAndroid Build Coastguard Worker return 0;
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker
ReflectorImpl(mojo::ScopedMessagePipeHandle handle,base::OnceClosure quit_closure)128*6777b538SAndroid Build Coastguard Worker ReflectorImpl::ReflectorImpl(mojo::ScopedMessagePipeHandle handle,
129*6777b538SAndroid Build Coastguard Worker base::OnceClosure quit_closure)
130*6777b538SAndroid Build Coastguard Worker : quit_closure_(std::move(quit_closure)),
131*6777b538SAndroid Build Coastguard Worker receiver_(
132*6777b538SAndroid Build Coastguard Worker this,
133*6777b538SAndroid Build Coastguard Worker mojo::PendingReceiver<IPC::mojom::Reflector>(std::move(handle))) {}
134*6777b538SAndroid Build Coastguard Worker
~ReflectorImpl()135*6777b538SAndroid Build Coastguard Worker ReflectorImpl::~ReflectorImpl() {
136*6777b538SAndroid Build Coastguard Worker std::ignore = receiver_.Unbind().PassPipe().release();
137*6777b538SAndroid Build Coastguard Worker }
138*6777b538SAndroid Build Coastguard Worker
Ping(const std::string & value,PingCallback callback)139*6777b538SAndroid Build Coastguard Worker void ReflectorImpl::Ping(const std::string& value, PingCallback callback) {
140*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(value);
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker
SyncPing(const std::string & value,PingCallback callback)143*6777b538SAndroid Build Coastguard Worker void ReflectorImpl::SyncPing(const std::string& value, PingCallback callback) {
144*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(value);
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker
Quit()147*6777b538SAndroid Build Coastguard Worker void ReflectorImpl::Quit() {
148*6777b538SAndroid Build Coastguard Worker if (quit_closure_)
149*6777b538SAndroid Build Coastguard Worker std::move(quit_closure_).Run();
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker
152*6777b538SAndroid Build Coastguard Worker } // namespace IPC
153