OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <objbase.h> | 5 #include <objbase.h> |
6 #include <windows.h> | 6 #include <windows.h> |
7 #include <winternl.h> | 7 #include <winternl.h> |
8 | 8 |
9 #include <cstdlib> | 9 #include <cstdlib> |
10 #include <map> | 10 #include <map> |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 | 238 |
239 private: | 239 private: |
240 HANDLE thread_handle_; | 240 HANDLE thread_handle_; |
241 bool was_successful_; | 241 bool was_successful_; |
242 | 242 |
243 DISALLOW_COPY_AND_ASSIGN(ScopedSuspendThread); | 243 DISALLOW_COPY_AND_ASSIGN(ScopedSuspendThread); |
244 }; | 244 }; |
245 | 245 |
246 ScopedSuspendThread::ScopedSuspendThread(HANDLE thread_handle) | 246 ScopedSuspendThread::ScopedSuspendThread(HANDLE thread_handle) |
247 : thread_handle_(thread_handle), | 247 : thread_handle_(thread_handle), |
248 was_successful_(::SuspendThread(thread_handle) != -1) { | 248 was_successful_(::SuspendThread(thread_handle) != |
249 } | 249 static_cast<DWORD>(-1)) {} |
250 | 250 |
251 ScopedSuspendThread::~ScopedSuspendThread() { | 251 ScopedSuspendThread::~ScopedSuspendThread() { |
252 if (!was_successful_) | 252 if (!was_successful_) |
253 return; | 253 return; |
254 | 254 |
255 // Disable the priority boost that the thread would otherwise receive on | 255 // Disable the priority boost that the thread would otherwise receive on |
256 // resume. We do this to avoid artificially altering the dynamics of the | 256 // resume. We do this to avoid artificially altering the dynamics of the |
257 // executing application any more than we already are by suspending and | 257 // executing application any more than we already are by suspending and |
258 // resuming the thread. | 258 // resuming the thread. |
259 // | 259 // |
260 // Note that this can racily disable a priority boost that otherwise would | 260 // Note that this can racily disable a priority boost that otherwise would |
261 // have been given to the thread, if the thread is waiting on other wait | 261 // have been given to the thread, if the thread is waiting on other wait |
262 // conditions at the time of SuspendThread and those conditions are satisfied | 262 // conditions at the time of SuspendThread and those conditions are satisfied |
263 // before priority boost is reenabled. The measured length of this window is | 263 // before priority boost is reenabled. The measured length of this window is |
264 // ~100us, so this should occur fairly rarely. | 264 // ~100us, so this should occur fairly rarely. |
265 ScopedDisablePriorityBoost disable_priority_boost(thread_handle_); | 265 ScopedDisablePriorityBoost disable_priority_boost(thread_handle_); |
266 bool resume_thread_succeeded = ::ResumeThread(thread_handle_) != -1; | 266 bool resume_thread_succeeded = |
| 267 ::ResumeThread(thread_handle_) != static_cast<DWORD>(-1); |
267 CHECK(resume_thread_succeeded) << "ResumeThread failed: " << GetLastError(); | 268 CHECK(resume_thread_succeeded) << "ResumeThread failed: " << GetLastError(); |
268 } | 269 } |
269 | 270 |
270 // Suspends the thread with |thread_handle|, copies its stack and resumes the | 271 // Suspends the thread with |thread_handle|, copies its stack and resumes the |
271 // thread, then records the stack into |instruction_pointers| and associated | 272 // thread, then records the stack into |instruction_pointers| and associated |
272 // modules into |modules|. | 273 // modules into |modules|. |
273 // | 274 // |
274 // IMPORTANT NOTE: No allocations from the default heap may occur in the | 275 // IMPORTANT NOTE: No allocations from the default heap may occur in the |
275 // ScopedSuspendThread scope, including indirectly via use of DCHECK/CHECK or | 276 // ScopedSuspendThread scope, including indirectly via use of DCHECK/CHECK or |
276 // other logging statements. Otherwise this code can deadlock on heap locks in | 277 // other logging statements. Otherwise this code can deadlock on heap locks in |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 if (thread_handle) { | 497 if (thread_handle) { |
497 return scoped_ptr<NativeStackSampler>(new NativeStackSamplerWin( | 498 return scoped_ptr<NativeStackSampler>(new NativeStackSamplerWin( |
498 win::ScopedHandle(thread_handle), | 499 win::ScopedHandle(thread_handle), |
499 test_delegate)); | 500 test_delegate)); |
500 } | 501 } |
501 #endif | 502 #endif |
502 return scoped_ptr<NativeStackSampler>(); | 503 return scoped_ptr<NativeStackSampler>(); |
503 } | 504 } |
504 | 505 |
505 } // namespace base | 506 } // namespace base |
OLD | NEW |