blob: 11d7b7dc6f28a0c85ed7b03cdf592b4177439899 [file] [log] [blame]
[email protected]5f99f45c32012-01-30 22:21:441// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]e09cee42010-11-09 01:50:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]623c0bd2011-03-12 01:00:415#ifndef CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
6#define CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
[email protected]e09cee42010-11-09 01:50:087
avi66a07722015-12-25 23:38:128#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/ref_counted.h"
[email protected]35a5b752011-11-17 23:58:5810#include "base/memory/weak_ptr.h"
[email protected]e55f5642013-07-18 00:22:5411#include "base/message_loop/message_loop.h"
[email protected]21e24902013-08-06 20:23:4812#include "base/power_monitor/power_observer.h"
[email protected]34b99632011-01-01 01:01:0613#include "base/threading/thread.h"
[email protected]abb522162013-06-28 01:54:1614#include "base/time/time.h"
avi66a07722015-12-25 23:38:1215#include "build/build_config.h"
lukasza9a90e8a2016-04-01 23:05:5116#include "content/common/gpu/gpu_watchdog.h"
sohan.jyoticf28abf2015-02-18 03:13:4217#include "ui/gfx/native_widget_types.h"
18
19#if defined(USE_X11)
20extern "C" {
21#include <X11/Xlib.h>
22#include <X11/Xatom.h>
23}
24#include <sys/poll.h>
25#include "ui/base/x/x11_util.h"
kylechar4abed71f2016-04-06 14:46:4226#include "ui/gfx/x/x11_types.h" // nogncheck
sohan.jyoticf28abf2015-02-18 03:13:4227#endif
[email protected]e09cee42010-11-09 01:50:0828
[email protected]eb398192012-10-22 20:16:1929namespace content {
30
[email protected]e09cee42010-11-09 01:50:0831// A thread that intermitently sends tasks to a group of watched message loops
32// and deliberately crashes if one of them does not respond after a timeout.
33class GpuWatchdogThread : public base::Thread,
lukasza9a90e8a2016-04-01 23:05:5134 public GpuWatchdog,
[email protected]21e24902013-08-06 20:23:4835 public base::PowerObserver,
[email protected]e09cee42010-11-09 01:50:0836 public base::RefCountedThreadSafe<GpuWatchdogThread> {
37 public:
[email protected]981c1c52010-12-01 20:09:2438 explicit GpuWatchdogThread(int timeout);
[email protected]e09cee42010-11-09 01:50:0839
[email protected]49eab482010-11-24 00:07:4340 // Accessible on watched thread but only modified by watchdog thread.
41 bool armed() const { return armed_; }
42 void PostAcknowledge();
[email protected]2dcf7022011-04-15 19:20:4143
lukasza9a90e8a2016-04-01 23:05:5144 // Implement GpuWatchdog.
dchenge933b3e2014-10-21 11:44:0945 void CheckArmed() override;
[email protected]49eab482010-11-24 00:07:4346
[email protected]21e24902013-08-06 20:23:4847 // Must be called after a PowerMonitor has been created. Can be called from
48 // any thread.
49 void AddPowerObserver();
50
[email protected]e09cee42010-11-09 01:50:0851 protected:
dchenge933b3e2014-10-21 11:44:0952 void Init() override;
53 void CleanUp() override;
[email protected]e09cee42010-11-09 01:50:0854
55 private:
[email protected]69d5c512012-04-28 06:36:1556 friend class base::RefCountedThreadSafe<GpuWatchdogThread>;
[email protected]49eab482010-11-24 00:07:4357
58 // An object of this type intercepts the reception and completion of all tasks
59 // on the watched thread and checks whether the watchdog is armed.
[email protected]dd32b1272013-05-04 14:17:1160 class GpuWatchdogTaskObserver : public base::MessageLoop::TaskObserver {
[email protected]49eab482010-11-24 00:07:4361 public:
62 explicit GpuWatchdogTaskObserver(GpuWatchdogThread* watchdog);
dchenge933b3e2014-10-21 11:44:0963 ~GpuWatchdogTaskObserver() override;
[email protected]49eab482010-11-24 00:07:4364
65 // Implements MessageLoop::TaskObserver.
dchenge933b3e2014-10-21 11:44:0966 void WillProcessTask(const base::PendingTask& pending_task) override;
67 void DidProcessTask(const base::PendingTask& pending_task) override;
[email protected]49eab482010-11-24 00:07:4368
69 private:
[email protected]49eab482010-11-24 00:07:4370 GpuWatchdogThread* watchdog_;
71 };
72
dchenge933b3e2014-10-21 11:44:0973 ~GpuWatchdogThread() override;
[email protected]69d5c512012-04-28 06:36:1574
[email protected]e09cee42010-11-09 01:50:0875 void OnAcknowledge();
[email protected]25cb8c452013-01-03 02:22:1876 void OnCheck(bool after_suspend);
[email protected]f9a7e08f2011-08-18 21:20:1677 void DeliberatelyTerminateToRecoverFromHang();
sohan.jyoticf28abf2015-02-18 03:13:4278#if defined(USE_X11)
79 void SetupXServer();
80 void SetupXChangeProp();
81 bool MatchXEventAtom(XEvent* event);
82#endif
[email protected]e09cee42010-11-09 01:50:0883
[email protected]21e24902013-08-06 20:23:4884 void OnAddPowerObserver();
85
86 // Implement PowerObserver.
dchenge933b3e2014-10-21 11:44:0987 void OnSuspend() override;
88 void OnResume() override;
[email protected]21e24902013-08-06 20:23:4889
jbauman227bc772016-02-23 20:40:0590#if defined(OS_WIN)
91 base::TimeDelta GetWatchedThreadTime();
92#endif
93
[email protected]dd32b1272013-05-04 14:17:1194 base::MessageLoop* watched_message_loop_;
[email protected]5f99f45c32012-01-30 22:21:4495 base::TimeDelta timeout_;
[email protected]49eab482010-11-24 00:07:4396 volatile bool armed_;
97 GpuWatchdogTaskObserver task_observer_;
[email protected]e09cee42010-11-09 01:50:0898
jbaumanfd8b3be2016-03-15 00:15:0099 // True if the watchdog should wait for a certain amount of CPU to be used
100 // before killing the process.
101 bool use_thread_cpu_time_;
102
103 // The number of consecutive acknowledgements that had a latency less than
104 // 50ms.
105 int responsive_acknowledge_count_;
106
jbauman227bc772016-02-23 20:40:05107#if defined(OS_WIN)
108 void* watched_thread_handle_;
109 base::TimeDelta arm_cpu_time_;
jbaumane6b5e252016-03-17 03:25:04110
111 // This measures the time that the system has been running, in units of 100
112 // ns.
113 ULONGLONG arm_interrupt_time_;
jbauman227bc772016-02-23 20:40:05114#endif
115
[email protected]25cb8c452013-01-03 02:22:18116 // Time after which it's assumed that the computer has been suspended since
117 // the task was posted.
118 base::Time suspension_timeout_;
[email protected]995a7f12011-02-11 23:07:17119
[email protected]21e24902013-08-06 20:23:48120 bool suspended_;
121
jbaumanfd8b3be2016-03-15 00:15:00122 // This is the time the last check was sent.
123 base::Time check_time_;
jbaumane6b5e252016-03-17 03:25:04124 base::TimeTicks check_timeticks_;
jbaumanfd8b3be2016-03-15 00:15:00125
[email protected]53cf4962013-10-10 21:57:22126#if defined(OS_CHROMEOS)
127 FILE* tty_file_;
128#endif
129
sohan.jyoticf28abf2015-02-18 03:13:42130#if defined(USE_X11)
131 XDisplay* display_;
132 gfx::AcceleratedWidget window_;
133 XAtom atom_;
134#endif
135
mohan.reddy6993ff92014-09-12 09:52:40136 base::WeakPtrFactory<GpuWatchdogThread> weak_factory_;
137
[email protected]e09cee42010-11-09 01:50:08138 DISALLOW_COPY_AND_ASSIGN(GpuWatchdogThread);
139};
140
[email protected]eb398192012-10-22 20:16:19141} // namespace content
142
[email protected]623c0bd2011-03-12 01:00:41143#endif // CONTENT_GPU_GPU_WATCHDOG_THREAD_H_