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