blob: d6890cd80df90b44dced3d6755299106c56aee26 [file] [log] [blame]
Yuzhu Shen4d50dc42017-09-06 20:39:091// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ipc/ipc_perftest_util.h"
6
7#include "base/logging.h"
8#include "base/run_loop.h"
9#include "ipc/ipc_channel_proxy.h"
10#include "ipc/ipc_perftest_messages.h"
Ken Rockot8a7f35f2018-07-04 19:40:5611#include "mojo/core/embedder/embedder.h"
12#include "mojo/core/test/multiprocess_test_helper.h"
Yuzhu Shen4d50dc42017-09-06 20:39:0913
14namespace IPC {
15
16scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() {
Ken Rockot8a7f35f2018-07-04 19:40:5617 scoped_refptr<base::TaskRunner> runner = mojo::core::GetIOTaskRunner();
Yuzhu Shen4d50dc42017-09-06 20:39:0918 return scoped_refptr<base::SingleThreadTaskRunner>(
19 static_cast<base::SingleThreadTaskRunner*>(runner.get()));
20}
21
Lukasz Anforowiczc695e532020-06-09 02:09:4522ChannelReflectorListener::ChannelReflectorListener() : channel_(nullptr) {
Yuzhu Shen4d50dc42017-09-06 20:39:0923 VLOG(1) << "Client listener up";
24}
25
26ChannelReflectorListener::~ChannelReflectorListener() {
27 VLOG(1) << "Client listener down";
28}
29
30void ChannelReflectorListener::Init(Sender* channel,
31 const base::Closure& quit_closure) {
32 DCHECK(!channel_);
33 channel_ = channel;
34 quit_closure_ = quit_closure;
35}
36
37bool ChannelReflectorListener::OnMessageReceived(const Message& message) {
38 CHECK(channel_);
39 bool handled = true;
40 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
41 IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
42 IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
43 IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing)
44 IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit)
45 IPC_MESSAGE_UNHANDLED(handled = false)
46 IPC_END_MESSAGE_MAP()
47 return handled;
48}
49
50void ChannelReflectorListener::OnHello() {
51 channel_->Send(new TestMsg_Hello);
52}
53
54void ChannelReflectorListener::OnPing(const std::string& payload) {
55 channel_->Send(new TestMsg_Ping(payload));
56}
57
58void ChannelReflectorListener::OnSyncPing(const std::string& payload,
59 std::string* response) {
60 *response = payload;
61}
62
63void ChannelReflectorListener::OnQuit() {
64 quit_closure_.Run();
65}
66
67void ChannelReflectorListener::Send(IPC::Message* message) {
68 channel_->Send(message);
69}
70
71LockThreadAffinity::LockThreadAffinity(int cpu_number)
72 : affinity_set_ok_(false) {
73#if defined(OS_WIN)
74 const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number;
75 old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask);
76 affinity_set_ok_ = old_affinity_ != 0;
Sean McAllister82700412020-08-19 20:10:3577#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
Yuzhu Shen4d50dc42017-09-06 20:39:0978 cpu_set_t cpuset;
79 CPU_ZERO(&cpuset);
80 CPU_SET(cpu_number, &cpuset);
81 auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
82 DCHECK_EQ(0, get_result);
83 auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset);
84 // Check for get_result failure, even though it should always succeed.
85 affinity_set_ok_ = (set_result == 0) && (get_result == 0);
86#endif
87 if (!affinity_set_ok_)
88 LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number;
89}
90
91LockThreadAffinity::~LockThreadAffinity() {
92 if (!affinity_set_ok_)
93 return;
94#if defined(OS_WIN)
95 auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_);
96 DCHECK_NE(0u, set_result);
Sean McAllister82700412020-08-19 20:10:3597#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
Yuzhu Shen4d50dc42017-09-06 20:39:0998 auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
99 DCHECK_EQ(0, set_result);
100#endif
101}
102
103MojoPerfTestClient::MojoPerfTestClient()
104 : listener_(new ChannelReflectorListener()) {
Ken Rockot8a7f35f2018-07-04 19:40:56105 mojo::core::test::MultiprocessTestHelper::ChildSetup();
Yuzhu Shen4d50dc42017-09-06 20:39:09106}
107
108MojoPerfTestClient::~MojoPerfTestClient() = default;
109
110int MojoPerfTestClient::Run(MojoHandle handle) {
111 handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));
112 LockThreadAffinity thread_locker(kSharedCore);
113
114 base::RunLoop run_loop;
Hajime Hoshiff15e972017-11-09 06:37:09115 std::unique_ptr<ChannelProxy> channel = IPC::ChannelProxy::Create(
116 handle_.release(), Channel::MODE_CLIENT, listener_.get(),
117 GetIOThreadTaskRunner(), base::ThreadTaskRunnerHandle::Get());
Yuzhu Shen4d50dc42017-09-06 20:39:09118 listener_->Init(channel.get(), run_loop.QuitWhenIdleClosure());
119 run_loop.Run();
120 return 0;
121}
122
123ReflectorImpl::ReflectorImpl(mojo::ScopedMessagePipeHandle handle,
124 const base::Closure& quit_closure)
125 : quit_closure_(quit_closure),
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54126 receiver_(
127 this,
128 mojo::PendingReceiver<IPC::mojom::Reflector>(std::move(handle))) {}
Yuzhu Shen4d50dc42017-09-06 20:39:09129
130ReflectorImpl::~ReflectorImpl() {
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54131 ignore_result(receiver_.Unbind().PassPipe().release());
Yuzhu Shen4d50dc42017-09-06 20:39:09132}
133
134void ReflectorImpl::Ping(const std::string& value, PingCallback callback) {
135 std::move(callback).Run(value);
136}
137
138void ReflectorImpl::SyncPing(const std::string& value, PingCallback callback) {
139 std::move(callback).Run(value);
140}
141
142void ReflectorImpl::Quit() {
143 if (quit_closure_)
144 quit_closure_.Run();
145}
146
147} // namespace IPC