Chromium Code Reviews| Index: chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc |
| diff --git a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc |
| index c7c9cca42ebc1c2ee54fa2f87b3096fa459b3617..660fa1aacba89214f431088eeaa057080c6605c4 100644 |
| --- a/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc |
| +++ b/chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.cc |
| @@ -5,10 +5,26 @@ |
| #include "chrome/browser/extensions/api/system_info_cpu/cpu_info_provider.h" |
| #include "base/sys_info.h" |
| +#include "content/public/browser/browser_thread.h" |
| namespace extensions { |
| using api::experimental_system_info_cpu::CpuInfo; |
| +using api::experimental_system_info_cpu::CpuUpdateInfo; |
| +using content::BrowserThread; |
| + |
| +// Default sampling interval is 1000ms. |
| +const unsigned int kDefaultSamplingIntervalMs = 1000; |
| + |
| +CpuInfoProvider::CpuInfoProvider() |
| + : is_sampling_started_(false), |
| + sampling_timer_(NULL), |
| + sampling_interval_(kDefaultSamplingIntervalMs) { |
| +} |
| + |
| +CpuInfoProvider::~CpuInfoProvider() { |
| + DCHECK(!sampling_timer_) << "Fogot to call StopSampling?"; |
|
Mihai Parparita -not on Chrome
2012/09/16 06:23:05
"StartSampling call without a corresponding StopSa
Mihai Parparita -not on Chrome
2012/09/16 06:23:05
Also, this will still leak the sampling timer in n
|
| +} |
| bool CpuInfoProvider::QueryInfo(CpuInfo* info) { |
| if (info == NULL) |
| @@ -20,14 +36,52 @@ bool CpuInfoProvider::QueryInfo(CpuInfo* info) { |
| return true; |
| } |
| -bool CpuInfoProvider::StartSampling(const QueryCpuTimeCallback& callback) { |
| - // TODO(hongbo): Implement sampling functionality for event router. |
| - return false; |
| +bool CpuInfoProvider::StartSampling(const SamplingCallback& callback) { |
| + if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { |
| + return BrowserThread::PostTask( |
| + BrowserThread::FILE, |
| + FROM_HERE, |
| + base::Bind(base::IgnoreResult(&CpuInfoProvider::StartSampling), |
| + base::Unretained(this), callback)); |
| + } |
| + |
| + // We are now on the FILE thread now. |
| + if (is_sampling_started_) return true; |
| + |
| + if (!QueryCpuTimePerProcessor(&sampling_value_)) |
| + return false; |
| + |
| + is_sampling_started_ = true; |
| + callback_ = callback; |
| + |
| + DCHECK(!sampling_timer_) << "The sampling timer is leaked. Did you forgot " |
| + "calling StopSampling?"; |
| + |
| + // Should be deleted in StopSampling. |
| + sampling_timer_ = new base::RepeatingTimer<CpuInfoProvider>(); |
| + |
| + sampling_timer_->Start(FROM_HERE, |
| + base::TimeDelta::FromMilliseconds(sampling_interval_), |
| + this, &CpuInfoProvider::DoStartSampling); |
|
Mihai Parparita -not on Chrome
2012/09/16 06:23:05
DoStartSampling seems like a misnomer, since it is
|
| + |
| + return true; |
| } |
| bool CpuInfoProvider::StopSampling() { |
| - // TODO(hongbo): Implement sampling functionality for event router. |
| - return false; |
| + if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { |
| + return BrowserThread::PostTask( |
| + BrowserThread::FILE, |
| + FROM_HERE, |
| + base::Bind(base::IgnoreResult(&CpuInfoProvider::StopSampling), |
| + base::Unretained(this))); |
| + } |
| + // We are now on the FILE thread now. |
| + if (!is_sampling_started_) return false; |
| + delete sampling_timer_; |
| + sampling_timer_ = NULL; |
| + sampling_value_.clear(); |
| + is_sampling_started_ = false; |
| + return true; |
| } |
| // static |
| @@ -35,4 +89,35 @@ CpuInfoProvider* CpuInfoProvider::Get() { |
| return CpuInfoProvider::GetInstance<CpuInfoProvider>(); |
| } |
| +void CpuInfoProvider::DoStartSampling() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + |
| + std::vector<CpuTime> new_sampling_value; |
| + if (!QueryCpuTimePerProcessor(&new_sampling_value)) |
| + return; |
| + |
| + // Calculate the CPU usage information from the two sampling values. |
| + double total_usage = 0; |
| + scoped_ptr<CpuUpdateInfo> info(new CpuUpdateInfo()); |
| + |
| + for (size_t i = 0; i < new_sampling_value.size(); ++i) { |
| + double total_time = |
| + (new_sampling_value[i].user - sampling_value_[i].user) + |
| + (new_sampling_value[i].kernel - sampling_value_[i].kernel) + |
| + (new_sampling_value[i].idle - sampling_value_[i].idle); |
| + double idle_time = new_sampling_value[i].idle - sampling_value_[i].idle; |
| + |
| + double usage = 0; |
| + if (total_time != 0) |
| + usage = (100 - idle_time * 100 / total_time); |
| + info->usage_per_processor.push_back(usage); |
| + total_usage += usage; |
| + } |
| + |
| + info->average_usage = total_usage / new_sampling_value.size(); |
| + |
| + if (!callback_.is_null()) |
| + callback_.Run(info.Pass()); |
| +} |
| + |
| } // namespace extensions |