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