OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #if defined(OS_WIN) | 5 #if defined(OS_WIN) |
6 #include <windows.h> | 6 #include <windows.h> |
7 #endif | 7 #endif |
8 | 8 |
9 #include "chrome/gpu/gpu_watchdog_thread.h" | 9 #include "chrome/gpu/gpu_watchdog_thread.h" |
10 | 10 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 } | 111 } |
112 | 112 |
113 void GpuWatchdogThread::OnAcknowledge() { | 113 void GpuWatchdogThread::OnAcknowledge() { |
114 // The check has already been acknowledged and another has already been | 114 // The check has already been acknowledged and another has already been |
115 // scheduled by a previous call to OnAcknowledge. It is normal for a | 115 // scheduled by a previous call to OnAcknowledge. It is normal for a |
116 // watched thread to see armed_ being true multiple times before | 116 // watched thread to see armed_ being true multiple times before |
117 // the OnAcknowledge task is run on the watchdog thread. | 117 // the OnAcknowledge task is run on the watchdog thread. |
118 if (!armed_) | 118 if (!armed_) |
119 return; | 119 return; |
120 | 120 |
121 // Revoke any pending OnExit. | 121 // Revoke any pending hang termination. |
122 method_factory_->RevokeAll(); | 122 method_factory_->RevokeAll(); |
123 armed_ = false; | 123 armed_ = false; |
124 | 124 |
125 // The monitored thread has responded. Post a task to check it again. | 125 // The monitored thread has responded. Post a task to check it again. |
126 message_loop()->PostDelayedTask( | 126 message_loop()->PostDelayedTask( |
127 FROM_HERE, | 127 FROM_HERE, |
128 method_factory_->NewRunnableMethod(&GpuWatchdogThread::OnCheck), | 128 method_factory_->NewRunnableMethod(&GpuWatchdogThread::OnCheck), |
129 kCheckPeriod); | 129 kCheckPeriod); |
130 } | 130 } |
131 | 131 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 // TaskObserver. Any other tasks that are pending on the watched thread will | 181 // TaskObserver. Any other tasks that are pending on the watched thread will |
182 // also wake up the observer. This simply ensures there is at least one. | 182 // also wake up the observer. This simply ensures there is at least one. |
183 watched_message_loop_->PostTask( | 183 watched_message_loop_->PostTask( |
184 FROM_HERE, | 184 FROM_HERE, |
185 NewRunnableFunction(DoNothing)); | 185 NewRunnableFunction(DoNothing)); |
186 | 186 |
187 // Post a task to the watchdog thread to exit if the monitored thread does | 187 // Post a task to the watchdog thread to exit if the monitored thread does |
188 // not respond in time. | 188 // not respond in time. |
189 message_loop()->PostDelayedTask( | 189 message_loop()->PostDelayedTask( |
190 FROM_HERE, | 190 FROM_HERE, |
191 method_factory_->NewRunnableMethod(&GpuWatchdogThread::OnExit), | 191 method_factory_->NewRunnableMethod( |
| 192 &GpuWatchdogThread::DeliberatelyCrashingToRecoverFromHang), |
192 timeout_); | 193 timeout_); |
193 } | 194 } |
194 | 195 |
195 // Use the --disable-gpu-watchdog command line switch to disable this. | 196 // Use the --disable-gpu-watchdog command line switch to disable this. |
196 void GpuWatchdogThread::OnExit() { | 197 void GpuWatchdogThread::DeliberatelyCrashingToRecoverFromHang() { |
197 #if defined(OS_WIN) | 198 #if defined(OS_WIN) |
198 // Defer termination until a certain amount of CPU time has elapsed on the | 199 // Defer termination until a certain amount of CPU time has elapsed on the |
199 // watched thread. | 200 // watched thread. |
200 int64 time_since_arm = GetWatchedThreadTime() - arm_cpu_time_; | 201 int64 time_since_arm = GetWatchedThreadTime() - arm_cpu_time_; |
201 if (time_since_arm < timeout_) { | 202 if (time_since_arm < timeout_) { |
202 message_loop()->PostDelayedTask( | 203 message_loop()->PostDelayedTask( |
203 FROM_HERE, | 204 FROM_HERE, |
204 method_factory_->NewRunnableMethod(&GpuWatchdogThread::OnExit), | 205 method_factory_->NewRunnableMethod( |
| 206 &GpuWatchdogThread::DeliberatelyCrashingToRecoverFromHang), |
205 timeout_ - time_since_arm); | 207 timeout_ - time_since_arm); |
206 return; | 208 return; |
207 } | 209 } |
208 #endif | 210 #endif |
209 | 211 |
210 // If the watchdog woke up significantly behind schedule, disarm and reset | 212 // If the watchdog woke up significantly behind schedule, disarm and reset |
211 // the watchdog check. This is to prevent the watchdog thread from terminating | 213 // the watchdog check. This is to prevent the watchdog thread from terminating |
212 // when a machine wakes up from sleep or hibernation, which would otherwise | 214 // when a machine wakes up from sleep or hibernation, which would otherwise |
213 // appear to be a hang. | 215 // appear to be a hang. |
214 if ((base::Time::Now() - arm_absolute_time_).InMilliseconds() > | 216 if ((base::Time::Now() - arm_absolute_time_).InMilliseconds() > |
(...skipping 17 matching lines...) Expand all Loading... |
232 #endif | 234 #endif |
233 | 235 |
234 LOG(ERROR) << "The GPU process hung. Terminating after " | 236 LOG(ERROR) << "The GPU process hung. Terminating after " |
235 << timeout_ << " ms."; | 237 << timeout_ << " ms."; |
236 | 238 |
237 volatile int* null_pointer = NULL; | 239 volatile int* null_pointer = NULL; |
238 *null_pointer = timeout; | 240 *null_pointer = timeout; |
239 | 241 |
240 crashed = true; | 242 crashed = true; |
241 } | 243 } |
OLD | NEW |