OLD | NEW |
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 "gpu/ipc/service/gpu_watchdog_thread.h" | 5 #include "gpu/ipc/service/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" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 arm_cpu_time_(), | 59 arm_cpu_time_(), |
60 #endif | 60 #endif |
61 suspended_(false), | 61 suspended_(false), |
62 #if defined(USE_X11) | 62 #if defined(USE_X11) |
63 display_(NULL), | 63 display_(NULL), |
64 window_(0), | 64 window_(0), |
65 atom_(None), | 65 atom_(None), |
66 host_tty_(-1), | 66 host_tty_(-1), |
67 #endif | 67 #endif |
68 weak_factory_(this) { | 68 weak_factory_(this) { |
| 69 base::subtle::NoBarrier_Store(&awaiting_acknowledge_, false); |
| 70 |
69 #if defined(OS_WIN) | 71 #if defined(OS_WIN) |
70 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread | 72 // GetCurrentThread returns a pseudo-handle that cannot be used by one thread |
71 // to identify another. DuplicateHandle creates a "real" handle that can be | 73 // to identify another. DuplicateHandle creates a "real" handle that can be |
72 // used for this purpose. | 74 // used for this purpose. |
73 BOOL result = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), | 75 BOOL result = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), |
74 GetCurrentProcess(), &watched_thread_handle_, | 76 GetCurrentProcess(), &watched_thread_handle_, |
75 THREAD_QUERY_INFORMATION, FALSE, 0); | 77 THREAD_QUERY_INFORMATION, FALSE, 0); |
76 DCHECK(result); | 78 DCHECK(result); |
77 #endif | 79 #endif |
78 | 80 |
(...skipping 14 matching lines...) Expand all Loading... |
93 } | 95 } |
94 | 96 |
95 void GpuWatchdogThread::PostAcknowledge() { | 97 void GpuWatchdogThread::PostAcknowledge() { |
96 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use | 98 // Called on the monitored thread. Responds with OnAcknowledge. Cannot use |
97 // the method factory. Rely on reference counting instead. | 99 // the method factory. Rely on reference counting instead. |
98 task_runner()->PostTask(FROM_HERE, | 100 task_runner()->PostTask(FROM_HERE, |
99 base::Bind(&GpuWatchdogThread::OnAcknowledge, this)); | 101 base::Bind(&GpuWatchdogThread::OnAcknowledge, this)); |
100 } | 102 } |
101 | 103 |
102 void GpuWatchdogThread::CheckArmed() { | 104 void GpuWatchdogThread::CheckArmed() { |
103 // Acknowledge the watchdog if it has armed itself. The watchdog will not | 105 // If the watchdog is |awaiting_acknowledge_|, reset this variable to false |
104 // change its armed state until it is acknowledged. | 106 // and post an acknowledge task now. No barrier is needed as |
105 if (armed()) { | 107 // |awaiting_acknowledge_| is only ever read from this thread. |
| 108 if (base::subtle::NoBarrier_CompareAndSwap(&awaiting_acknowledge_, true, |
| 109 false)) |
106 PostAcknowledge(); | 110 PostAcknowledge(); |
107 } | |
108 } | 111 } |
109 | 112 |
110 void GpuWatchdogThread::Init() { | 113 void GpuWatchdogThread::Init() { |
111 // Schedule the first check. | 114 // Schedule the first check. |
112 OnCheck(false); | 115 OnCheck(false); |
113 } | 116 } |
114 | 117 |
115 void GpuWatchdogThread::CleanUp() { | 118 void GpuWatchdogThread::CleanUp() { |
116 weak_factory_.InvalidateWeakPtrs(); | 119 weak_factory_.InvalidateWeakPtrs(); |
117 } | 120 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } | 205 } |
203 | 206 |
204 void GpuWatchdogThread::OnCheck(bool after_suspend) { | 207 void GpuWatchdogThread::OnCheck(bool after_suspend) { |
205 CHECK(base::PlatformThread::CurrentId() == GetThreadId()); | 208 CHECK(base::PlatformThread::CurrentId() == GetThreadId()); |
206 | 209 |
207 // Do not create any new termination tasks if one has already been created | 210 // Do not create any new termination tasks if one has already been created |
208 // or the system is suspended. | 211 // or the system is suspended. |
209 if (armed_ || suspended_) | 212 if (armed_ || suspended_) |
210 return; | 213 return; |
211 | 214 |
212 // Must set armed before posting the task. This task might be the only task | |
213 // that will activate the TaskObserver on the watched thread and it must not | |
214 // miss the false -> true transition. | |
215 armed_ = true; | 215 armed_ = true; |
216 | 216 |
| 217 // Must set |awaiting_acknowledge_| before posting the task. This task might |
| 218 // be the only task that will activate the TaskObserver on the watched thread |
| 219 // and it must not miss the false -> true transition. No barrier is needed |
| 220 // here, as the PostTask which follows contains a barrier. |
| 221 base::subtle::NoBarrier_Store(&awaiting_acknowledge_, true); |
| 222 |
217 #if defined(OS_WIN) | 223 #if defined(OS_WIN) |
218 arm_cpu_time_ = GetWatchedThreadTime(); | 224 arm_cpu_time_ = GetWatchedThreadTime(); |
219 | 225 |
220 QueryUnbiasedInterruptTime(&arm_interrupt_time_); | 226 QueryUnbiasedInterruptTime(&arm_interrupt_time_); |
221 #endif | 227 #endif |
222 | 228 |
223 check_time_ = base::Time::Now(); | 229 check_time_ = base::Time::Now(); |
224 check_timeticks_ = base::TimeTicks::Now(); | 230 check_timeticks_ = base::TimeTicks::Now(); |
225 // Immediately after the computer is woken up from being suspended it might | 231 // Immediately after the computer is woken up from being suspended it might |
226 // be pretty sluggish, so allow some extra time before the next timeout. | 232 // be pretty sluggish, so allow some extra time before the next timeout. |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 int tty_number; | 481 int tty_number; |
476 size_t num_res = sscanf(tty_string, "tty%d\n", &tty_number); | 482 size_t num_res = sscanf(tty_string, "tty%d\n", &tty_number); |
477 if (num_res == 1) | 483 if (num_res == 1) |
478 return tty_number; | 484 return tty_number; |
479 } | 485 } |
480 return -1; | 486 return -1; |
481 } | 487 } |
482 #endif | 488 #endif |
483 | 489 |
484 } // namespace gpu | 490 } // namespace gpu |
OLD | NEW |