Index: build/android/pylib/perf/perf_control.py |
diff --git a/build/android/pylib/perf/perf_control.py b/build/android/pylib/perf/perf_control.py |
index af1d52c3880e5dacf53e363c7ea12a4cf36f4ad7..d95d7b76bb017e86e3c4c98dfbdfa43a989d418d 100644 |
--- a/build/android/pylib/perf/perf_control.py |
+++ b/build/android/pylib/perf/perf_control.py |
@@ -1,156 +1,8 @@ |
-# Copyright 2013 The Chromium Authors. All rights reserved. |
+# 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. |
-import atexit |
-import logging |
+# pylint: disable=unused-wildcard-import |
+# pylint: disable=wildcard-import |
-from devil.android import device_errors |
- |
- |
-class PerfControl(object): |
- """Provides methods for setting the performance mode of a device.""" |
- _CPU_PATH = '/sys/devices/system/cpu' |
- _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max' |
- |
- def __init__(self, device): |
- self._device = device |
- # this will raise an AdbCommandFailedError if no CPU files are found |
- self._cpu_files = self._device.RunShellCommand( |
- 'ls -d cpu[0-9]*', cwd=self._CPU_PATH, check_return=True, as_root=True) |
- assert self._cpu_files, 'Failed to detect CPUs.' |
- self._cpu_file_list = ' '.join(self._cpu_files) |
- logging.info('CPUs found: %s', self._cpu_file_list) |
- self._have_mpdecision = self._device.FileExists('/system/bin/mpdecision') |
- |
- def SetHighPerfMode(self): |
- """Sets the highest stable performance mode for the device.""" |
- try: |
- self._device.EnableRoot() |
- except device_errors.CommandFailedError: |
- message = 'Need root for performance mode. Results may be NOISY!!' |
- logging.warning(message) |
- # Add an additional warning at exit, such that it's clear that any results |
- # may be different/noisy (due to the lack of intended performance mode). |
- atexit.register(logging.warning, message) |
- return |
- |
- product_model = self._device.product_model |
- # TODO(epenner): Enable on all devices (http://crbug.com/383566) |
- if 'Nexus 4' == product_model: |
- self._ForceAllCpusOnline(True) |
- if not self._AllCpusAreOnline(): |
- logging.warning('Failed to force CPUs online. Results may be NOISY!') |
- self._SetScalingGovernorInternal('performance') |
- elif 'Nexus 5' == product_model: |
- self._ForceAllCpusOnline(True) |
- if not self._AllCpusAreOnline(): |
- logging.warning('Failed to force CPUs online. Results may be NOISY!') |
- self._SetScalingGovernorInternal('performance') |
- self._SetScalingMaxFreq(1190400) |
- self._SetMaxGpuClock(200000000) |
- else: |
- self._SetScalingGovernorInternal('performance') |
- |
- def SetPerfProfilingMode(self): |
- """Enables all cores for reliable perf profiling.""" |
- self._ForceAllCpusOnline(True) |
- self._SetScalingGovernorInternal('performance') |
- if not self._AllCpusAreOnline(): |
- if not self._device.HasRoot(): |
- raise RuntimeError('Need root to force CPUs online.') |
- raise RuntimeError('Failed to force CPUs online.') |
- |
- def SetDefaultPerfMode(self): |
- """Sets the performance mode for the device to its default mode.""" |
- if not self._device.HasRoot(): |
- return |
- product_model = self._device.product_model |
- if 'Nexus 5' == product_model: |
- if self._AllCpusAreOnline(): |
- self._SetScalingMaxFreq(2265600) |
- self._SetMaxGpuClock(450000000) |
- |
- governor_mode = { |
- 'GT-I9300': 'pegasusq', |
- 'Galaxy Nexus': 'interactive', |
- 'Nexus 4': 'ondemand', |
- 'Nexus 5': 'ondemand', |
- 'Nexus 7': 'interactive', |
- 'Nexus 10': 'interactive' |
- }.get(product_model, 'ondemand') |
- self._SetScalingGovernorInternal(governor_mode) |
- self._ForceAllCpusOnline(False) |
- |
- def GetCpuInfo(self): |
- online = (output.rstrip() == '1' and status == 0 |
- for (_, output, status) in self._ForEachCpu('cat "$CPU/online"')) |
- governor = (output.rstrip() if status == 0 else None |
- for (_, output, status) |
- in self._ForEachCpu('cat "$CPU/cpufreq/scaling_governor"')) |
- return zip(self._cpu_files, online, governor) |
- |
- def _ForEachCpu(self, cmd): |
- script = '; '.join([ |
- 'for CPU in %s' % self._cpu_file_list, |
- 'do %s' % cmd, |
- 'echo -n "%~%$?%~%"', |
- 'done' |
- ]) |
- output = self._device.RunShellCommand( |
- script, cwd=self._CPU_PATH, check_return=True, as_root=True) |
- output = '\n'.join(output).split('%~%') |
- return zip(self._cpu_files, output[0::2], (int(c) for c in output[1::2])) |
- |
- def _WriteEachCpuFile(self, path, value): |
- results = self._ForEachCpu( |
- 'test -e "$CPU/{path}" && echo {value} > "$CPU/{path}"'.format( |
- path=path, value=value)) |
- cpus = ' '.join(cpu for (cpu, _, status) in results if status == 0) |
- if cpus: |
- logging.info('Successfully set %s to %r on: %s', path, value, cpus) |
- else: |
- logging.warning('Failed to set %s to %r on any cpus', path, value) |
- |
- def _SetScalingGovernorInternal(self, value): |
- self._WriteEachCpuFile('cpufreq/scaling_governor', value) |
- |
- def _SetScalingMaxFreq(self, value): |
- self._WriteEachCpuFile('cpufreq/scaling_max_freq', '%d' % value) |
- |
- def _SetMaxGpuClock(self, value): |
- self._device.WriteFile('/sys/class/kgsl/kgsl-3d0/max_gpuclk', |
- str(value), |
- as_root=True) |
- |
- def _AllCpusAreOnline(self): |
- results = self._ForEachCpu('cat "$CPU/online"') |
- # TODO(epenner): Investigate why file may be missing |
- # (http://crbug.com/397118) |
- return all(output.rstrip() == '1' and status == 0 |
- for (cpu, output, status) in results |
- if cpu != 'cpu0') |
- |
- def _ForceAllCpusOnline(self, force_online): |
- """Enable all CPUs on a device. |
- |
- Some vendors (or only Qualcomm?) hot-plug their CPUs, which can add noise |
- to measurements: |
- - In perf, samples are only taken for the CPUs that are online when the |
- measurement is started. |
- - The scaling governor can't be set for an offline CPU and frequency scaling |
- on newly enabled CPUs adds noise to both perf and tracing measurements. |
- |
- It appears Qualcomm is the only vendor that hot-plugs CPUs, and on Qualcomm |
- this is done by "mpdecision". |
- |
- """ |
- if self._have_mpdecision: |
- script = 'stop mpdecision' if force_online else 'start mpdecision' |
- self._device.RunShellCommand(script, check_return=True, as_root=True) |
- |
- if not self._have_mpdecision and not self._AllCpusAreOnline(): |
- logging.warning('Unexpected cpu hot plugging detected.') |
- |
- if force_online: |
- self._ForEachCpu('echo 1 > "$CPU/online"') |
+from devil.android.perf.perf_control import * |