Chromium Code Reviews| Index: base/profiler/cpu_profiler.cc |
| diff --git a/base/profiler/cpu_profiler.cc b/base/profiler/cpu_profiler.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a96bedb498d03f95e25f8217dd4808353a74d60f |
| --- /dev/null |
| +++ b/base/profiler/cpu_profiler.cc |
| @@ -0,0 +1,165 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/profiler/cpu_profiler.h" |
| + |
| +#include <stddef.h> |
| + |
| +#include "base/debug/stack_trace.h" |
| +#include "base/metrics/field_trial.h" |
| +#include "base/strings/string_number_conversions.h" |
| +#include "base/threading/thread_id_name_manager.h" |
| +#include "base/time/time.h" |
| +#include "base/timer/elapsed_timer.h" |
| + |
| +namespace base { |
| + |
| +namespace { |
| + |
| +const char kMode[] = "Mode"; |
| +const char kInitialDelay[] = "InitialDelay"; |
| +const char kNumberOfBursts[] = "NumberOfBursts"; |
| +const char kBurstIdleTime[] = "IdleTime"; |
| +const char kNumberOfSamples[] = "NumberOfSamples"; |
| +const char kSamplingSleepTime[] = "SamplingSleepTime"; |
| + |
| +} // namespace |
| + |
| +CpuProfiler* CpuProfiler::g_instance_ = NULL; |
| + |
| +SamplingThread::SamplingThread() |
| + : thread_running_(false), |
| + waitable_event_(false, false) { |
| +} |
| + |
| +SamplingThread::~SamplingThread() {} |
| + |
| +void SamplingThread::ThreadMain() { |
| + PlatformThread::SetName("Chrome_CPUProfilerThread"); |
| + thread_running_ = true; |
| + |
|
cpu_(ooo_6.6-7.5)
2015/02/05 22:41:47
Note that GetInstance() is not thread safe.
As-is
Mike Wittman
2015/02/06 20:01:14
Done.
|
| + CpuProfiler* instance = CpuProfiler::GetInstance(); |
| + if (instance->GetStringParam(kMode) == "bursts") { |
| + int64 initial_delay = instance->GetInt64Param(kInitialDelay); |
| + int number_of_bursts = instance->GetIntParam(kNumberOfBursts); |
| + int64 burst_idle_time = instance->GetInt64Param(kBurstIdleTime); |
| + int number_of_samples = instance->GetIntParam(kNumberOfSamples); |
| + int64 sampling_sleep_time = instance->GetInt64Param(kSamplingSleepTime); |
| + |
| + if (waitable_event_.TimedWait(TimeDelta::FromMicroseconds(initial_delay))) |
| + return; |
| + for (int i = 0; i < number_of_bursts; ++i) { |
| + int64 delta = 0; |
| + for (int j = 0; ; ++j) { |
| + base::ElapsedTimer time; |
| + GetSamples(); |
| + delta = time.Elapsed().InMicroseconds(); |
| + if (j == (number_of_samples - 1)) |
| + break; |
| + if (delta < sampling_sleep_time) { |
| + if (waitable_event_.TimedWait( |
| + TimeDelta::FromMicroseconds(sampling_sleep_time - delta))) |
| + return; |
| + } else { |
| + if (waitable_event_.TimedWait( |
| + TimeDelta::FromMicroseconds(sampling_sleep_time))) |
| + return; |
| + } |
| + } |
| + if (waitable_event_.TimedWait( |
| + TimeDelta::FromMicroseconds(burst_idle_time - delta))) |
| + return; |
| + } |
| + } |
| +} |
| + |
| +void SamplingThread::Stop() { |
| + waitable_event_.Signal(); |
| +} |
| + |
| +void SamplingThread::GetSamples() { |
| + CpuProfiler* instance = CpuProfiler::GetInstance(); |
| + instance->OnTimer(); |
| +} |
| + |
| +// static |
| +void CpuProfiler::Initialize(const std::map<std::string, std::string>* params) { |
| + if (!CpuProfiler::IsPlatformSupported()) |
| + return; |
| + |
| + CpuProfiler* instance = CpuProfiler::GetInstance(); |
| + |
| + // temp code ================== |
| + std::map<std::string, std::string> default_params; |
| + default_params[kMode] = "bursts"; |
| + default_params[kInitialDelay] = "2000000"; // 2 sec |
| + default_params[kNumberOfBursts] = "10"; |
| + default_params[kBurstIdleTime] = "10000000"; // 10 sec |
| + default_params[kNumberOfSamples] = "20"; |
| + default_params[kSamplingSleepTime] = "50000"; // 10 ms |
| + |
| + if (!params) |
| + instance->SetParams(default_params); |
| + else |
| + // end temp code ================== |
|
cpu_(ooo_6.6-7.5)
2015/02/05 22:41:47
don't add a comment between single line else and t
Mike Wittman
2015/02/06 20:01:14
Done.
|
| + instance->SetParams(*params); |
| + |
| + instance->sampling_thread_.reset(new SamplingThread()); |
| + if (!PlatformThread::Create( |
| + 0, instance->sampling_thread_.get(), |
| + &instance->sampling_thread_handle_)) { |
| + LOG(ERROR) << "failed to create thread"; |
| + } |
| +} |
| + |
| +// static |
| +CpuProfiler* CpuProfiler::GetInstance() { |
| + if (!g_instance_) { |
| + g_instance_ = new CpuProfiler(); |
| + } |
| + return g_instance_; |
| +} |
| + |
| +// static |
| +void CpuProfiler::Stop() { |
| + CpuProfiler* instance = CpuProfiler::GetInstance(); |
| + if (instance && instance->sampling_thread_) |
| + instance->sampling_thread_->Stop(); |
| +} |
| + |
| + |
| +std::string CpuProfiler::GetStringParam(const std::string& key) { |
| + const auto entry = params_.find(key); |
|
cpu_(ooo_6.6-7.5)
2015/02/05 22:41:47
const auto& ?
Mike Wittman
2015/02/06 20:01:14
If you prefer; not sure the additional iterator co
cpu_(ooo_6.6-7.5)
2015/02/07 01:27:27
I misread, as is is fine.
|
| + if (entry != params_.end()) { |
| + return entry->second; |
| + } |
| + return ""; |
| +} |
| + |
| +int CpuProfiler::GetIntParam(const std::string& key) { |
| + const auto entry = params_.find(key); |
| + if (entry != params_.end()) { |
| + int output; |
| + if (base::StringToInt(entry->second, &output)) |
| + return output; |
| + } |
| + return 0; |
| +} |
| + |
| +int64 CpuProfiler::GetInt64Param(const std::string& key) { |
| + const auto entry = params_.find(key); |
|
cpu_(ooo_6.6-7.5)
2015/02/05 22:41:47
same here I think you mean a reference.
Mike Wittman
2015/02/06 20:01:14
Done.
|
| + if (entry != params_.end()) { |
| + int64 output; |
| + if (base::StringToInt64(entry->second, &output)) |
| + return output; |
| + } |
| + return 0; |
| +} |
| + |
| +void CpuProfiler::SetParams( |
| + const std::map<std::string, std::string>& params) { |
| + params_ = params; |
| +} |
| + |
| +} // namespace base |