blob: 39a4afc1ce4de28fe8dbecd167a91259bb5789ca [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
Avi Drissman625f99aa2022-01-10 20:44:167#include <tuple>
8
Yuzhu Shen4d50dc42017-09-06 20:39:099#include "base/logging.h"
10#include "base/run_loop.h"
Xiaohan Wangab909b32022-01-12 17:57:3911#include "build/build_config.h"
Yuzhu Shen4d50dc42017-09-06 20:39:0912#include "ipc/ipc_channel_proxy.h"
13#include "ipc/ipc_perftest_messages.h"
Ken Rockot8a7f35f2018-07-04 19:40:5614#include "mojo/core/embedder/embedder.h"
15#include "mojo/core/test/multiprocess_test_helper.h"
Yuzhu Shen4d50dc42017-09-06 20:39:0916
17namespace IPC {
18
19scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() {
Ken Rockot8a7f35f2018-07-04 19:40:5620 scoped_refptr<base::TaskRunner> runner = mojo::core::GetIOTaskRunner();
Yuzhu Shen4d50dc42017-09-06 20:39:0921 return scoped_refptr<base::SingleThreadTaskRunner>(
22 static_cast<base::SingleThreadTaskRunner*>(runner.get()));
23}
24
Lukasz Anforowiczc695e532020-06-09 02:09:4525ChannelReflectorListener::ChannelReflectorListener() : channel_(nullptr) {
Yuzhu Shen4d50dc42017-09-06 20:39:0926 VLOG(1) << "Client listener up";
27}
28
29ChannelReflectorListener::~ChannelReflectorListener() {
30 VLOG(1) << "Client listener down";
31}
32
33void ChannelReflectorListener::Init(Sender* channel,
Alex Turner02b697a2020-10-28 22:37:1334 base::OnceClosure quit_closure) {
Yuzhu Shen4d50dc42017-09-06 20:39:0935 DCHECK(!channel_);
36 channel_ = channel;
Alex Turner02b697a2020-10-28 22:37:1337 quit_closure_ = std::move(quit_closure);
Yuzhu Shen4d50dc42017-09-06 20:39:0938}
39
40bool ChannelReflectorListener::OnMessageReceived(const Message& message) {
41 CHECK(channel_);
42 bool handled = true;
43 IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
44 IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
45 IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
46 IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing)
47 IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit)
48 IPC_MESSAGE_UNHANDLED(handled = false)
49 IPC_END_MESSAGE_MAP()
50 return handled;
51}
52
53void ChannelReflectorListener::OnHello() {
54 channel_->Send(new TestMsg_Hello);
55}
56
57void ChannelReflectorListener::OnPing(const std::string& payload) {
58 channel_->Send(new TestMsg_Ping(payload));
59}
60
61void ChannelReflectorListener::OnSyncPing(const std::string& payload,
62 std::string* response) {
63 *response = payload;
64}
65
66void ChannelReflectorListener::OnQuit() {
Alex Turner02b697a2020-10-28 22:37:1367 std::move(quit_closure_).Run();
Yuzhu Shen4d50dc42017-09-06 20:39:0968}
69
70void ChannelReflectorListener::Send(IPC::Message* message) {
71 channel_->Send(message);
72}
73
74LockThreadAffinity::LockThreadAffinity(int cpu_number)
75 : affinity_set_ok_(false) {
Xiaohan Wangab909b32022-01-12 17:57:3976#if BUILDFLAG(IS_WIN)
Yuzhu Shen4d50dc42017-09-06 20:39:0977 const DWORD_PTR thread_mask = static_cast<DWORD_PTR>(1) << cpu_number;
78 old_affinity_ = SetThreadAffinityMask(GetCurrentThread(), thread_mask);
79 affinity_set_ok_ = old_affinity_ != 0;
Xiaohan Wangab909b32022-01-12 17:57:3980#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Yuzhu Shen4d50dc42017-09-06 20:39:0981 cpu_set_t cpuset;
82 CPU_ZERO(&cpuset);
83 CPU_SET(cpu_number, &cpuset);
84 auto get_result = sched_getaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
85 DCHECK_EQ(0, get_result);
86 auto set_result = sched_setaffinity(0, sizeof(cpuset), &cpuset);
87 // Check for get_result failure, even though it should always succeed.
88 affinity_set_ok_ = (set_result == 0) && (get_result == 0);
89#endif
90 if (!affinity_set_ok_)
91 LOG(WARNING) << "Failed to set thread affinity to CPU " << cpu_number;
92}
93
94LockThreadAffinity::~LockThreadAffinity() {
95 if (!affinity_set_ok_)
96 return;
Xiaohan Wangab909b32022-01-12 17:57:3997#if BUILDFLAG(IS_WIN)
Yuzhu Shen4d50dc42017-09-06 20:39:0998 auto set_result = SetThreadAffinityMask(GetCurrentThread(), old_affinity_);
99 DCHECK_NE(0u, set_result);
Xiaohan Wangab909b32022-01-12 17:57:39100#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Yuzhu Shen4d50dc42017-09-06 20:39:09101 auto set_result = sched_setaffinity(0, sizeof(old_cpuset_), &old_cpuset_);
102 DCHECK_EQ(0, set_result);
103#endif
104}
105
106MojoPerfTestClient::MojoPerfTestClient()
107 : listener_(new ChannelReflectorListener()) {
Ken Rockot8a7f35f2018-07-04 19:40:56108 mojo::core::test::MultiprocessTestHelper::ChildSetup();
Yuzhu Shen4d50dc42017-09-06 20:39:09109}
110
111MojoPerfTestClient::~MojoPerfTestClient() = default;
112
113int MojoPerfTestClient::Run(MojoHandle handle) {
114 handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));
115 LockThreadAffinity thread_locker(kSharedCore);
116
117 base::RunLoop run_loop;
Hajime Hoshiff15e972017-11-09 06:37:09118 std::unique_ptr<ChannelProxy> channel = IPC::ChannelProxy::Create(
119 handle_.release(), Channel::MODE_CLIENT, listener_.get(),
120 GetIOThreadTaskRunner(), base::ThreadTaskRunnerHandle::Get());
Yuzhu Shen4d50dc42017-09-06 20:39:09121 listener_->Init(channel.get(), run_loop.QuitWhenIdleClosure());
122 run_loop.Run();
123 return 0;
124}
125
126ReflectorImpl::ReflectorImpl(mojo::ScopedMessagePipeHandle handle,
Alex Turner02b697a2020-10-28 22:37:13127 base::OnceClosure quit_closure)
128 : quit_closure_(std::move(quit_closure)),
Julie Jeongeun Kim6eb409ed2019-09-28 01:27:54129 receiver_(
130 this,
131 mojo::PendingReceiver<IPC::mojom::Reflector>(std::move(handle))) {}
Yuzhu Shen4d50dc42017-09-06 20:39:09132
133ReflectorImpl::~ReflectorImpl() {
Avi Drissman625f99aa2022-01-10 20:44:16134 std::ignore = receiver_.Unbind().PassPipe().release();
Yuzhu Shen4d50dc42017-09-06 20:39:09135}
136
137void ReflectorImpl::Ping(const std::string& value, PingCallback callback) {
138 std::move(callback).Run(value);
139}
140
141void ReflectorImpl::SyncPing(const std::string& value, PingCallback callback) {
142 std::move(callback).Run(value);
143}
144
145void ReflectorImpl::Quit() {
146 if (quit_closure_)
Alex Turner02b697a2020-10-28 22:37:13147 std::move(quit_closure_).Run();
Yuzhu Shen4d50dc42017-09-06 20:39:09148}
149
150} // namespace IPC