diff options
Diffstat (limited to 'third_party/catapult/devil/devil/android/perf/thermal_throttle.py')
-rw-r--r-- | third_party/catapult/devil/devil/android/perf/thermal_throttle.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/third_party/catapult/devil/devil/android/perf/thermal_throttle.py b/third_party/catapult/devil/devil/android/perf/thermal_throttle.py new file mode 100644 index 0000000000..546a92e092 --- /dev/null +++ b/third_party/catapult/devil/devil/android/perf/thermal_throttle.py @@ -0,0 +1,135 @@ +# 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 + +logger = logging.getLogger(__name__) + + +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): + 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'], large_output=True, check_return=True) + degree_symbol = unichr(0x00B0) + for line in log: + if self._detector.BecameThrottled(line): + if not self._throttled: + logger.warning('>>> Device %s thermally throttled', serial_number) + self._throttled = True + has_been_throttled = True + elif self._detector.BecameUnthrottled(line): + if self._throttled: + logger.warning('>>> Device %s thermally unthrottled', serial_number) + self._throttled = False + has_been_throttled = True + temperature = self._detector.GetThrottlingTemperature(line) + if temperature is not None: + logger.info(u'Device %s thermally throttled at %3.1f%sC', + serial_number, temperature, degree_symbol) + + if logger.isEnabledFor(logging.DEBUG): + # Print current temperature of CPU SoC. + temperature = self._detector.GetCurrentTemperature() + if temperature is not None: + logger.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'], check_return=True) + for line in dumpsys_log: + if 'temperature' in line: + btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0 + logger.debug(u'Current battery temperature of %s = %3.1f%sC', + serial_number, btemp, degree_symbol) + + return has_been_throttled |