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

Unified Diff: content/gpu/gpu_watchdog_thread.cc

Issue 1725983002: Revert of Don't measure CPU time in timing out GPU watchdog. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/gpu/gpu_watchdog_thread.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/gpu/gpu_watchdog_thread.cc
diff --git a/content/gpu/gpu_watchdog_thread.cc b/content/gpu/gpu_watchdog_thread.cc
index 22982db10489fcd6e00d6a9eb8a5f45c95a7f7dc..4cfde4f94b51803d2866226284431054230bd223 100644
--- a/content/gpu/gpu_watchdog_thread.cc
+++ b/content/gpu/gpu_watchdog_thread.cc
@@ -42,6 +42,10 @@
timeout_(base::TimeDelta::FromMilliseconds(timeout)),
armed_(false),
task_observer_(this),
+#if defined(OS_WIN)
+ watched_thread_handle_(0),
+ arm_cpu_time_(),
+#endif
suspended_(false),
#if defined(USE_X11)
display_(NULL),
@@ -50,6 +54,20 @@
#endif
weak_factory_(this) {
DCHECK(timeout >= 0);
+
+#if defined(OS_WIN)
+ // GetCurrentThread returns a pseudo-handle that cannot be used by one thread
+ // to identify another. DuplicateHandle creates a "real" handle that can be
+ // used for this purpose.
+ BOOL result = DuplicateHandle(GetCurrentProcess(),
+ GetCurrentThread(),
+ GetCurrentProcess(),
+ &watched_thread_handle_,
+ THREAD_QUERY_INFORMATION,
+ FALSE,
+ 0);
+ DCHECK(result);
+#endif
#if defined(OS_CHROMEOS)
tty_file_ = base::OpenFile(base::FilePath(kTtyFilePath), "r");
@@ -106,6 +124,10 @@
// implicitly by the destructor, CleanUp() will not be called.
DCHECK(!weak_factory_.HasWeakPtrs());
+#if defined(OS_WIN)
+ CloseHandle(watched_thread_handle_);
+#endif
+
base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
if (power_monitor)
power_monitor->RemoveObserver(this);
@@ -163,6 +185,10 @@
// that will activate the TaskObserver on the watched thread and it must not
// miss the false -> true transition.
armed_ = true;
+
+#if defined(OS_WIN)
+ arm_cpu_time_ = GetWatchedThreadTime();
+#endif
// Immediately after the computer is woken up from being suspended it might
// be pretty sluggish, so allow some extra time before the next timeout.
@@ -188,6 +214,21 @@
void GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang() {
// Should not get here while the system is suspended.
DCHECK(!suspended_);
+
+#if defined(OS_WIN)
+ // Defer termination until a certain amount of CPU time has elapsed on the
+ // watched thread.
+ base::TimeDelta time_since_arm = GetWatchedThreadTime() - arm_cpu_time_;
+ if (time_since_arm < timeout_) {
+ message_loop()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(
+ &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
+ weak_factory_.GetWeakPtr()),
+ timeout_ - time_since_arm);
+ return;
+ }
+#endif
// If the watchdog woke up significantly behind schedule, disarm and reset
// the watchdog check. This is to prevent the watchdog thread from terminating
@@ -329,4 +370,37 @@
OnCheck(true);
}
+#if defined(OS_WIN)
+base::TimeDelta GpuWatchdogThread::GetWatchedThreadTime() {
+ FILETIME creation_time;
+ FILETIME exit_time;
+ FILETIME user_time;
+ FILETIME kernel_time;
+ BOOL result = GetThreadTimes(watched_thread_handle_,
+ &creation_time,
+ &exit_time,
+ &kernel_time,
+ &user_time);
+ DCHECK(result);
+
+ ULARGE_INTEGER user_time64;
+ user_time64.HighPart = user_time.dwHighDateTime;
+ user_time64.LowPart = user_time.dwLowDateTime;
+
+ ULARGE_INTEGER kernel_time64;
+ kernel_time64.HighPart = kernel_time.dwHighDateTime;
+ kernel_time64.LowPart = kernel_time.dwLowDateTime;
+
+ // Time is reported in units of 100 nanoseconds. Kernel and user time are
+ // summed to deal with to kinds of hangs. One is where the GPU process is
+ // stuck in user level, never calling into the kernel and kernel time is
+ // not increasing. The other is where either the kernel hangs and never
+ // returns to user level or where user level code
+ // calls into kernel level repeatedly, giving up its quanta before it is
+ // tracked, for example a loop that repeatedly Sleeps.
+ return base::TimeDelta::FromMilliseconds(static_cast<int64_t>(
+ (user_time64.QuadPart + kernel_time64.QuadPart) / 10000));
+}
+#endif
+
} // namespace content
« 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