summaryrefslogtreecommitdiff
path: root/third_party/catapult/devil/devil/android/perf/thermal_throttle.py
diff options
context:
space:
mode:
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.py135
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