root/chrome/browser/performance_monitor/process_metrics_history.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. last_update_sequence_
  2. ResetCounters
  3. Initialize
  4. SampleMetrics
  5. EndOfCycle
  6. RunPerformanceTriggers

// Copyright 2013 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 <limits>

#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/process/process_metrics.h"

#include "chrome/browser/performance_monitor/constants.h"
#include "chrome/browser/performance_monitor/process_metrics_history.h"
#if defined(OS_MACOSX)
#include "content/public/browser/browser_child_process_host.h"
#endif
#include "content/public/common/process_type.h"

namespace performance_monitor {

ProcessMetricsHistory::ProcessMetricsHistory()
    : process_handle_(0),
      process_type_(content::PROCESS_TYPE_UNKNOWN),
      last_update_sequence_(0) {
  ResetCounters();
}

ProcessMetricsHistory::~ProcessMetricsHistory() {}

void ProcessMetricsHistory::ResetCounters() {
  min_cpu_usage_ = std::numeric_limits<double>::max();
  accumulated_cpu_usage_ = 0.0;
  accumulated_private_bytes_ = 0;
  accumulated_shared_bytes_ = 0;
  sample_count_ = 0;
}

void ProcessMetricsHistory::Initialize(base::ProcessHandle process_handle,
                                       int process_type,
                                       int initial_update_sequence) {
  DCHECK(process_handle_ == 0);
  process_handle_ = process_handle;
  process_type_ = process_type;
  last_update_sequence_ = initial_update_sequence;

#if defined(OS_MACOSX)
  process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(
      process_handle_, content::BrowserChildProcessHost::GetPortProvider()));
#else
  process_metrics_.reset(
      base::ProcessMetrics::CreateProcessMetrics(process_handle_));
#endif
}

void ProcessMetricsHistory::SampleMetrics() {
  double cpu_usage = process_metrics_->GetPlatformIndependentCPUUsage();
  min_cpu_usage_ = std::min(min_cpu_usage_, cpu_usage);
  accumulated_cpu_usage_ += cpu_usage;

  size_t private_bytes = 0;
  size_t shared_bytes = 0;
  if (!process_metrics_->GetMemoryBytes(&private_bytes, &shared_bytes))
    LOG(WARNING) << "GetMemoryBytes returned NULL (platform-specific error)";

  accumulated_private_bytes_ += private_bytes;
  accumulated_shared_bytes_ += shared_bytes;

  sample_count_++;
}

void ProcessMetricsHistory::EndOfCycle() {
  RunPerformanceTriggers();
  ResetCounters();
}

void ProcessMetricsHistory::RunPerformanceTriggers() {
  if (sample_count_ == 0)
    return;

  // We scale up to the equivalent of 64 CPU cores fully loaded. More than this
  // doesn't really matter, as we're already in a terrible place.
  const int kHistogramMin = 0;
  const int kHistogramMax = 6400;
  const int kHistogramBucketCount = 50;

  const double average_cpu_usage = accumulated_cpu_usage_ / sample_count_;

  // The histogram macros don't support variables as histogram names,
  // hence the macro duplication for each process type.
  switch (process_type_) {
    case content::PROCESS_TYPE_BROWSER:
      UMA_HISTOGRAM_CUSTOM_COUNTS(
          "PerformanceMonitor.AverageCPU.BrowserProcess", average_cpu_usage,
          kHistogramMin, kHistogramMax, kHistogramBucketCount);
      // If CPU usage has consistently been above our threshold,
      // we *may* have an issue.
      if (min_cpu_usage_ > kHighCPUUtilizationThreshold) {
        UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.BrowserProcess",
                              true);
      }
      break;
    case content::PROCESS_TYPE_RENDERER:
      UMA_HISTOGRAM_CUSTOM_COUNTS(
          "PerformanceMonitor.AverageCPU.RendererProcess", average_cpu_usage,
          kHistogramMin, kHistogramMax, kHistogramBucketCount);
      if (min_cpu_usage_ > kHighCPUUtilizationThreshold) {
        UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.RendererProcess",
                              true);
      }
      break;
    case content::PROCESS_TYPE_PLUGIN:
      UMA_HISTOGRAM_CUSTOM_COUNTS(
          "PerformanceMonitor.AverageCPU.PluginProcess", average_cpu_usage,
          kHistogramMin, kHistogramMax, kHistogramBucketCount);
      if (min_cpu_usage_ > kHighCPUUtilizationThreshold)
        UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.PluginProcess", true);
      break;
    case content::PROCESS_TYPE_WORKER:
      UMA_HISTOGRAM_CUSTOM_COUNTS(
          "PerformanceMonitor.AverageCPU.WorkerProcess", average_cpu_usage,
          kHistogramMin, kHistogramMax, kHistogramBucketCount);
      if (min_cpu_usage_ > kHighCPUUtilizationThreshold)
        UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.WorkerProcess", true);
      break;
    case content::PROCESS_TYPE_GPU:
      UMA_HISTOGRAM_CUSTOM_COUNTS(
          "PerformanceMonitor.AverageCPU.GPUProcess", average_cpu_usage,
          kHistogramMin, kHistogramMax, kHistogramBucketCount);
      if (min_cpu_usage_ > kHighCPUUtilizationThreshold)
        UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.GPUProcess", true);
      break;
    case content::PROCESS_TYPE_PPAPI_PLUGIN:
      UMA_HISTOGRAM_CUSTOM_COUNTS(
          "PerformanceMonitor.AverageCPU.PPAPIProcess", average_cpu_usage,
          kHistogramMin, kHistogramMax, kHistogramBucketCount);
      if (min_cpu_usage_ > kHighCPUUtilizationThreshold)
        UMA_HISTOGRAM_BOOLEAN("PerformanceMonitor.HighCPU.PPAPIProcess", true);
      break;
    default:
      break;
  }
}

}  // namespace performance_monitor

/* [<][>][^][v][top][bottom][index][help] */