Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: base/profiler/stack_sampling_profiler.cc

Issue 1029653002: Enable startup profiling by Win x64 stack sampling profiler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@statprof-metrics-provider
Patch Set: restore AVeryLongTimeDelta Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/profiler/stack_sampling_profiler.h" 5 #include "base/profiler/stack_sampling_profiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
12 #include "base/profiler/native_stack_sampler.h" 12 #include "base/profiler/native_stack_sampler.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "base/timer/elapsed_timer.h" 14 #include "base/timer/elapsed_timer.h"
15 15
16 namespace base { 16 namespace base {
17 17
18 // PendingProfiles ------------------------------------------------------------ 18 // DefaultProfileProcessor ----------------------------------------------------
19 19
20 namespace { 20 namespace {
21 21
22 // Thread-safe singleton class that stores collected call stack profiles waiting 22 // Singleton class responsible for providing the default processing for profiles
23 // to be processed. 23 // (i.e. for profiles generated by profilers without their own completed
24 class PendingProfiles { 24 // callback).
25 class DefaultProfileProcessor {
25 public: 26 public:
26 ~PendingProfiles(); 27 using CompletedCallback = StackSamplingProfiler::CompletedCallback;
27 28
28 static PendingProfiles* GetInstance(); 29 ~DefaultProfileProcessor();
29 30
30 // Appends |profiles| to |profiles_|. This function may be called on any 31 static DefaultProfileProcessor* GetInstance();
31 // thread. 32
32 void AppendProfiles( 33 // Sets the callback to use for processing profiles captured without a
33 const std::vector<StackSamplingProfiler::CallStackProfile>& profiles); 34 // per-profiler completed callback. Pending completed profiles are stored in
35 // this object until a non-null callback is provided here. This function is
36 // thread-safe.
37 void SetCompletedCallback(CompletedCallback callback);
38
39 // Processes |profiles|. This function is thread safe.
40 void ProcessProfiles(
41 const StackSamplingProfiler::CallStackProfiles& profiles);
42
43 private:
44 friend struct DefaultSingletonTraits<DefaultProfileProcessor>;
45
46 DefaultProfileProcessor();
34 47
35 // Copies the pending profiles from |profiles_| into |profiles|, and clears 48 // Copies the pending profiles from |profiles_| into |profiles|, and clears
36 // |profiles_|. This function may be called on any thread. 49 // |profiles_|. This function may be called on any thread.
37 void GetAndClearPendingProfiles( 50 void GetAndClearPendingProfiles(
38 std::vector<StackSamplingProfiler::CallStackProfile>* profiles); 51 StackSamplingProfiler::CallStackProfiles* profiles);
39 52
40 private: 53 // Gets the current completed callback, with proper locking.
41 friend struct DefaultSingletonTraits<PendingProfiles>; 54 CompletedCallback GetCompletedCallback() const;
42 55
43 PendingProfiles(); 56 mutable Lock callback_lock_;
57 CompletedCallback default_completed_callback_;
44 58
45 Lock profiles_lock_; 59 Lock profiles_lock_;
46 std::vector<StackSamplingProfiler::CallStackProfile> profiles_; 60 StackSamplingProfiler::CallStackProfiles profiles_;
47 61
48 DISALLOW_COPY_AND_ASSIGN(PendingProfiles); 62 DISALLOW_COPY_AND_ASSIGN(DefaultProfileProcessor);
49 }; 63 };
50 64
51 PendingProfiles::PendingProfiles() {} 65 DefaultProfileProcessor::~DefaultProfileProcessor() {}
52
53 PendingProfiles::~PendingProfiles() {}
54 66
55 // static 67 // static
56 PendingProfiles* PendingProfiles::GetInstance() { 68 DefaultProfileProcessor* DefaultProfileProcessor::GetInstance() {
57 return Singleton<PendingProfiles>::get(); 69 return Singleton<DefaultProfileProcessor>::get();
58 } 70 }
59 71
60 void PendingProfiles::AppendProfiles( 72 void DefaultProfileProcessor::SetCompletedCallback(CompletedCallback callback) {
61 const std::vector<StackSamplingProfiler::CallStackProfile>& profiles) { 73 {
62 AutoLock scoped_lock(profiles_lock_); 74 AutoLock scoped_lock(callback_lock_);
63 profiles_.insert(profiles_.end(), profiles.begin(), profiles.end()); 75 default_completed_callback_ = callback;
76 }
77
78 if (!callback.is_null()) {
79 // Provide any pending profiles to the callback immediately.
80 StackSamplingProfiler::CallStackProfiles profiles;
81 GetAndClearPendingProfiles(&profiles);
82 if (!profiles.empty())
83 callback.Run(profiles);
84 }
64 } 85 }
65 86
66 void PendingProfiles::GetAndClearPendingProfiles( 87 void DefaultProfileProcessor::ProcessProfiles(
67 std::vector<StackSamplingProfiler::CallStackProfile>* profiles) { 88 const StackSamplingProfiler::CallStackProfiles& profiles) {
89 CompletedCallback callback = GetCompletedCallback();
90
91 // Store pending profiles if we don't have a valid callback.
92 if (!callback.is_null()) {
93 callback.Run(profiles);
94 } else {
95 AutoLock scoped_lock(profiles_lock_);
96 profiles_.insert(profiles_.end(), profiles.begin(), profiles.end());
97 }
98 }
99
100 DefaultProfileProcessor::DefaultProfileProcessor() {}
101
102 void DefaultProfileProcessor::GetAndClearPendingProfiles(
103 StackSamplingProfiler::CallStackProfiles* profiles) {
68 profiles->clear(); 104 profiles->clear();
69 105
70 AutoLock scoped_lock(profiles_lock_); 106 AutoLock scoped_lock(profiles_lock_);
71 profiles_.swap(*profiles); 107 profiles_.swap(*profiles);
72 } 108 }
109 DefaultProfileProcessor::CompletedCallback
110 DefaultProfileProcessor::GetCompletedCallback() const {
111 AutoLock scoped_lock(callback_lock_);
112 return default_completed_callback_;
113 }
73 114
74 } // namespace 115 } // namespace
75 116
76 // StackSamplingProfiler::Module ---------------------------------------------- 117 // StackSamplingProfiler::Module ----------------------------------------------
77 118
78 StackSamplingProfiler::Module::Module() : base_address(nullptr) {} 119 StackSamplingProfiler::Module::Module() : base_address(nullptr) {}
79 StackSamplingProfiler::Module::Module(const void* base_address, 120 StackSamplingProfiler::Module::Module(const void* base_address,
80 const std::string& id, 121 const std::string& id,
81 const FilePath& filename) 122 const FilePath& filename)
82 : base_address(base_address), id(id), filename(filename) {} 123 : base_address(base_address), id(id), filename(filename) {}
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 burst_interval(TimeDelta::FromMilliseconds(10000)), 243 burst_interval(TimeDelta::FromMilliseconds(10000)),
203 samples_per_burst(300), 244 samples_per_burst(300),
204 sampling_interval(TimeDelta::FromMilliseconds(100)), 245 sampling_interval(TimeDelta::FromMilliseconds(100)),
205 preserve_sample_ordering(false) { 246 preserve_sample_ordering(false) {
206 } 247 }
207 248
208 StackSamplingProfiler::StackSamplingProfiler(PlatformThreadId thread_id, 249 StackSamplingProfiler::StackSamplingProfiler(PlatformThreadId thread_id,
209 const SamplingParams& params) 250 const SamplingParams& params)
210 : thread_id_(thread_id), params_(params) {} 251 : thread_id_(thread_id), params_(params) {}
211 252
212 StackSamplingProfiler::~StackSamplingProfiler() {} 253 StackSamplingProfiler::StackSamplingProfiler(PlatformThreadId thread_id,
254 const SamplingParams& params,
255 CompletedCallback callback)
256 : thread_id_(thread_id), params_(params), completed_callback_(callback) {}
257
258 StackSamplingProfiler::~StackSamplingProfiler() {
259 Stop();
260 if (!sampling_thread_handle_.is_null())
261 PlatformThread::Join(sampling_thread_handle_);
262 }
213 263
214 void StackSamplingProfiler::Start() { 264 void StackSamplingProfiler::Start() {
215 scoped_ptr<NativeStackSampler> native_sampler = 265 scoped_ptr<NativeStackSampler> native_sampler =
216 NativeStackSampler::Create(thread_id_); 266 NativeStackSampler::Create(thread_id_);
217 if (!native_sampler) 267 if (!native_sampler)
218 return; 268 return;
219 269
270 CompletedCallback callback =
271 !completed_callback_.is_null() ? completed_callback_ :
272 Bind(&DefaultProfileProcessor::ProcessProfiles,
273 Unretained(DefaultProfileProcessor::GetInstance()));
220 sampling_thread_.reset( 274 sampling_thread_.reset(
221 new SamplingThread( 275 new SamplingThread(native_sampler.Pass(), params_, callback));
222 native_sampler.Pass(), params_, 276 if (!PlatformThread::Create(0, sampling_thread_.get(),
223 (custom_completed_callback_.is_null() ? 277 &sampling_thread_handle_))
224 Bind(&PendingProfiles::AppendProfiles,
225 Unretained(PendingProfiles::GetInstance())) :
226 custom_completed_callback_)));
227 if (!PlatformThread::CreateNonJoinable(0, sampling_thread_.get()))
228 sampling_thread_.reset(); 278 sampling_thread_.reset();
229 } 279 }
230 280
231 void StackSamplingProfiler::Stop() { 281 void StackSamplingProfiler::Stop() {
232 if (sampling_thread_) 282 if (sampling_thread_)
233 sampling_thread_->Stop(); 283 sampling_thread_->Stop();
234 } 284 }
235 285
236 // static 286 // static
237 void StackSamplingProfiler::GetPendingProfiles(CallStackProfiles* profiles) { 287 void StackSamplingProfiler::SetDefaultCompletedCallback(
238 PendingProfiles::GetInstance()->GetAndClearPendingProfiles(profiles); 288 CompletedCallback callback) {
289 DefaultProfileProcessor::GetInstance()->SetCompletedCallback(callback);
239 } 290 }
240 291
241 // StackSamplingProfiler::Frame global functions ------------------------------ 292 // StackSamplingProfiler::Frame global functions ------------------------------
242 293
243 bool operator==(const StackSamplingProfiler::Frame &a, 294 bool operator==(const StackSamplingProfiler::Frame &a,
244 const StackSamplingProfiler::Frame &b) { 295 const StackSamplingProfiler::Frame &b) {
245 return a.instruction_pointer == b.instruction_pointer && 296 return a.instruction_pointer == b.instruction_pointer &&
246 a.module_index == b.module_index; 297 a.module_index == b.module_index;
247 } 298 }
248 299
249 bool operator<(const StackSamplingProfiler::Frame &a, 300 bool operator<(const StackSamplingProfiler::Frame &a,
250 const StackSamplingProfiler::Frame &b) { 301 const StackSamplingProfiler::Frame &b) {
251 return (a.module_index < b.module_index) || 302 return (a.module_index < b.module_index) ||
252 (a.module_index == b.module_index && 303 (a.module_index == b.module_index &&
253 a.instruction_pointer < b.instruction_pointer); 304 a.instruction_pointer < b.instruction_pointer);
254 } 305 }
255 306
256 } // namespace base 307 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698