| 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 |