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

Side by Side Diff: content/gpu/gpu_watchdog_thread.cc

Issue 2071613002: Revert of GPU Watchdog to check I/O before terminating GPU process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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 | « content/gpu/gpu_watchdog_thread.h ('k') | 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/gpu/gpu_watchdog_thread.h" 5 #include "content/gpu/gpu_watchdog_thread.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/debug/alias.h" 14 #include "base/debug/alias.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
17 #include "base/location.h" 16 #include "base/location.h"
18 #include "base/macros.h" 17 #include "base/macros.h"
19 #include "base/power_monitor/power_monitor.h" 18 #include "base/power_monitor/power_monitor.h"
20 #include "base/process/process.h" 19 #include "base/process/process.h"
21 #include "base/single_thread_task_runner.h" 20 #include "base/single_thread_task_runner.h"
22 #include "base/threading/platform_thread.h" 21 #include "base/threading/platform_thread.h"
23 #include "base/timer/elapsed_timer.h"
24 #include "build/build_config.h" 22 #include "build/build_config.h"
25 #include "content/common/gpu_watchdog_utils.h"
26 #include "content/public/common/content_switches.h" 23 #include "content/public/common/content_switches.h"
27 #include "content/public/common/result_codes.h" 24 #include "content/public/common/result_codes.h"
28 25
29 #if defined(OS_WIN) 26 #if defined(OS_WIN)
30 #include <windows.h> 27 #include <windows.h>
31 #endif 28 #endif
32 29
33 namespace content { 30 namespace content {
34 namespace { 31 namespace {
35 #if defined(USE_X11) 32 #if defined(USE_X11)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 FALSE, 70 FALSE,
74 0); 71 0);
75 DCHECK(result); 72 DCHECK(result);
76 #endif 73 #endif
77 74
78 #if defined(USE_X11) 75 #if defined(USE_X11)
79 tty_file_ = base::OpenFile(base::FilePath(kTtyFilePath), "r"); 76 tty_file_ = base::OpenFile(base::FilePath(kTtyFilePath), "r");
80 SetupXServer(); 77 SetupXServer();
81 #endif 78 #endif
82 watched_message_loop_->AddTaskObserver(&task_observer_); 79 watched_message_loop_->AddTaskObserver(&task_observer_);
83
84 #if defined(OS_WIN)
85 // Create a temp file for checking whether I/O is a bottleneck.
86 // This code runs on the main GPU thread before the sandbox is lowered.
87 base::FilePath temp_file_path;
88 if (GetGpuWatchdogTempFile(&temp_file_path)) {
89 // Please note that multiple instances of GPU process may reuse the same
90 // temporary file. That's OK because the file is written to only when
91 // the watchdog gets triggered and about to crash the process. The file
92 // should be deleted when the last handle is closed.
93 temp_file_for_io_checking_.Initialize(
94 temp_file_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE |
95 base::File::FLAG_DELETE_ON_CLOSE |
96 base::File::FLAG_SHARE_DELETE);
97 if (!temp_file_for_io_checking_.IsValid()) {
98 LOG(ERROR) << "Couldn't create " << temp_file_path.value().c_str()
99 << ", error: " << temp_file_for_io_checking_.error_details();
100 }
101 }
102 #endif
103 } 80 }
104 81
105 void GpuWatchdogThread::PostAcknowledge() { 82 void GpuWatchdogThread::PostAcknowledge() {
106 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use 83 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use
107 // the method factory. Rely on reference counting instead. 84 // the method factory. Rely on reference counting instead.
108 task_runner()->PostTask(FROM_HERE, 85 task_runner()->PostTask(FROM_HERE,
109 base::Bind(&GpuWatchdogThread::OnAcknowledge, this)); 86 base::Bind(&GpuWatchdogThread::OnAcknowledge, this));
110 } 87 }
111 88
112 void GpuWatchdogThread::CheckArmed() { 89 void GpuWatchdogThread::CheckArmed() {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 217
241 // Post a task to the monitored thread that does nothing but wake up the 218 // Post a task to the monitored thread that does nothing but wake up the
242 // TaskObserver. Any other tasks that are pending on the watched thread will 219 // TaskObserver. Any other tasks that are pending on the watched thread will
243 // also wake up the observer. This simply ensures there is at least one. 220 // also wake up the observer. This simply ensures there is at least one.
244 watched_message_loop_->task_runner()->PostTask(FROM_HERE, 221 watched_message_loop_->task_runner()->PostTask(FROM_HERE,
245 base::Bind(&base::DoNothing)); 222 base::Bind(&base::DoNothing));
246 223
247 // Post a task to the watchdog thread to exit if the monitored thread does 224 // Post a task to the watchdog thread to exit if the monitored thread does
248 // not respond in time. 225 // not respond in time.
249 task_runner()->PostDelayedTask( 226 task_runner()->PostDelayedTask(
250 FROM_HERE, base::Bind(&GpuWatchdogThread::BeginTerminating, 227 FROM_HERE,
251 weak_factory_.GetWeakPtr()), 228 base::Bind(&GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
229 weak_factory_.GetWeakPtr()),
252 timeout); 230 timeout);
253 } 231 }
254 232
255 void GpuWatchdogThread::BeginTerminating() { 233 // Use the --disable-gpu-watchdog command line switch to disable this.
234 void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() {
256 // Should not get here while the system is suspended. 235 // Should not get here while the system is suspended.
257 DCHECK(!suspended_); 236 DCHECK(!suspended_);
258 237
259 #if defined(OS_WIN) 238 #if defined(OS_WIN)
260 // Defer termination until a certain amount of CPU time has elapsed on the 239 // Defer termination until a certain amount of CPU time has elapsed on the
261 // watched thread. 240 // watched thread.
262 base::ThreadTicks current_cpu_time = GetWatchedThreadTime(); 241 base::ThreadTicks current_cpu_time = GetWatchedThreadTime();
263 base::TimeDelta time_since_arm = current_cpu_time - arm_cpu_time_; 242 base::TimeDelta time_since_arm = current_cpu_time - arm_cpu_time_;
264 if (use_thread_cpu_time_ && (time_since_arm < timeout_)) { 243 if (use_thread_cpu_time_ && (time_since_arm < timeout_)) {
265 message_loop()->PostDelayedTask( 244 message_loop()->PostDelayedTask(
266 FROM_HERE, base::Bind(&GpuWatchdogThread::BeginTerminating, 245 FROM_HERE,
267 weak_factory_.GetWeakPtr()), 246 base::Bind(
247 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
248 weak_factory_.GetWeakPtr()),
268 timeout_ - time_since_arm); 249 timeout_ - time_since_arm);
269 return; 250 return;
270 } 251 }
271
272 // If the machine is busy with heavy I/O activity this should defer
273 // termination until the I/O queue clears (on the drive that contains
274 // the temp directory).
275 if (temp_file_for_io_checking_.IsValid()) {
276 // Write a few bytes and wait for the write to flush.
277 const char temp_data[32] = {};
278 base::ElapsedTimer timer;
279 temp_file_for_io_checking_.Write(0, temp_data, sizeof(temp_data));
280 temp_file_for_io_checking_.Flush();
281 // Record duration of the write operation above for crash dump analysis.
282 io_check_duration_ = timer.Elapsed();
283 }
284 #endif 252 #endif
285 253
286 // Post a new task to actually terminate unless an acknowledge from the
287 // watched thread arrives in between.
288 message_loop()->PostTask(
289 FROM_HERE,
290 base::Bind(&GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
291 weak_factory_.GetWeakPtr()));
292 }
293
294 // Use the --disable-gpu-watchdog command line switch to disable this.
295 void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() {
296 // Should not get here while the system is suspended.
297 DCHECK(!suspended_);
298
299 // If the watchdog woke up significantly behind schedule, disarm and reset 254 // If the watchdog woke up significantly behind schedule, disarm and reset
300 // the watchdog check. This is to prevent the watchdog thread from terminating 255 // the watchdog check. This is to prevent the watchdog thread from terminating
301 // when a machine wakes up from sleep or hibernation, which would otherwise 256 // when a machine wakes up from sleep or hibernation, which would otherwise
302 // appear to be a hang. 257 // appear to be a hang.
303 if (base::Time::Now() > suspension_timeout_) { 258 if (base::Time::Now() > suspension_timeout_) {
304 armed_ = false; 259 armed_ = false;
305 OnCheck(true); 260 OnCheck(true);
306 return; 261 return;
307 } 262 }
308 263
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 329
375 // Store variables so they're available in crash dumps to help determine the 330 // Store variables so they're available in crash dumps to help determine the
376 // cause of any hang. 331 // cause of any hang.
377 #if defined(OS_WIN) 332 #if defined(OS_WIN)
378 ULONGLONG fire_interrupt_time; 333 ULONGLONG fire_interrupt_time;
379 QueryUnbiasedInterruptTime(&fire_interrupt_time); 334 QueryUnbiasedInterruptTime(&fire_interrupt_time);
380 335
381 // This is the time since the watchdog was armed, in 100ns intervals, 336 // This is the time since the watchdog was armed, in 100ns intervals,
382 // ignoring time where the computer is suspended. 337 // ignoring time where the computer is suspended.
383 ULONGLONG interrupt_delay = fire_interrupt_time - arm_interrupt_time_; 338 ULONGLONG interrupt_delay = fire_interrupt_time - arm_interrupt_time_;
339
384 base::debug::Alias(&interrupt_delay); 340 base::debug::Alias(&interrupt_delay);
385
386 base::ThreadTicks current_cpu_time = GetWatchedThreadTime();
387 base::debug::Alias(&current_cpu_time); 341 base::debug::Alias(&current_cpu_time);
388
389 base::TimeDelta time_since_arm = current_cpu_time - arm_cpu_time_;
390 base::debug::Alias(&time_since_arm); 342 base::debug::Alias(&time_since_arm);
391 343
392 bool using_thread_ticks = base::ThreadTicks::IsSupported(); 344 bool using_thread_ticks = base::ThreadTicks::IsSupported();
393 base::debug::Alias(&using_thread_ticks); 345 base::debug::Alias(&using_thread_ticks);
394 346
395 bool using_high_res_timer = base::Time::IsHighResolutionTimerInUse(); 347 bool using_high_res_timer = base::Time::IsHighResolutionTimerInUse();
396 base::debug::Alias(&using_high_res_timer); 348 base::debug::Alias(&using_high_res_timer);
397 #endif 349 #endif
398 350
399 base::Time current_time = base::Time::Now(); 351 base::Time current_time = base::Time::Now();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 int tty_number; 460 int tty_number;
509 size_t num_res = sscanf(tty_string, "tty%d\n", &tty_number); 461 size_t num_res = sscanf(tty_string, "tty%d\n", &tty_number);
510 if (num_res == 1) 462 if (num_res == 1)
511 return tty_number; 463 return tty_number;
512 } 464 }
513 return -1; 465 return -1;
514 } 466 }
515 #endif 467 #endif
516 468
517 } // namespace content 469 } // namespace content
OLDNEW
« no previous file with comments | « content/gpu/gpu_watchdog_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698