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

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

Issue 1977693002: Support CPU throttling on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/devtools/devtools_cpu_throttler.h" 5 #include "content/renderer/devtools/devtools_cpu_throttler.h"
6 6
7 #include "base/atomicops.h" 7 #include "base/atomicops.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/synchronization/cancellation_flag.h" 9 #include "base/synchronization/cancellation_flag.h"
10 #include "base/threading/platform_thread.h" 10 #include "base/threading/platform_thread.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 12
13 #if defined(OS_POSIX) 13 #if defined(OS_POSIX)
14 #include <signal.h> 14 #include <signal.h>
15 #define USE_SIGNALS 15 #define USE_SIGNALS 1
16 #endif 16 #endif
17 17
18 using base::subtle::Atomic32; 18 using base::subtle::Atomic32;
19 using base::subtle::Acquire_Load; 19 using base::subtle::Acquire_Load;
20 using base::subtle::Release_Store; 20 using base::subtle::Release_Store;
21 21
22 namespace content { 22 namespace content {
23 23
24 class CPUThrottlingThread final : public base::PlatformThread::Delegate { 24 class CPUThrottlingThread final : public base::PlatformThread::Delegate {
25 public: 25 public:
26 explicit CPUThrottlingThread(double rate); 26 explicit CPUThrottlingThread(double rate);
27 ~CPUThrottlingThread() override; 27 ~CPUThrottlingThread() override;
28 28
29 void SetThrottlingRate(double rate); 29 void SetThrottlingRate(double rate);
30 30
31 private: 31 private:
32 void ThreadMain() override; 32 void ThreadMain() override;
33 33
34 void Start(); 34 void Start();
35 void Stop(); 35 void Stop();
36 void Throttle(); 36 void Throttle();
37 37
38 static void SuspendThread(base::PlatformThreadHandle thread_handle); 38 static void SuspendThread(base::PlatformThreadHandle thread_handle);
39 static void ResumeThread(base::PlatformThreadHandle thread_handle); 39 static void ResumeThread(base::PlatformThreadHandle thread_handle);
40 static void Sleep(base::TimeDelta duration);
40 41
41 #ifdef USE_SIGNALS 42 #ifdef USE_SIGNALS
42 void InstallSignalHandler(); 43 void InstallSignalHandler();
43 void RestoreSignalHandler(); 44 void RestoreSignalHandler();
44 static void HandleSignal(int signal); 45 static void HandleSignal(int signal);
45 46
46 static bool signal_handler_installed_; 47 static bool signal_handler_installed_;
47 static struct sigaction old_signal_handler_; 48 static struct sigaction old_signal_handler_;
48 static Atomic32 suspended_; 49 static Atomic32 suspended_;
49 #endif 50 #endif
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 return; 116 return;
116 while (Acquire_Load(&suspended_)) { 117 while (Acquire_Load(&suspended_)) {
117 } 118 }
118 } 119 }
119 120
120 #endif // USE_SIGNALS 121 #endif // USE_SIGNALS
121 122
122 // static 123 // static
123 void CPUThrottlingThread::SuspendThread( 124 void CPUThrottlingThread::SuspendThread(
124 base::PlatformThreadHandle thread_handle) { 125 base::PlatformThreadHandle thread_handle) {
125 #ifdef USE_SIGNALS 126 #if defined(USE_SIGNALS)
126 Release_Store(&suspended_, 1); 127 Release_Store(&suspended_, 1);
127 pthread_kill(thread_handle.platform_handle(), SIGUSR2); 128 pthread_kill(thread_handle.platform_handle(), SIGUSR2);
129 #elif OS_WIN
caseq 2016/05/13 01:49:07 defined(OS_WIN)?
alph 2016/05/13 21:00:59 Done.
130 ::SuspendThread(thread_handle.platform_handle());
128 #endif 131 #endif
129 } 132 }
130 133
131 // static 134 // static
132 void CPUThrottlingThread::ResumeThread( 135 void CPUThrottlingThread::ResumeThread(
133 base::PlatformThreadHandle thread_handle) { 136 base::PlatformThreadHandle thread_handle) {
134 #ifdef USE_SIGNALS 137 #if defined(USE_SIGNALS)
135 Release_Store(&suspended_, 0); 138 Release_Store(&suspended_, 0);
139 #elif OS_WIN
caseq 2016/05/13 01:49:07 ditto
alph 2016/05/13 21:00:59 Done.
140 ::ResumeThread(thread_handle.platform_handle());
136 #endif 141 #endif
137 } 142 }
138 143
139 void CPUThrottlingThread::Start() { 144 void CPUThrottlingThread::Start() {
140 #ifdef USE_SIGNALS 145 #ifdef USE_SIGNALS
141 InstallSignalHandler(); 146 InstallSignalHandler();
142 #endif 147 #endif
143 if (!base::PlatformThread::Create(0, this, &throttling_thread_handle_)) { 148 if (!base::PlatformThread::Create(0, this, &throttling_thread_handle_)) {
144 LOG(ERROR) << "Failed to create throttling thread."; 149 LOG(ERROR) << "Failed to create throttling thread.";
145 } 150 }
146 } 151 }
147 152
153 void CPUThrottlingThread::Sleep(base::TimeDelta duration) {
154 #if defined(USE_SIGNALS)
155 base::PlatformThread::Sleep(duration);
156 #elif OS_WIN
caseq 2016/05/13 01:49:07 ditto
alph 2016/05/13 21:00:59 Done.
157 // We cannot rely on ::Sleep function as it's precision is not enough for
158 // the purpose. Could be up to 16ms jitter.
159 base::TimeTicks wakeup_time = base::TimeTicks::Now() + duration;
160 while (base::TimeTicks::Now() < wakeup_time) {}
161 #endif
caseq 2016/05/13 01:49:07 What do we do #else?
alph 2016/05/13 21:00:59 I don't want it to break the build if CPU throttli
162 }
163
148 void CPUThrottlingThread::Stop() { 164 void CPUThrottlingThread::Stop() {
149 cancellation_flag_.Set(); 165 cancellation_flag_.Set();
150 base::PlatformThread::Join(throttling_thread_handle_); 166 base::PlatformThread::Join(throttling_thread_handle_);
151 #ifdef USE_SIGNALS 167 #ifdef USE_SIGNALS
152 RestoreSignalHandler(); 168 RestoreSignalHandler();
153 #endif 169 #endif
154 } 170 }
155 171
156 void CPUThrottlingThread::Throttle() { 172 void CPUThrottlingThread::Throttle() {
157 const int quant_time_us = 200; 173 const int quant_time_us = 200;
158 double rate = Acquire_Load(&throttling_rate_percent_) / 100.; 174 double rate = Acquire_Load(&throttling_rate_percent_) / 100.;
159 base::TimeDelta run_duration = 175 base::TimeDelta run_duration =
160 base::TimeDelta::FromMicroseconds(static_cast<int>(quant_time_us / rate)); 176 base::TimeDelta::FromMicroseconds(static_cast<int>(quant_time_us / rate));
161 base::TimeDelta sleep_duration = 177 base::TimeDelta sleep_duration =
162 base::TimeDelta::FromMicroseconds(quant_time_us) - run_duration; 178 base::TimeDelta::FromMicroseconds(quant_time_us) - run_duration;
163 base::PlatformThread::Sleep(run_duration); 179 Sleep(run_duration);
164 SuspendThread(throttled_thread_handle_); 180 SuspendThread(throttled_thread_handle_);
165 base::PlatformThread::Sleep(sleep_duration); 181 Sleep(sleep_duration);
166 ResumeThread(throttled_thread_handle_); 182 ResumeThread(throttled_thread_handle_);
167 } 183 }
168 184
169 DevToolsCPUThrottler::DevToolsCPUThrottler() {} 185 DevToolsCPUThrottler::DevToolsCPUThrottler() {}
170 186
171 DevToolsCPUThrottler::~DevToolsCPUThrottler() {} 187 DevToolsCPUThrottler::~DevToolsCPUThrottler() {}
172 188
173 void DevToolsCPUThrottler::SetThrottlingRate(double rate) { 189 void DevToolsCPUThrottler::SetThrottlingRate(double rate) {
174 if (rate <= 1) { 190 if (rate <= 1) {
175 if (throttling_thread_) { 191 if (throttling_thread_) {
176 throttling_thread_.reset(); 192 throttling_thread_.reset();
177 } 193 }
178 return; 194 return;
179 } 195 }
180 if (throttling_thread_) { 196 if (throttling_thread_) {
181 throttling_thread_->SetThrottlingRate(rate); 197 throttling_thread_->SetThrottlingRate(rate);
182 } else { 198 } else {
183 throttling_thread_.reset(new CPUThrottlingThread(rate)); 199 throttling_thread_.reset(new CPUThrottlingThread(rate));
184 } 200 }
185 } 201 }
186 202
187 } // namespace content 203 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698