Home | History | Annotate | Download | only in metrics
      1 # Copyright 2013 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 from metrics import Metric
      6 
      7 class CpuMetric(Metric):
      8   """Calulates CPU load over a span of time."""
      9 
     10   def __init__(self, browser):
     11     super(CpuMetric, self).__init__()
     12     self._results = None
     13     self._browser = browser
     14     self._start_cpu = None
     15 
     16   def DidStartBrowser(self, browser):
     17     # Save the browser object so that cpu_stats can be accessed later.
     18     self._browser = browser
     19 
     20   def Start(self, page, tab):
     21     self._start_cpu = self._browser.cpu_stats
     22 
     23   def Stop(self, page, tab):
     24     assert self._start_cpu, 'Must call Start() first'
     25     self._results = _SubtractCpuStats(self._browser.cpu_stats, self._start_cpu)
     26 
     27   # Optional argument trace_name is not in base class Metric.
     28   # pylint: disable=W0221
     29   def AddResults(self, tab, results, trace_name='cpu_utilization'):
     30     assert self._results, 'Must call Stop() first'
     31     # Add a result for each process type.
     32     for process_type in self._results:
     33       trace_name = '%s_%s' % (trace_name, process_type.lower())
     34       cpu_percent = 100 * self._results[process_type]
     35       results.Add(trace_name, '%', cpu_percent, chart_name='cpu_utilization',
     36                   data_type='unimportant')
     37 
     38 
     39 def _SubtractCpuStats(cpu_stats, start_cpu_stats):
     40   """Computes average cpu usage over a time period for different process types.
     41 
     42   Each of the two cpu_stats arguments is a dict with the following format:
     43       {'Browser': {'CpuProcessTime': ..., 'TotalTime': ...},
     44        'Renderer': {'CpuProcessTime': ..., 'TotalTime': ...}
     45        'Gpu': {'CpuProcessTime': ..., 'TotalTime': ...}}
     46 
     47   The 'CpuProcessTime' fields represent the number of seconds of CPU time
     48   spent in each process, and total time is the number of real seconds
     49   that have passed (this may be a Unix timestamp).
     50 
     51   Returns:
     52     A dict of process type names (Browser, Renderer, etc.) to ratios of cpu
     53     time used to total time elapsed.
     54   """
     55   cpu_usage = {}
     56   for process_type in cpu_stats:
     57     assert process_type in start_cpu_stats, 'Mismatching process types'
     58     # Skip any process_types that are empty.
     59     if (not cpu_stats[process_type]) or (not start_cpu_stats[process_type]):
     60       continue
     61     cpu_process_time = (cpu_stats[process_type]['CpuProcessTime'] -
     62                         start_cpu_stats[process_type]['CpuProcessTime'])
     63     total_time = (cpu_stats[process_type]['TotalTime'] -
     64                   start_cpu_stats[process_type]['TotalTime'])
     65     assert total_time > 0, 'Expected total_time > 0, was: %d' % total_time
     66     cpu_usage[process_type] = float(cpu_process_time) / total_time
     67   return cpu_usage
     68 
     69