summaryrefslogtreecommitdiff
path: root/chromium/ipc/ipc_perftest_util.h
blob: ae96a703a6208b435eb567022e99024b19d0d79c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IPC_IPC_PERFTEST_UTIL_H_
#define IPC_IPC_PERFTEST_UTIL_H_

#include <string>

#include "base/memory/raw_ptr.h"
#include "build/build_config.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/process/process_metrics.h"
#include "base/task/single_thread_task_executor.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_sender.h"
#include "ipc/ipc_test.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/system/message_pipe.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif

namespace IPC {

scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner();

// This channel listener just replies to all messages with the exact same
// message. It assumes each message has one string parameter. When the string
// "quit" is sent, it will exit.
class ChannelReflectorListener : public Listener {
 public:
  ChannelReflectorListener();

  ~ChannelReflectorListener() override;

  void Init(Sender* channel, base::OnceClosure quit_closure);

  bool OnMessageReceived(const Message& message) override;

  void OnHello();

  void OnPing(const std::string& payload);

  void OnSyncPing(const std::string& payload, std::string* response);

  void OnQuit();

  void Send(IPC::Message* message);

 private:
  raw_ptr<Sender> channel_;
  base::OnceClosure quit_closure_;
};

// This class locks the current thread to a particular CPU core. This is
// important because otherwise the different threads and processes of these
// tests end up on different CPU cores which means that all of the cores are
// lightly loaded so the OS (Windows and Linux) fails to ramp up the CPU
// frequency, leading to unpredictable and often poor performance.
class LockThreadAffinity {
 public:
  explicit LockThreadAffinity(int cpu_number);

  LockThreadAffinity(const LockThreadAffinity&) = delete;
  LockThreadAffinity& operator=(const LockThreadAffinity&) = delete;

  ~LockThreadAffinity();

 private:
  bool affinity_set_ok_;
#if BUILDFLAG(IS_WIN)
  DWORD_PTR old_affinity_;
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  cpu_set_t old_cpuset_;
#endif
};

// Avoid core 0 due to conflicts with Intel's Power Gadget.
// Setting thread affinity will fail harmlessly on single/dual core machines.
const int kSharedCore = 2;

class MojoPerfTestClient {
 public:
  MojoPerfTestClient();

  ~MojoPerfTestClient();

  int Run(MojoHandle handle);

 private:
  base::SingleThreadTaskExecutor main_task_executor_;
  std::unique_ptr<ChannelReflectorListener> listener_;
  std::unique_ptr<Channel> channel_;
  mojo::ScopedMessagePipeHandle handle_;
};

class ReflectorImpl : public IPC::mojom::Reflector {
 public:
  explicit ReflectorImpl(mojo::ScopedMessagePipeHandle handle,
                         base::OnceClosure quit_closure);

  ~ReflectorImpl() override;

 private:
  // IPC::mojom::Reflector:
  void Ping(const std::string& value, PingCallback callback) override;

  void SyncPing(const std::string& value, PingCallback callback) override;

  void Quit() override;

  base::OnceClosure quit_closure_;
  mojo::Receiver<IPC::mojom::Reflector> receiver_;
};

}  // namespace IPC

#endif  // IPC_IPC_PERFTEST_UTIL_H_