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 ede131789d70faca081d3810e5ccafb659adfb07..73cf95c53608591365b0335ff1aca2218f03d4d4 100644 |
--- a/build/android/pylib/perf/perf_control.py |
+++ b/build/android/pylib/perf/perf_control.py |
@@ -10,9 +10,7 @@ from pylib.device import device_utils |
class PerfControl(object): |
"""Provides methods for setting the performance mode of a device.""" |
- _SCALING_GOVERNOR_FMT = ( |
- '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor') |
- _CPU_ONLINE_FMT = '/sys/devices/system/cpu/cpu%d/online' |
+ _CPU_PATH = '/sys/devices/system/cpu' |
_KERNEL_MAX = '/sys/devices/system/cpu/kernel_max' |
def __init__(self, device): |
@@ -20,11 +18,12 @@ class PerfControl(object): |
if isinstance(device, android_commands.AndroidCommands): |
device = device_utils.DeviceUtils(device) |
self._device = device |
- cpu_files = self._device.RunShellCommand( |
- 'ls -d /sys/devices/system/cpu/cpu[0-9]*') |
- self._num_cpu_cores = len(cpu_files) |
- assert self._num_cpu_cores > 0, 'Failed to detect CPUs.' |
- logging.info('Number of CPUs: %d', self._num_cpu_cores) |
+ # this will raise an AdbShellCommandFailedError 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): |
@@ -84,22 +83,41 @@ class PerfControl(object): |
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') |
+ |
def _SetScalingGovernorInternal(self, value): |
- cpu_cores = ' '.join([str(x) for x in range(self._num_cpu_cores)]) |
- script = ('for CPU in %s; do\n' |
- ' FILE="/sys/devices/system/cpu/cpu$CPU/cpufreq/scaling_governor"\n' |
- ' test -e $FILE && echo %s > $FILE\n' |
- 'done\n') % (cpu_cores, value) |
- logging.info('Setting scaling governor mode: %s', value) |
- self._device.RunShellCommand(script, as_root=True) |
+ self._WriteEachCpuFile('cpufreq/scaling_governor', value) |
def _SetScalingMaxFreq(self, value): |
- cpu_cores = ' '.join([str(x) for x in range(self._num_cpu_cores)]) |
- script = ('for CPU in %s; do\n' |
- ' FILE="/sys/devices/system/cpu/cpu$CPU/cpufreq/scaling_max_freq"\n' |
- ' test -e $FILE && echo %d > $FILE\n' |
- 'done\n') % (cpu_cores, value) |
- self._device.RunShellCommand(script, as_root=True) |
+ self._WriteEachCpuFile('cpufreq/scaling_max_freq', '%d' % value) |
def _SetMaxGpuClock(self, value): |
self._device.WriteFile('/sys/class/kgsl/kgsl-3d0/max_gpuclk', |
@@ -107,14 +125,12 @@ class PerfControl(object): |
as_root=True) |
def _AllCpusAreOnline(self): |
- for cpu in range(1, self._num_cpu_cores): |
- online_path = PerfControl._CPU_ONLINE_FMT % cpu |
- # TODO(epenner): Investigate why file may be missing |
- # (http://crbug.com/397118) |
- if not self._device.FileExists(online_path) or \ |
- self._device.ReadFile(online_path)[0] == '0': |
- return False |
- return True |
+ 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. |
@@ -132,15 +148,10 @@ class PerfControl(object): |
""" |
if self._have_mpdecision: |
script = 'stop mpdecision' if force_online else 'start mpdecision' |
- self._device.RunShellCommand(script, as_root=True) |
+ 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 not force_online: |
- return |
- |
- for cpu in range(self._num_cpu_cores): |
- online_path = PerfControl._CPU_ONLINE_FMT % cpu |
- self._device.WriteFile(online_path, '1', as_root=True) |
- |
+ if force_online: |
+ self._ForEachCpu('echo 1 > "$CPU/online"') |