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

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

Issue 1980263002: GPU Watchdog to check I/O before terminating GPU process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Avoid creating the temp file in advance 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 | « 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"
15 #include "base/files/file_util.h" 16 #include "base/files/file_util.h"
16 #include "base/location.h" 17 #include "base/location.h"
17 #include "base/macros.h" 18 #include "base/macros.h"
18 #include "base/power_monitor/power_monitor.h" 19 #include "base/power_monitor/power_monitor.h"
19 #include "base/process/process.h" 20 #include "base/process/process.h"
20 #include "base/single_thread_task_runner.h" 21 #include "base/single_thread_task_runner.h"
21 #include "base/threading/platform_thread.h" 22 #include "base/threading/platform_thread.h"
23 #include "base/timer/elapsed_timer.h"
22 #include "build/build_config.h" 24 #include "build/build_config.h"
23 #include "content/public/common/content_switches.h" 25 #include "content/public/common/content_switches.h"
24 #include "content/public/common/result_codes.h" 26 #include "content/public/common/result_codes.h"
25 27
26 #if defined(OS_WIN) 28 #if defined(OS_WIN)
27 #include <windows.h> 29 #include <windows.h>
28 #endif 30 #endif
29 31
30 namespace content { 32 namespace content {
31 namespace { 33 namespace {
(...skipping 12 matching lines...) Expand all
44 timeout_(base::TimeDelta::FromMilliseconds(timeout)), 46 timeout_(base::TimeDelta::FromMilliseconds(timeout)),
45 armed_(false), 47 armed_(false),
46 task_observer_(this), 48 task_observer_(this),
47 use_thread_cpu_time_(true), 49 use_thread_cpu_time_(true),
48 responsive_acknowledge_count_(0), 50 responsive_acknowledge_count_(0),
49 #if defined(OS_WIN) 51 #if defined(OS_WIN)
50 watched_thread_handle_(0), 52 watched_thread_handle_(0),
51 arm_cpu_time_(), 53 arm_cpu_time_(),
52 #endif 54 #endif
53 suspended_(false), 55 suspended_(false),
56 use_temp_file_for_io_checking_(false),
54 #if defined(USE_X11) 57 #if defined(USE_X11)
55 display_(NULL), 58 display_(NULL),
56 window_(0), 59 window_(0),
57 atom_(None), 60 atom_(None),
58 #endif 61 #endif
59 weak_factory_(this) { 62 weak_factory_(this) {
60 DCHECK(timeout >= 0); 63 DCHECK(timeout >= 0);
61 64
62 #if defined(OS_WIN) 65 #if defined(OS_WIN)
63 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread 66 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 // Do not create any new termination tasks if one has already been created 204 // Do not create any new termination tasks if one has already been created
202 // or the system is suspended. 205 // or the system is suspended.
203 if (armed_ || suspended_) 206 if (armed_ || suspended_)
204 return; 207 return;
205 208
206 // Must set armed before posting the task. This task might be the only task 209 // Must set armed before posting the task. This task might be the only task
207 // that will activate the TaskObserver on the watched thread and it must not 210 // that will activate the TaskObserver on the watched thread and it must not
208 // miss the false -> true transition. 211 // miss the false -> true transition.
209 armed_ = true; 212 armed_ = true;
210 213
214 use_temp_file_for_io_checking_ = true;
215
211 #if defined(OS_WIN) 216 #if defined(OS_WIN)
212 arm_cpu_time_ = GetWatchedThreadTime(); 217 arm_cpu_time_ = GetWatchedThreadTime();
213 218
214 QueryUnbiasedInterruptTime(&arm_interrupt_time_); 219 QueryUnbiasedInterruptTime(&arm_interrupt_time_);
215 #endif 220 #endif
216 221
217 check_time_ = base::Time::Now(); 222 check_time_ = base::Time::Now();
218 check_timeticks_ = base::TimeTicks::Now(); 223 check_timeticks_ = base::TimeTicks::Now();
219 // Immediately after the computer is woken up from being suspended it might 224 // Immediately after the computer is woken up from being suspended it might
220 // be pretty sluggish, so allow some extra time before the next timeout. 225 // be pretty sluggish, so allow some extra time before the next timeout.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // If the watchdog woke up significantly behind schedule, disarm and reset 265 // If the watchdog woke up significantly behind schedule, disarm and reset
261 // the watchdog check. This is to prevent the watchdog thread from terminating 266 // the watchdog check. This is to prevent the watchdog thread from terminating
262 // when a machine wakes up from sleep or hibernation, which would otherwise 267 // when a machine wakes up from sleep or hibernation, which would otherwise
263 // appear to be a hang. 268 // appear to be a hang.
264 if (base::Time::Now() > suspension_timeout_) { 269 if (base::Time::Now() > suspension_timeout_) {
265 armed_ = false; 270 armed_ = false;
266 OnCheck(true); 271 OnCheck(true);
267 return; 272 return;
268 } 273 }
269 274
275 // If the watchdog woke up while there is a heavy I/O we want to give the
276 // machine a chance to clear the I/O queue before terminating the process.
277 if (use_temp_file_for_io_checking_) {
jbauman 2016/05/17 22:57:20 Instead of using a flag here, we should make this
stanisc 2016/05/18 00:01:30 Good point! I didn't realize that adding sandbox r
278 base::File temp_file;
279 base::FilePath temp_dir_path;
280 if (GetTempDir(&temp_dir_path)) {
281 base::FilePath temp_file_path = temp_dir_path.Append(L"gpu-watchdog.tmp");
282 // Please note that multiple instances of GPU process may reuse the same
283 // temporary file. That's OK because the file is written to only when
284 // the watchdog gets triggered and about to crash the process. The file
285 // should be deleted when the last handle is closed.
286 temp_file.Initialize(
jbauman 2016/05/17 22:57:20 We're not doing anything special with the sandbox
287 temp_file_path,
288 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE |
289 base::File::FLAG_DELETE_ON_CLOSE | base::File::FLAG_SHARE_DELETE);
290 if (temp_file.IsValid()) {
291 // Write a few bytes and wait for the write to flush.
292 const char temp_data[32] = {0};
293 base::ElapsedTimer timer;
294 temp_file.Write(0, temp_data, sizeof(temp_data));
295 temp_file.Flush();
296 io_check_duration_ = timer.Elapsed();
297
298 // Reset the flag and re-post this task to actually terminate unless
299 // acknowledge arrives in between.
300 use_temp_file_for_io_checking_ = false;
301 message_loop()->PostTask(
302 FROM_HERE,
303 base::Bind(
304 &GpuWatchdogThread::DeliberatelyTerminateToRecoverFromHang,
305 weak_factory_.GetWeakPtr()));
306 return;
307 }
308 }
309 }
310
270 #if defined(USE_X11) 311 #if defined(USE_X11)
271 XWindowAttributes attributes; 312 XWindowAttributes attributes;
272 XGetWindowAttributes(display_, window_, &attributes); 313 XGetWindowAttributes(display_, window_, &attributes);
273 314
274 XSelectInput(display_, window_, PropertyChangeMask); 315 XSelectInput(display_, window_, PropertyChangeMask);
275 SetupXChangeProp(); 316 SetupXChangeProp();
276 317
277 XFlush(display_); 318 XFlush(display_);
278 319
279 // We wait for the property change event with a timeout. If it arrives we know 320 // We wait for the property change event with a timeout. If it arrives we know
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 // calls into kernel level repeatedly, giving up its quanta before it is 498 // calls into kernel level repeatedly, giving up its quanta before it is
458 // tracked, for example a loop that repeatedly Sleeps. 499 // tracked, for example a loop that repeatedly Sleeps.
459 return base::ThreadTicks() + 500 return base::ThreadTicks() +
460 base::TimeDelta::FromMilliseconds(static_cast<int64_t>( 501 base::TimeDelta::FromMilliseconds(static_cast<int64_t>(
461 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000)); 502 (user_time64.QuadPart + kernel_time64.QuadPart) / 10000));
462 } 503 }
463 } 504 }
464 #endif 505 #endif
465 506
466 } // namespace content 507 } // 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