cpu.py revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)# found in the LICENSE file. 458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from metrics import Metric 658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class CpuMetric(Metric): 858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) """Calulates CPU load over a span of time.""" 958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def __init__(self, browser): 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) super(CpuMetric, self).__init__() 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._results = None 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._browser = browser 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._start_cpu = None 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def DidStartBrowser(self, browser): 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Save the browser object so that cpu_stats can be accessed later. 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self._browser = browser 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def Start(self, page, tab): 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._start_cpu = self._browser.cpu_stats 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def Stop(self, page, tab): 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert self._start_cpu, 'Must call Start() first' 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) self._results = _SubtractCpuStats(self._browser.cpu_stats, self._start_cpu) 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Optional argument trace_name is not in base class Metric. 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) # pylint: disable=W0221 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) def AddResults(self, tab, results, trace_name='cpu_utilization'): 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert self._results, 'Must call Stop() first' 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Add a result for each process type. 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for process_type in self._results: 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) trace_name = '%s_%s' % (trace_name, process_type.lower()) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cpu_percent = 100 * self._results[process_type] 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) results.Add(trace_name, '%', cpu_percent, chart_name='cpu_utilization', 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) data_type='unimportant') 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)def _SubtractCpuStats(cpu_stats, start_cpu_stats): 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """Computes average cpu usage over a time period for different process types. 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Each of the two cpu_stats arguments is a dict with the following format: 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) {'Browser': {'CpuProcessTime': ..., 'TotalTime': ...}, 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'Renderer': {'CpuProcessTime': ..., 'TotalTime': ...} 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 'Gpu': {'CpuProcessTime': ..., 'TotalTime': ...}} 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) The 'CpuProcessTime' fields represent the number of seconds of CPU time 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) spent in each process, and total time is the number of real seconds 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) that have passed (this may be a Unix timestamp). 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Returns: 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) A dict of process type names (Browser, Renderer, etc.) to ratios of cpu 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) time used to total time elapsed. 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) """ 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cpu_usage = {} 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for process_type in cpu_stats: 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert process_type in start_cpu_stats, 'Mismatching process types' 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) # Skip any process_types that are empty. 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (not cpu_stats[process_type]) or (not start_cpu_stats[process_type]): 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cpu_process_time = (cpu_stats[process_type]['CpuProcessTime'] - 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) start_cpu_stats[process_type]['CpuProcessTime']) 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) total_time = (cpu_stats[process_type]['TotalTime'] - 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) start_cpu_stats[process_type]['TotalTime']) 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) assert total_time > 0, 'Expected total_time > 0, was: %d' % total_time 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cpu_usage[process_type] = float(cpu_process_time) / total_time 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return cpu_usage 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 69