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. 4 5import logging 6 7 8class OmapThrottlingDetector(object): 9 """Class to detect and track thermal throttling on an OMAP 4.""" 10 OMAP_TEMP_FILE = ('/sys/devices/platform/omap/omap_temp_sensor.0/' 11 'temperature') 12 13 @staticmethod 14 def IsSupported(device): 15 return device.FileExists(OmapThrottlingDetector.OMAP_TEMP_FILE) 16 17 def __init__(self, device): 18 self._device = device 19 20 @staticmethod 21 def BecameThrottled(log_line): 22 return 'omap_thermal_throttle' in log_line 23 24 @staticmethod 25 def BecameUnthrottled(log_line): 26 return 'omap_thermal_unthrottle' in log_line 27 28 @staticmethod 29 def GetThrottlingTemperature(log_line): 30 if 'throttle_delayed_work_fn' in log_line: 31 return float([s for s in log_line.split() if s.isdigit()][0]) / 1000.0 32 33 def GetCurrentTemperature(self): 34 tempdata = self._device.ReadFile(OmapThrottlingDetector.OMAP_TEMP_FILE) 35 return float(tempdata) / 1000.0 36 37 38class ExynosThrottlingDetector(object): 39 """Class to detect and track thermal throttling on an Exynos 5.""" 40 @staticmethod 41 def IsSupported(device): 42 return device.FileExists('/sys/bus/exynos5-core') 43 44 def __init__(self, device): 45 pass 46 47 @staticmethod 48 def BecameThrottled(log_line): 49 return 'exynos_tmu: Throttling interrupt' in log_line 50 51 @staticmethod 52 def BecameUnthrottled(log_line): 53 return 'exynos_thermal_unthrottle: not throttling' in log_line 54 55 @staticmethod 56 def GetThrottlingTemperature(_log_line): 57 return None 58 59 @staticmethod 60 def GetCurrentTemperature(): 61 return None 62 63 64class ThermalThrottle(object): 65 """Class to detect and track thermal throttling. 66 67 Usage: 68 Wait for IsThrottled() to be False before running test 69 After running test call HasBeenThrottled() to find out if the 70 test run was affected by thermal throttling. 71 """ 72 73 def __init__(self, device): 74 self._device = device 75 self._throttled = False 76 self._detector = None 77 if OmapThrottlingDetector.IsSupported(device): 78 self._detector = OmapThrottlingDetector(device) 79 elif ExynosThrottlingDetector.IsSupported(device): 80 self._detector = ExynosThrottlingDetector(device) 81 82 def HasBeenThrottled(self): 83 """True if there has been any throttling since the last call to 84 HasBeenThrottled or IsThrottled. 85 """ 86 return self._ReadLog() 87 88 def IsThrottled(self): 89 """True if currently throttled.""" 90 self._ReadLog() 91 return self._throttled 92 93 def _ReadLog(self): 94 if not self._detector: 95 return False 96 has_been_throttled = False 97 serial_number = str(self._device) 98 log = self._device.RunShellCommand( 99 ['dmesg', '-c'], large_output=True, check_return=True) 100 degree_symbol = unichr(0x00B0) 101 for line in log: 102 if self._detector.BecameThrottled(line): 103 if not self._throttled: 104 logging.warning('>>> Device %s thermally throttled', serial_number) 105 self._throttled = True 106 has_been_throttled = True 107 elif self._detector.BecameUnthrottled(line): 108 if self._throttled: 109 logging.warning('>>> Device %s thermally unthrottled', serial_number) 110 self._throttled = False 111 has_been_throttled = True 112 temperature = self._detector.GetThrottlingTemperature(line) 113 if temperature is not None: 114 logging.info(u'Device %s thermally throttled at %3.1f%sC', 115 serial_number, temperature, degree_symbol) 116 117 if logging.getLogger().isEnabledFor(logging.DEBUG): 118 # Print current temperature of CPU SoC. 119 temperature = self._detector.GetCurrentTemperature() 120 if temperature is not None: 121 logging.debug(u'Current SoC temperature of %s = %3.1f%sC', 122 serial_number, temperature, degree_symbol) 123 124 # Print temperature of battery, to give a system temperature 125 dumpsys_log = self._device.RunShellCommand('dumpsys battery') 126 for line in dumpsys_log: 127 if 'temperature' in line: 128 btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0 129 logging.debug(u'Current battery temperature of %s = %3.1f%sC', 130 serial_number, btemp, degree_symbol) 131 132 return has_been_throttled 133