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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: base/profiler/stack_sampling_profiler.cc
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index 317400b2d4d70422b34f1abe7af1f4975e046522..1c08234fdf39ae05d5ff0d6326e49effb92cab01 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -15,61 +15,102 @@
namespace base {
-// PendingProfiles ------------------------------------------------------------
+// DefaultProfileProcessor ----------------------------------------------------
namespace {
-// Thread-safe singleton class that stores collected call stack profiles waiting
-// to be processed.
-class PendingProfiles {
+// Singleton class responsible for providing the default processing for profiles
+// (i.e. for profiles generated by profilers without their own completed
+// callback).
+class DefaultProfileProcessor {
public:
- ~PendingProfiles();
+ using CompletedCallback = StackSamplingProfiler::CompletedCallback;
- static PendingProfiles* GetInstance();
+ ~DefaultProfileProcessor();
- // Appends |profiles| to |profiles_|. This function may be called on any
- // thread.
- void AppendProfiles(
- const std::vector<StackSamplingProfiler::CallStackProfile>& profiles);
+ static DefaultProfileProcessor* GetInstance();
+
+ // Sets the callback to use for processing profiles captured without a
+ // per-profiler completed callback. Pending completed profiles are stored in
+ // this object until a non-null callback is provided here. This function is
+ // thread-safe.
+ void SetCompletedCallback(CompletedCallback callback);
+
+ // Processes |profiles|. This function is thread safe.
+ void ProcessProfiles(
+ const StackSamplingProfiler::CallStackProfiles& profiles);
+
+ private:
+ friend struct DefaultSingletonTraits<DefaultProfileProcessor>;
+
+ DefaultProfileProcessor();
// Copies the pending profiles from |profiles_| into |profiles|, and clears
// |profiles_|. This function may be called on any thread.
void GetAndClearPendingProfiles(
- std::vector<StackSamplingProfiler::CallStackProfile>* profiles);
+ StackSamplingProfiler::CallStackProfiles* profiles);
- private:
- friend struct DefaultSingletonTraits<PendingProfiles>;
+ // Gets the current completed callback, with proper locking.
+ CompletedCallback GetCompletedCallback() const;
- PendingProfiles();
+ mutable Lock callback_lock_;
+ CompletedCallback default_completed_callback_;
Lock profiles_lock_;
- std::vector<StackSamplingProfiler::CallStackProfile> profiles_;
+ StackSamplingProfiler::CallStackProfiles profiles_;
- DISALLOW_COPY_AND_ASSIGN(PendingProfiles);
+ DISALLOW_COPY_AND_ASSIGN(DefaultProfileProcessor);
};
-PendingProfiles::PendingProfiles() {}
-
-PendingProfiles::~PendingProfiles() {}
+DefaultProfileProcessor::~DefaultProfileProcessor() {}
// static
-PendingProfiles* PendingProfiles::GetInstance() {
- return Singleton<PendingProfiles>::get();
+DefaultProfileProcessor* DefaultProfileProcessor::GetInstance() {
+ return Singleton<DefaultProfileProcessor>::get();
}
-void PendingProfiles::AppendProfiles(
- const std::vector<StackSamplingProfiler::CallStackProfile>& profiles) {
- AutoLock scoped_lock(profiles_lock_);
- profiles_.insert(profiles_.end(), profiles.begin(), profiles.end());
+void DefaultProfileProcessor::SetCompletedCallback(CompletedCallback callback) {
+ {
+ AutoLock scoped_lock(callback_lock_);
+ default_completed_callback_ = callback;
+ }
+
+ if (!callback.is_null()) {
+ // Provide any pending profiles to the callback immediately.
+ StackSamplingProfiler::CallStackProfiles profiles;
+ GetAndClearPendingProfiles(&profiles);
+ if (!profiles.empty())
+ callback.Run(profiles);
+ }
+}
+
+void DefaultProfileProcessor::ProcessProfiles(
+ const StackSamplingProfiler::CallStackProfiles& profiles) {
+ CompletedCallback callback = GetCompletedCallback();
+
+ // Store pending profiles if we don't have a valid callback.
+ if (!callback.is_null()) {
+ callback.Run(profiles);
+ } else {
+ AutoLock scoped_lock(profiles_lock_);
+ profiles_.insert(profiles_.end(), profiles.begin(), profiles.end());
+ }
}
-void PendingProfiles::GetAndClearPendingProfiles(
- std::vector<StackSamplingProfiler::CallStackProfile>* profiles) {
+DefaultProfileProcessor::DefaultProfileProcessor() {}
+
+void DefaultProfileProcessor::GetAndClearPendingProfiles(
+ StackSamplingProfiler::CallStackProfiles* profiles) {
profiles->clear();
AutoLock scoped_lock(profiles_lock_);
profiles_.swap(*profiles);
}
+DefaultProfileProcessor::CompletedCallback
+DefaultProfileProcessor::GetCompletedCallback() const {
+ AutoLock scoped_lock(callback_lock_);
+ return default_completed_callback_;
+}
} // namespace
@@ -209,7 +250,16 @@ StackSamplingProfiler::StackSamplingProfiler(PlatformThreadId thread_id,
const SamplingParams& params)
: thread_id_(thread_id), params_(params) {}
-StackSamplingProfiler::~StackSamplingProfiler() {}
+StackSamplingProfiler::StackSamplingProfiler(PlatformThreadId thread_id,
+ const SamplingParams& params,
+ CompletedCallback callback)
+ : thread_id_(thread_id), params_(params), completed_callback_(callback) {}
+
+StackSamplingProfiler::~StackSamplingProfiler() {
+ Stop();
+ if (!sampling_thread_handle_.is_null())
+ PlatformThread::Join(sampling_thread_handle_);
+}
void StackSamplingProfiler::Start() {
scoped_ptr<NativeStackSampler> native_sampler =
@@ -217,14 +267,14 @@ void StackSamplingProfiler::Start() {
if (!native_sampler)
return;
+ CompletedCallback callback =
+ !completed_callback_.is_null() ? completed_callback_ :
+ Bind(&DefaultProfileProcessor::ProcessProfiles,
+ Unretained(DefaultProfileProcessor::GetInstance()));
sampling_thread_.reset(
- new SamplingThread(
- native_sampler.Pass(), params_,
- (custom_completed_callback_.is_null() ?
- Bind(&PendingProfiles::AppendProfiles,
- Unretained(PendingProfiles::GetInstance())) :
- custom_completed_callback_)));
- if (!PlatformThread::CreateNonJoinable(0, sampling_thread_.get()))
+ new SamplingThread(native_sampler.Pass(), params_, callback));
+ if (!PlatformThread::Create(0, sampling_thread_.get(),
+ &sampling_thread_handle_))
sampling_thread_.reset();
}
@@ -234,8 +284,9 @@ void StackSamplingProfiler::Stop() {
}
// static
-void StackSamplingProfiler::GetPendingProfiles(CallStackProfiles* profiles) {
- PendingProfiles::GetInstance()->GetAndClearPendingProfiles(profiles);
+void StackSamplingProfiler::SetDefaultCompletedCallback(
+ CompletedCallback callback) {
+ DefaultProfileProcessor::GetInstance()->SetCompletedCallback(callback);
}
// StackSamplingProfiler::Frame global functions ------------------------------

Powered by Google App Engine
This is Rietveld 408576698