| Index: build/android/pylib/perf/thermal_throttle.py
|
| diff --git a/build/android/pylib/perf/thermal_throttle.py b/build/android/pylib/perf/thermal_throttle.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..383b6d55f8627707d56daa0479f1e4ac1b92c2df
|
| --- /dev/null
|
| +++ b/build/android/pylib/perf/thermal_throttle.py
|
| @@ -0,0 +1,137 @@
|
| +# 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.
|
| +
|
| +import logging
|
| +from pylib import android_commands
|
| +from pylib.device import device_utils
|
| +
|
| +
|
| +class OmapThrottlingDetector(object):
|
| + """Class to detect and track thermal throttling on an OMAP 4."""
|
| + OMAP_TEMP_FILE = ('/sys/devices/platform/omap/omap_temp_sensor.0/'
|
| + 'temperature')
|
| +
|
| + @staticmethod
|
| + def IsSupported(device):
|
| + return device.FileExists(OmapThrottlingDetector.OMAP_TEMP_FILE)
|
| +
|
| + def __init__(self, device):
|
| + self._device = device
|
| +
|
| + @staticmethod
|
| + def BecameThrottled(log_line):
|
| + return 'omap_thermal_throttle' in log_line
|
| +
|
| + @staticmethod
|
| + def BecameUnthrottled(log_line):
|
| + return 'omap_thermal_unthrottle' in log_line
|
| +
|
| + @staticmethod
|
| + def GetThrottlingTemperature(log_line):
|
| + if 'throttle_delayed_work_fn' in log_line:
|
| + return float([s for s in log_line.split() if s.isdigit()][0]) / 1000.0
|
| +
|
| + def GetCurrentTemperature(self):
|
| + tempdata = self._device.ReadFile(OmapThrottlingDetector.OMAP_TEMP_FILE)
|
| + return float(tempdata) / 1000.0
|
| +
|
| +
|
| +class ExynosThrottlingDetector(object):
|
| + """Class to detect and track thermal throttling on an Exynos 5."""
|
| + @staticmethod
|
| + def IsSupported(device):
|
| + return device.FileExists('/sys/bus/exynos5-core')
|
| +
|
| + def __init__(self, device):
|
| + pass
|
| +
|
| + @staticmethod
|
| + def BecameThrottled(log_line):
|
| + return 'exynos_tmu: Throttling interrupt' in log_line
|
| +
|
| + @staticmethod
|
| + def BecameUnthrottled(log_line):
|
| + return 'exynos_thermal_unthrottle: not throttling' in log_line
|
| +
|
| + @staticmethod
|
| + def GetThrottlingTemperature(_log_line):
|
| + return None
|
| +
|
| + @staticmethod
|
| + def GetCurrentTemperature():
|
| + return None
|
| +
|
| +
|
| +class ThermalThrottle(object):
|
| + """Class to detect and track thermal throttling.
|
| +
|
| + Usage:
|
| + Wait for IsThrottled() to be False before running test
|
| + After running test call HasBeenThrottled() to find out if the
|
| + test run was affected by thermal throttling.
|
| + """
|
| +
|
| + def __init__(self, device):
|
| + # TODO(jbudorick) Remove once telemetry gets switched over.
|
| + if isinstance(device, android_commands.AndroidCommands):
|
| + device = device_utils.DeviceUtils(device)
|
| + self._device = device
|
| + self._throttled = False
|
| + self._detector = None
|
| + if OmapThrottlingDetector.IsSupported(device):
|
| + self._detector = OmapThrottlingDetector(device)
|
| + elif ExynosThrottlingDetector.IsSupported(device):
|
| + self._detector = ExynosThrottlingDetector(device)
|
| +
|
| + def HasBeenThrottled(self):
|
| + """True if there has been any throttling since the last call to
|
| + HasBeenThrottled or IsThrottled.
|
| + """
|
| + return self._ReadLog()
|
| +
|
| + def IsThrottled(self):
|
| + """True if currently throttled."""
|
| + self._ReadLog()
|
| + return self._throttled
|
| +
|
| + def _ReadLog(self):
|
| + if not self._detector:
|
| + return False
|
| + has_been_throttled = False
|
| + serial_number = str(self._device)
|
| + log = self._device.RunShellCommand('dmesg -c')
|
| + degree_symbol = unichr(0x00B0)
|
| + for line in log:
|
| + if self._detector.BecameThrottled(line):
|
| + if not self._throttled:
|
| + logging.warning('>>> Device %s thermally throttled', serial_number)
|
| + self._throttled = True
|
| + has_been_throttled = True
|
| + elif self._detector.BecameUnthrottled(line):
|
| + if self._throttled:
|
| + logging.warning('>>> Device %s thermally unthrottled', serial_number)
|
| + self._throttled = False
|
| + has_been_throttled = True
|
| + temperature = self._detector.GetThrottlingTemperature(line)
|
| + if temperature is not None:
|
| + logging.info(u'Device %s thermally throttled at %3.1f%sC',
|
| + serial_number, temperature, degree_symbol)
|
| +
|
| + if logging.getLogger().isEnabledFor(logging.DEBUG):
|
| + # Print current temperature of CPU SoC.
|
| + temperature = self._detector.GetCurrentTemperature()
|
| + if temperature is not None:
|
| + logging.debug(u'Current SoC temperature of %s = %3.1f%sC',
|
| + serial_number, temperature, degree_symbol)
|
| +
|
| + # Print temperature of battery, to give a system temperature
|
| + dumpsys_log = self._device.RunShellCommand('dumpsys battery')
|
| + for line in dumpsys_log:
|
| + if 'temperature' in line:
|
| + btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0
|
| + logging.debug(u'Current battery temperature of %s = %3.1f%sC',
|
| + serial_number, btemp, degree_symbol)
|
| +
|
| + return has_been_throttled
|
| +
|
|
|