1 // Copyright 2017 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef IPC_IPC_PERFTEST_UTIL_H_ 6 #define IPC_IPC_PERFTEST_UTIL_H_ 7 8 #include <string> 9 10 #include "base/memory/raw_ptr.h" 11 #include "base/task/single_thread_task_runner.h" 12 #include "build/build_config.h" 13 14 #if BUILDFLAG(IS_WIN) 15 #include <windows.h> 16 #endif 17 18 #include "base/functional/callback.h" 19 #include "base/memory/ref_counted.h" 20 #include "base/process/process_metrics.h" 21 #include "base/task/single_thread_task_executor.h" 22 #include "base/task/single_thread_task_runner.h" 23 #include "build/build_config.h" 24 #include "ipc/ipc_channel.h" 25 #include "ipc/ipc_listener.h" 26 #include "ipc/ipc_message.h" 27 #include "ipc/ipc_sender.h" 28 #include "ipc/ipc_test.mojom.h" 29 #include "mojo/public/cpp/bindings/receiver.h" 30 #include "mojo/public/cpp/system/message_pipe.h" 31 32 #if BUILDFLAG(IS_WIN) 33 #include <windows.h> 34 #endif 35 36 namespace IPC { 37 38 scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner(); 39 40 // This channel listener just replies to all messages with the exact same 41 // message. It assumes each message has one string parameter. When the string 42 // "quit" is sent, it will exit. 43 class ChannelReflectorListener : public Listener { 44 public: 45 ChannelReflectorListener(); 46 47 ~ChannelReflectorListener() override; 48 49 void Init(Sender* channel, base::OnceClosure quit_closure); 50 51 bool OnMessageReceived(const Message& message) override; 52 53 void OnHello(); 54 55 void OnPing(const std::string& payload); 56 57 void OnSyncPing(const std::string& payload, std::string* response); 58 59 void OnQuit(); 60 61 void Send(IPC::Message* message); 62 63 private: 64 raw_ptr<Sender> channel_; 65 base::OnceClosure quit_closure_; 66 }; 67 68 // This class locks the current thread to a particular CPU core. This is 69 // important because otherwise the different threads and processes of these 70 // tests end up on different CPU cores which means that all of the cores are 71 // lightly loaded so the OS (Windows and Linux) fails to ramp up the CPU 72 // frequency, leading to unpredictable and often poor performance. 73 class LockThreadAffinity { 74 public: 75 explicit LockThreadAffinity(int cpu_number); 76 77 LockThreadAffinity(const LockThreadAffinity&) = delete; 78 LockThreadAffinity& operator=(const LockThreadAffinity&) = delete; 79 80 ~LockThreadAffinity(); 81 82 private: 83 bool affinity_set_ok_; 84 #if BUILDFLAG(IS_WIN) 85 DWORD_PTR old_affinity_; 86 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 87 cpu_set_t old_cpuset_; 88 #endif 89 }; 90 91 // Avoid core 0 due to conflicts with Intel's Power Gadget. 92 // Setting thread affinity will fail harmlessly on single/dual core machines. 93 const int kSharedCore = 2; 94 95 class MojoPerfTestClient { 96 public: 97 MojoPerfTestClient(); 98 99 ~MojoPerfTestClient(); 100 101 int Run(MojoHandle handle); 102 103 private: 104 base::SingleThreadTaskExecutor main_task_executor_; 105 std::unique_ptr<ChannelReflectorListener> listener_; 106 std::unique_ptr<Channel> channel_; 107 mojo::ScopedMessagePipeHandle handle_; 108 }; 109 110 class ReflectorImpl : public IPC::mojom::Reflector { 111 public: 112 explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle, 113 base::OnceClosure quit_closure); 114 115 ~ReflectorImpl() override; 116 117 private: 118 // IPC::mojom::Reflector: 119 void Ping(const std::string& value, PingCallback callback) override; 120 121 void SyncPing(const std::string& value, PingCallback callback) override; 122 123 void Quit() override; 124 125 base::OnceClosure quit_closure_; 126 mojo::Receiver<IPC::mojom::Reflector> receiver_; 127 }; 128 129 } // namespace IPC 130 131 #endif // IPC_IPC_PERFTEST_UTIL_H_ 132