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