Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: content/renderer/devtools/devtools_cpu_throttler.cc

Issue 1521113002: DevTools: Initial implementation of slow CPU emulation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 4 landing Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 #include "content/renderer/devtools/devtools_cpu_throttler.h"
6
7 #if defined(OS_POSIX)
8 #include <signal.h>
9 #define USE_SIGNALS
10 #endif
11
12 #include "base/atomicops.h"
13 #include "base/synchronization/cancellation_flag.h"
14 #include "base/threading/platform_thread.h"
15
16 using base::subtle::Atomic32;
17 using base::subtle::Acquire_Load;
18 using base::subtle::Release_Store;
19
20 namespace content {
21
22 class CPUThrottlingThread final : public base::PlatformThread::Delegate {
23 public:
24 explicit CPUThrottlingThread(double rate);
25 ~CPUThrottlingThread() override;
26
27 void SetThrottlingRate(double rate);
28
29 private:
30 void ThreadMain() override;
31
32 void Start();
33 void Stop();
34 void Throttle();
35
36 static void SuspendThread(base::PlatformThreadHandle thread_handle);
37 static void ResumeThread(base::PlatformThreadHandle thread_handle);
38
39 #ifdef USE_SIGNALS
40 void InstallSignalHandler();
41 void RestoreSignalHandler();
42 static void HandleSignal(int signal);
43
44 static bool signal_handler_installed_;
45 static struct sigaction old_signal_handler_;
46 static Atomic32 suspended_;
47 #endif
48 static Atomic32 thread_exists_;
49
50 base::PlatformThreadHandle throttled_thread_handle_;
51 base::PlatformThreadHandle throttling_thread_handle_;
52 base::CancellationFlag cancellation_flag_;
53 Atomic32 throttling_rate_percent_;
54
55 DISALLOW_COPY_AND_ASSIGN(CPUThrottlingThread);
56 };
57
58 #ifdef USE_SIGNALS
59 bool CPUThrottlingThread::signal_handler_installed_;
60 struct sigaction CPUThrottlingThread::old_signal_handler_;
61 Atomic32 CPUThrottlingThread::suspended_;
62 #endif
63 Atomic32 CPUThrottlingThread::thread_exists_;
64
65 CPUThrottlingThread::CPUThrottlingThread(double rate)
66 : throttled_thread_handle_(base::PlatformThread::CurrentHandle()),
67 throttling_rate_percent_(static_cast<Atomic32>(rate * 100)) {
68 CHECK(base::subtle::NoBarrier_AtomicExchange(&thread_exists_, 1) == 0);
69 Start();
70 }
71
72 CPUThrottlingThread::~CPUThrottlingThread() {
73 Stop();
74 CHECK(base::subtle::NoBarrier_AtomicExchange(&thread_exists_, 0) == 1);
75 }
76
77 void CPUThrottlingThread::SetThrottlingRate(double rate) {
78 Release_Store(&throttling_rate_percent_, static_cast<Atomic32>(rate * 100));
79 }
80
81 void CPUThrottlingThread::ThreadMain() {
82 base::PlatformThread::SetName("DevToolsCPUThrottlingThread");
83 while (!cancellation_flag_.IsSet()) {
84 Throttle();
85 }
86 }
87
88 #ifdef USE_SIGNALS
89
90 // static
91 void CPUThrottlingThread::InstallSignalHandler() {
92 // There must be the only one!
93 DCHECK(!signal_handler_installed_);
94 struct sigaction sa;
95 sa.sa_handler = &HandleSignal;
96 sigemptyset(&sa.sa_mask);
97 sa.sa_flags = SA_RESTART;
98 signal_handler_installed_ =
99 (sigaction(SIGUSR2, &sa, &old_signal_handler_) == 0);
100 }
101
102 // static
103 void CPUThrottlingThread::RestoreSignalHandler() {
104 if (!signal_handler_installed_)
105 return;
106 sigaction(SIGUSR2, &old_signal_handler_, 0);
107 signal_handler_installed_ = false;
108 }
109
110 // static
111 void CPUThrottlingThread::HandleSignal(int signal) {
112 if (signal != SIGUSR2)
113 return;
114 while (Acquire_Load(&suspended_)) {
115 }
116 }
117
118 #endif // USE_SIGNALS
119
120 // static
121 void CPUThrottlingThread::SuspendThread(
122 base::PlatformThreadHandle thread_handle) {
123 #ifdef USE_SIGNALS
124 Release_Store(&suspended_, 1);
125 pthread_kill(thread_handle.platform_handle(), SIGUSR2);
126 #endif
127 }
128
129 // static
130 void CPUThrottlingThread::ResumeThread(
131 base::PlatformThreadHandle thread_handle) {
132 #ifdef USE_SIGNALS
133 Release_Store(&suspended_, 0);
134 #endif
135 }
136
137 void CPUThrottlingThread::Start() {
138 #ifdef USE_SIGNALS
139 InstallSignalHandler();
140 #endif
141 if (!base::PlatformThread::Create(0, this, &throttling_thread_handle_)) {
142 LOG(ERROR) << "Failed to create throttling thread.";
143 }
144 }
145
146 void CPUThrottlingThread::Stop() {
147 cancellation_flag_.Set();
148 base::PlatformThread::Join(throttling_thread_handle_);
149 #ifdef USE_SIGNALS
150 RestoreSignalHandler();
151 #endif
152 }
153
154 void CPUThrottlingThread::Throttle() {
155 const int quant_time_us = 200;
156 double rate = Acquire_Load(&throttling_rate_percent_) / 100.;
157 base::TimeDelta run_duration =
158 base::TimeDelta::FromMicroseconds(static_cast<int>(quant_time_us / rate));
159 base::TimeDelta sleep_duration =
160 base::TimeDelta::FromMicroseconds(quant_time_us) - run_duration;
161 base::PlatformThread::Sleep(run_duration);
162 SuspendThread(throttled_thread_handle_);
163 base::PlatformThread::Sleep(sleep_duration);
164 ResumeThread(throttled_thread_handle_);
165 }
166
167 DevToolsCPUThrottler::DevToolsCPUThrottler() {}
168
169 DevToolsCPUThrottler::~DevToolsCPUThrottler() {}
170
171 void DevToolsCPUThrottler::SetThrottlingRate(double rate) {
172 if (rate <= 1) {
173 if (throttling_thread_) {
174 throttling_thread_.reset();
175 }
176 return;
177 }
178 if (throttling_thread_) {
179 throttling_thread_->SetThrottlingRate(rate);
180 } else {
181 throttling_thread_.reset(new CPUThrottlingThread(rate));
182 }
183 }
184
185 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/devtools/devtools_cpu_throttler.h ('k') | content/renderer/devtools/v8_sampling_profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698