Adding Peter Thatcher to the owners file.
[chromium-blink-merge.git] / build / android / pylib / perf / thermal_throttle.py
blob383b6d55f8627707d56daa0479f1e4ac1b92c2df
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import logging
6 from pylib import android_commands
7 from pylib.device import device_utils
10 class OmapThrottlingDetector(object):
11 """Class to detect and track thermal throttling on an OMAP 4."""
12 OMAP_TEMP_FILE = ('/sys/devices/platform/omap/omap_temp_sensor.0/'
13 'temperature')
15 @staticmethod
16 def IsSupported(device):
17 return device.FileExists(OmapThrottlingDetector.OMAP_TEMP_FILE)
19 def __init__(self, device):
20 self._device = device
22 @staticmethod
23 def BecameThrottled(log_line):
24 return 'omap_thermal_throttle' in log_line
26 @staticmethod
27 def BecameUnthrottled(log_line):
28 return 'omap_thermal_unthrottle' in log_line
30 @staticmethod
31 def GetThrottlingTemperature(log_line):
32 if 'throttle_delayed_work_fn' in log_line:
33 return float([s for s in log_line.split() if s.isdigit()][0]) / 1000.0
35 def GetCurrentTemperature(self):
36 tempdata = self._device.ReadFile(OmapThrottlingDetector.OMAP_TEMP_FILE)
37 return float(tempdata) / 1000.0
40 class ExynosThrottlingDetector(object):
41 """Class to detect and track thermal throttling on an Exynos 5."""
42 @staticmethod
43 def IsSupported(device):
44 return device.FileExists('/sys/bus/exynos5-core')
46 def __init__(self, device):
47 pass
49 @staticmethod
50 def BecameThrottled(log_line):
51 return 'exynos_tmu: Throttling interrupt' in log_line
53 @staticmethod
54 def BecameUnthrottled(log_line):
55 return 'exynos_thermal_unthrottle: not throttling' in log_line
57 @staticmethod
58 def GetThrottlingTemperature(_log_line):
59 return None
61 @staticmethod
62 def GetCurrentTemperature():
63 return None
66 class ThermalThrottle(object):
67 """Class to detect and track thermal throttling.
69 Usage:
70 Wait for IsThrottled() to be False before running test
71 After running test call HasBeenThrottled() to find out if the
72 test run was affected by thermal throttling.
73 """
75 def __init__(self, device):
76 # TODO(jbudorick) Remove once telemetry gets switched over.
77 if isinstance(device, android_commands.AndroidCommands):
78 device = device_utils.DeviceUtils(device)
79 self._device = device
80 self._throttled = False
81 self._detector = None
82 if OmapThrottlingDetector.IsSupported(device):
83 self._detector = OmapThrottlingDetector(device)
84 elif ExynosThrottlingDetector.IsSupported(device):
85 self._detector = ExynosThrottlingDetector(device)
87 def HasBeenThrottled(self):
88 """True if there has been any throttling since the last call to
89 HasBeenThrottled or IsThrottled.
90 """
91 return self._ReadLog()
93 def IsThrottled(self):
94 """True if currently throttled."""
95 self._ReadLog()
96 return self._throttled
98 def _ReadLog(self):
99 if not self._detector:
100 return False
101 has_been_throttled = False
102 serial_number = str(self._device)
103 log = self._device.RunShellCommand('dmesg -c')
104 degree_symbol = unichr(0x00B0)
105 for line in log:
106 if self._detector.BecameThrottled(line):
107 if not self._throttled:
108 logging.warning('>>> Device %s thermally throttled', serial_number)
109 self._throttled = True
110 has_been_throttled = True
111 elif self._detector.BecameUnthrottled(line):
112 if self._throttled:
113 logging.warning('>>> Device %s thermally unthrottled', serial_number)
114 self._throttled = False
115 has_been_throttled = True
116 temperature = self._detector.GetThrottlingTemperature(line)
117 if temperature is not None:
118 logging.info(u'Device %s thermally throttled at %3.1f%sC',
119 serial_number, temperature, degree_symbol)
121 if logging.getLogger().isEnabledFor(logging.DEBUG):
122 # Print current temperature of CPU SoC.
123 temperature = self._detector.GetCurrentTemperature()
124 if temperature is not None:
125 logging.debug(u'Current SoC temperature of %s = %3.1f%sC',
126 serial_number, temperature, degree_symbol)
128 # Print temperature of battery, to give a system temperature
129 dumpsys_log = self._device.RunShellCommand('dumpsys battery')
130 for line in dumpsys_log:
131 if 'temperature' in line:
132 btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0
133 logging.debug(u'Current battery temperature of %s = %3.1f%sC',
134 serial_number, btemp, degree_symbol)
136 return has_been_throttled