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

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

Issue 1910063003: More accurate implementation of watched thread time for Gpu Watchdog. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
« base/time/time_win.cc ('K') | « base/time/time_win.cc ('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_util.h" 15 #include "base/files/file_util.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/power_monitor/power_monitor.h" 18 #include "base/power_monitor/power_monitor.h"
19 #include "base/process/process.h" 19 #include "base/process/process.h"
20 #include "base/single_thread_task_runner.h" 20 #include "base/single_thread_task_runner.h"
21 #include "base/threading/platform_thread.h"
21 #include "build/build_config.h" 22 #include "build/build_config.h"
22 #include "content/public/common/content_switches.h" 23 #include "content/public/common/content_switches.h"
23 #include "content/public/common/result_codes.h" 24 #include "content/public/common/result_codes.h"
24 25
25 #if defined(OS_WIN) 26 #if defined(OS_WIN)
26 #include <windows.h> 27 #include <windows.h>
27 #endif 28 #endif
28 29
29 namespace content { 30 namespace content {
30 namespace { 31 namespace {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 237 }
237 238
238 // Use the --disable-gpu-watchdog command line switch to disable this. 239 // Use the --disable-gpu-watchdog command line switch to disable this.
239 void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() { 240 void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() {
240 // Should not get here while the system is suspended. 241 // Should not get here while the system is suspended.
241 DCHECK(!suspended_); 242 DCHECK(!suspended_);
242 243
243 #if defined(OS_WIN) 244 #if defined(OS_WIN)
244 // Defer termination until a certain amount of CPU time has elapsed on the 245 // Defer termination until a certain amount of CPU time has elapsed on the
245 // watched thread. 246 // watched thread.
246 base::TimeDelta time_since_arm = GetWatchedThreadTime() - arm_cpu_time_; 247 base::TimeDelta time_since_arm = GetWatchedThreadTime() - arm_cpu_time_;
fdoray 2016/04/21 21:08:38 ThreadTicks::Now() returns a null ThreadTicks befo
stanisc 2016/04/22 01:11:45 I think it should be fine for GetWatchedThreadTime
247 if (use_thread_cpu_time_ && (time_since_arm < timeout_)) { 248 if (use_thread_cpu_time_ && (time_since_arm < timeout_)) {
248 message_loop()->PostDelayedTask( 249 message_loop()->PostDelayedTask(
249 FROM_HERE, 250 FROM_HERE,
250 base::Bind( 251 base::Bind(
251 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang, 252 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
252 weak_factory_.GetWeakPtr()), 253 weak_factory_.GetWeakPtr()),
253 timeout_ - time_since_arm); 254 timeout_ - time_since_arm);
254 return; 255 return;
255 } 256 }
256 #endif 257 #endif
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 suspended_ = false; 415 suspended_ = false;
415 resume_time_ = base::Time::Now(); 416 resume_time_ = base::Time::Now();
416 417
417 // After resuming jump-start the watchdog again. 418 // After resuming jump-start the watchdog again.
418 armed_ = false; 419 armed_ = false;
419 OnCheck(true); 420 OnCheck(true);
420 } 421 }
421 422
422 #if defined(OS_WIN) 423 #if defined(OS_WIN)
423 base::TimeDelta GpuWatchdogThread::GetWatchedThreadTime() { 424 base::TimeDelta GpuWatchdogThread::GetWatchedThreadTime() {
424 FILETIME creation_time; 425 if (base::ThreadTicks::IsSupported()) {
425 FILETIME exit_time; 426 // Convert ThreadTicks::Now() to TimeDelta.
426 FILETIME user_time; 427 return base::ThreadTicks::Now(
427 FILETIME kernel_time; 428 base::PlatformThreadHandle(watched_thread_handle_)) -
428 BOOL result = GetThreadTimes(watched_thread_handle_, 429 base::ThreadTicks();
fdoray 2016/04/21 21:08:37 Ideally, you would store a ThreadTicks and compute
stanisc 2016/04/22 01:11:45 Yes, it seems like a good idea for this method to
429 &creation_time,
430 &exit_time,
431 &kernel_time,
432 &user_time);
433 DCHECK(result);
434 430
435 ULARGE_INTEGER user_time64; 431 } else {
436 user_time64.HighPart = user_time.dwHighDateTime; 432 // Use GetThreadTimes as a backup mechanism.
437 user_time64.LowPart = user_time.dwLowDateTime; 433 FILETIME creation_time;
434 FILETIME exit_time;
435 FILETIME user_time;
436 FILETIME kernel_time;
437 BOOL result = GetThreadTimes(watched_thread_handle_, &creation_time,
438 &exit_time, &kernel_time, &user_time);
439 DCHECK(result);
438 440
439 ULARGE_INTEGER kernel_time64; 441 ULARGE_INTEGER user_time64;
440 kernel_time64.HighPart = kernel_time.dwHighDateTime; 442 user_time64.HighPart = user_time.dwHighDateTime;
441 kernel_time64.LowPart = kernel_time.dwLowDateTime; 443 user_time64.LowPart = user_time.dwLowDateTime;
442 444
443 // Time is reported in units of 100 nanoseconds. Kernel and user time are 445 ULARGE_INTEGER kernel_time64;
444 // summed to deal with to kinds of hangs. One is where the GPU process is 446 kernel_time64.HighPart = kernel_time.dwHighDateTime;
445 // stuck in user level, never calling into the kernel and kernel time is 447 kernel_time64.LowPart = kernel_time.dwLowDateTime;
446 // not increasing. The other is where either the kernel hangs and never 448
447 // returns to user level or where user level code 449 // Time is reported in units of 100 nanoseconds. Kernel and user time are
448 // calls into kernel level repeatedly, giving up its quanta before it is 450 // summed to deal with to kinds of hangs. One is where the GPU process is
449 // tracked, for example a loop that repeatedly Sleeps. 451 // stuck in user level, never calling into the kernel and kernel time is
450 return base::TimeDelta::FromMilliseconds(static_cast<int64_t>( 452 // not increasing. The other is where either the kernel hangs and never
451 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000)); 453 // returns to user level or where user level code
454 // calls into kernel level repeatedly, giving up its quanta before it is
455 // tracked, for example a loop that repeatedly Sleeps.
456 return base::TimeDelta::FromMilliseconds(static_cast<int64_t>(
457 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000));
458 }
452 } 459 }
453 #endif 460 #endif
454 461
455 } // namespace content 462 } // namespace content
OLDNEW
« base/time/time_win.cc ('K') | « base/time/time_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698