Home | History | Annotate | Download | only in perf
      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 
      5 import logging
      6 
      7 
      8 class 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 
     35 class 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 
     57 class 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