[email protected] | 5f99f45c3 | 2012-01-30 22:21:44 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | ||||
4 | |||||
[email protected] | 623c0bd | 2011-03-12 01:00:41 | [diff] [blame] | 5 | #ifndef CONTENT_GPU_GPU_WATCHDOG_THREAD_H_ |
6 | #define CONTENT_GPU_GPU_WATCHDOG_THREAD_H_ | ||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 7 | |
avi | 66a0772 | 2015-12-25 23:38:12 | [diff] [blame] | 8 | #include "base/macros.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 9 | #include "base/memory/ref_counted.h" |
[email protected] | 35a5b75 | 2011-11-17 23:58:58 | [diff] [blame] | 10 | #include "base/memory/weak_ptr.h" |
[email protected] | e55f564 | 2013-07-18 00:22:54 | [diff] [blame] | 11 | #include "base/message_loop/message_loop.h" |
[email protected] | 21e2490 | 2013-08-06 20:23:48 | [diff] [blame] | 12 | #include "base/power_monitor/power_observer.h" |
[email protected] | 34b9963 | 2011-01-01 01:01:06 | [diff] [blame] | 13 | #include "base/threading/thread.h" |
[email protected] | abb52216 | 2013-06-28 01:54:16 | [diff] [blame] | 14 | #include "base/time/time.h" |
avi | 66a0772 | 2015-12-25 23:38:12 | [diff] [blame] | 15 | #include "build/build_config.h" |
lukasza | 9a90e8a | 2016-04-01 23:05:51 | [diff] [blame] | 16 | #include "content/common/gpu/gpu_watchdog.h" |
sohan.jyoti | cf28abf | 2015-02-18 03:13:42 | [diff] [blame] | 17 | #include "ui/gfx/native_widget_types.h" |
18 | |||||
19 | #if defined(USE_X11) | ||||
20 | extern "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" | ||||
kylechar | 4abed71f | 2016-04-06 14:46:42 | [diff] [blame^] | 26 | #include "ui/gfx/x/x11_types.h" // nogncheck |
sohan.jyoti | cf28abf | 2015-02-18 03:13:42 | [diff] [blame] | 27 | #endif |
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 28 | |
[email protected] | eb39819 | 2012-10-22 20:16:19 | [diff] [blame] | 29 | namespace content { |
30 | |||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 31 | // 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. | ||||
33 | class GpuWatchdogThread : public base::Thread, | ||||
lukasza | 9a90e8a | 2016-04-01 23:05:51 | [diff] [blame] | 34 | public GpuWatchdog, |
[email protected] | 21e2490 | 2013-08-06 20:23:48 | [diff] [blame] | 35 | public base::PowerObserver, |
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 36 | public base::RefCountedThreadSafe<GpuWatchdogThread> { |
37 | public: | ||||
[email protected] | 981c1c5 | 2010-12-01 20:09:24 | [diff] [blame] | 38 | explicit GpuWatchdogThread(int timeout); |
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 39 | |
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 40 | // Accessible on watched thread but only modified by watchdog thread. |
41 | bool armed() const { return armed_; } | ||||
42 | void PostAcknowledge(); | ||||
[email protected] | 2dcf702 | 2011-04-15 19:20:41 | [diff] [blame] | 43 | |
lukasza | 9a90e8a | 2016-04-01 23:05:51 | [diff] [blame] | 44 | // Implement GpuWatchdog. |
dcheng | e933b3e | 2014-10-21 11:44:09 | [diff] [blame] | 45 | void CheckArmed() override; |
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 46 | |
[email protected] | 21e2490 | 2013-08-06 20:23:48 | [diff] [blame] | 47 | // Must be called after a PowerMonitor has been created. Can be called from |
48 | // any thread. | ||||
49 | void AddPowerObserver(); | ||||
50 | |||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 51 | protected: |
dcheng | e933b3e | 2014-10-21 11:44:09 | [diff] [blame] | 52 | void Init() override; |
53 | void CleanUp() override; | ||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 54 | |
55 | private: | ||||
[email protected] | 69d5c51 | 2012-04-28 06:36:15 | [diff] [blame] | 56 | friend class base::RefCountedThreadSafe<GpuWatchdogThread>; |
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 57 | |
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] | dd32b127 | 2013-05-04 14:17:11 | [diff] [blame] | 60 | class GpuWatchdogTaskObserver : public base::MessageLoop::TaskObserver { |
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 61 | public: |
62 | explicit GpuWatchdogTaskObserver(GpuWatchdogThread* watchdog); | ||||
dcheng | e933b3e | 2014-10-21 11:44:09 | [diff] [blame] | 63 | ~GpuWatchdogTaskObserver() override; |
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 64 | |
65 | // Implements MessageLoop::TaskObserver. | ||||
dcheng | e933b3e | 2014-10-21 11:44:09 | [diff] [blame] | 66 | void WillProcessTask(const base::PendingTask& pending_task) override; |
67 | void DidProcessTask(const base::PendingTask& pending_task) override; | ||||
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 68 | |
69 | private: | ||||
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 70 | GpuWatchdogThread* watchdog_; |
71 | }; | ||||
72 | |||||
dcheng | e933b3e | 2014-10-21 11:44:09 | [diff] [blame] | 73 | ~GpuWatchdogThread() override; |
[email protected] | 69d5c51 | 2012-04-28 06:36:15 | [diff] [blame] | 74 | |
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 75 | void OnAcknowledge(); |
[email protected] | 25cb8c45 | 2013-01-03 02:22:18 | [diff] [blame] | 76 | void OnCheck(bool after_suspend); |
[email protected] | f9a7e08f | 2011-08-18 21:20:16 | [diff] [blame] | 77 | void DeliberatelyTerminateToRecoverFromHang(); |
sohan.jyoti | cf28abf | 2015-02-18 03:13:42 | [diff] [blame] | 78 | #if defined(USE_X11) |
79 | void SetupXServer(); | ||||
80 | void SetupXChangeProp(); | ||||
81 | bool MatchXEventAtom(XEvent* event); | ||||
82 | #endif | ||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 83 | |
[email protected] | 21e2490 | 2013-08-06 20:23:48 | [diff] [blame] | 84 | void OnAddPowerObserver(); |
85 | |||||
86 | // Implement PowerObserver. | ||||
dcheng | e933b3e | 2014-10-21 11:44:09 | [diff] [blame] | 87 | void OnSuspend() override; |
88 | void OnResume() override; | ||||
[email protected] | 21e2490 | 2013-08-06 20:23:48 | [diff] [blame] | 89 | |
jbauman | 227bc77 | 2016-02-23 20:40:05 | [diff] [blame] | 90 | #if defined(OS_WIN) |
91 | base::TimeDelta GetWatchedThreadTime(); | ||||
92 | #endif | ||||
93 | |||||
[email protected] | dd32b127 | 2013-05-04 14:17:11 | [diff] [blame] | 94 | base::MessageLoop* watched_message_loop_; |
[email protected] | 5f99f45c3 | 2012-01-30 22:21:44 | [diff] [blame] | 95 | base::TimeDelta timeout_; |
[email protected] | 49eab48 | 2010-11-24 00:07:43 | [diff] [blame] | 96 | volatile bool armed_; |
97 | GpuWatchdogTaskObserver task_observer_; | ||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 98 | |
jbauman | fd8b3be | 2016-03-15 00:15:00 | [diff] [blame] | 99 | // 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 | |||||
jbauman | 227bc77 | 2016-02-23 20:40:05 | [diff] [blame] | 107 | #if defined(OS_WIN) |
108 | void* watched_thread_handle_; | ||||
109 | base::TimeDelta arm_cpu_time_; | ||||
jbauman | e6b5e25 | 2016-03-17 03:25:04 | [diff] [blame] | 110 | |
111 | // This measures the time that the system has been running, in units of 100 | ||||
112 | // ns. | ||||
113 | ULONGLONG arm_interrupt_time_; | ||||
jbauman | 227bc77 | 2016-02-23 20:40:05 | [diff] [blame] | 114 | #endif |
115 | |||||
[email protected] | 25cb8c45 | 2013-01-03 02:22:18 | [diff] [blame] | 116 | // 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] | 995a7f1 | 2011-02-11 23:07:17 | [diff] [blame] | 119 | |
[email protected] | 21e2490 | 2013-08-06 20:23:48 | [diff] [blame] | 120 | bool suspended_; |
121 | |||||
jbauman | fd8b3be | 2016-03-15 00:15:00 | [diff] [blame] | 122 | // This is the time the last check was sent. |
123 | base::Time check_time_; | ||||
jbauman | e6b5e25 | 2016-03-17 03:25:04 | [diff] [blame] | 124 | base::TimeTicks check_timeticks_; |
jbauman | fd8b3be | 2016-03-15 00:15:00 | [diff] [blame] | 125 | |
[email protected] | 53cf496 | 2013-10-10 21:57:22 | [diff] [blame] | 126 | #if defined(OS_CHROMEOS) |
127 | FILE* tty_file_; | ||||
128 | #endif | ||||
129 | |||||
sohan.jyoti | cf28abf | 2015-02-18 03:13:42 | [diff] [blame] | 130 | #if defined(USE_X11) |
131 | XDisplay* display_; | ||||
132 | gfx::AcceleratedWidget window_; | ||||
133 | XAtom atom_; | ||||
134 | #endif | ||||
135 | |||||
mohan.reddy | 6993ff9 | 2014-09-12 09:52:40 | [diff] [blame] | 136 | base::WeakPtrFactory<GpuWatchdogThread> weak_factory_; |
137 | |||||
[email protected] | e09cee4 | 2010-11-09 01:50:08 | [diff] [blame] | 138 | DISALLOW_COPY_AND_ASSIGN(GpuWatchdogThread); |
139 | }; | ||||
140 | |||||
[email protected] | eb39819 | 2012-10-22 20:16:19 | [diff] [blame] | 141 | } // namespace content |
142 | |||||
[email protected] | 623c0bd | 2011-03-12 01:00:41 | [diff] [blame] | 143 | #endif // CONTENT_GPU_GPU_WATCHDOG_THREAD_H_ |