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(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 
     38 class 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 
     64 class 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('dmesg -c')
     99     degree_symbol = unichr(0x00B0)
    100     for line in log:
    101       if self._detector.BecameThrottled(line):
    102         if not self._throttled:
    103           logging.warning('>>> Device %s thermally throttled', serial_number)
    104         self._throttled = True
    105         has_been_throttled = True
    106       elif self._detector.BecameUnthrottled(line):
    107         if self._throttled:
    108           logging.warning('>>> Device %s thermally unthrottled', serial_number)
    109         self._throttled = False
    110         has_been_throttled = True
    111       temperature = self._detector.GetThrottlingTemperature(line)
    112       if temperature is not None:
    113         logging.info(u'Device %s thermally throttled at %3.1f%sC',
    114                      serial_number, temperature, degree_symbol)
    115 
    116     if logging.getLogger().isEnabledFor(logging.DEBUG):
    117       # Print current temperature of CPU SoC.
    118       temperature = self._detector.GetCurrentTemperature()
    119       if temperature is not None:
    120         logging.debug(u'Current SoC temperature of %s = %3.1f%sC',
    121                       serial_number, temperature, degree_symbol)
    122 
    123       # Print temperature of battery, to give a system temperature
    124       dumpsys_log = self._device.RunShellCommand('dumpsys battery')
    125       for line in dumpsys_log:
    126         if 'temperature' in line:
    127           btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0
    128           logging.debug(u'Current battery temperature of %s = %3.1f%sC',
    129                         serial_number, btemp, degree_symbol)
    130 
    131     return has_been_throttled
    132