ipc_perftest_util.cc 4.7 KB

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