Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / platform / power_monitor / sysfs_power_monitor.py
index 62c9f14..421f583 100644 (file)
@@ -3,23 +3,26 @@
 # found in the LICENSE file.
 
 import collections
+import logging
 import os
 import re
 
 from telemetry import decorators
 from telemetry.core.platform import power_monitor
 
+
 CPU_PATH = '/sys/devices/system/cpu/'
 
+
 class SysfsPowerMonitor(power_monitor.PowerMonitor):
   """PowerMonitor that relies on sysfs to monitor CPU statistics on several
   different platforms.
   """
-  def __init__(self, platform):
+  def __init__(self, linux_based_platform_backend):
     """Constructor.
 
     Args:
-        platform: A SysfsPlatform object.
+        linux_based_platform_backend: A LinuxBasedPlatformBackend object.
 
     Attributes:
         _browser: The browser to monitor.
@@ -29,28 +32,31 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
         _final_freq: The CPU frequency times after the test.
         _initial_cstate: The c-state residency times before the test.
         _initial_freq: The CPU frequency times before the test.
-        _platform: A SysfsPlatform object associated with the target platform.
+        _platform: A LinuxBasedPlatformBackend object associated with the
+            target platform.
         _start_time: The time the test started monitoring power.
     """
     super(SysfsPowerMonitor, self).__init__()
     self._browser = None
-    self._cpus = filter(lambda x: re.match(r'^cpu[0-9]+', x),
-                        platform.RunShellCommand('ls %s' % CPU_PATH).split())
+    self._cpus = None
     self._final_cstate = None
     self._final_freq = None
     self._initial_cstate = None
     self._initial_freq = None
-    self._platform = platform
+    self._platform = linux_based_platform_backend
 
   @decorators.Cache
   def CanMonitorPower(self):
-    return bool(self._platform.RunShellCommand(
+    return bool(self._platform.RunCommand(
         'if [ -e %s ]; then echo true; fi' % CPU_PATH))
 
   def StartMonitoringPower(self, browser):
     assert not self._browser, 'Must call StopMonitoringPower().'
     self._browser = browser
     if self.CanMonitorPower():
+      self._cpus = filter(
+          lambda x: re.match(r'^cpu[0-9]+', x),
+          self._platform.RunCommand('ls %s' % CPU_PATH).split())
       self._initial_freq = self.GetCpuFreq()
       self._initial_cstate = self.GetCpuState()
 
@@ -58,15 +64,15 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
     assert self._browser, 'StartMonitoringPower() not called.'
     try:
       out = {}
-      if self.CanMonitorPower():
+      if SysfsPowerMonitor.CanMonitorPower(self):
         self._final_freq = self.GetCpuFreq()
         self._final_cstate = self.GetCpuState()
         frequencies = SysfsPowerMonitor.ComputeCpuStats(
             SysfsPowerMonitor.ParseFreqSample(self._initial_freq),
             SysfsPowerMonitor.ParseFreqSample(self._final_freq))
         cstates = SysfsPowerMonitor.ComputeCpuStats(
-            self._platform.ParseStateSample(self._initial_cstate),
-            self._platform.ParseStateSample(self._final_cstate))
+            self._platform.ParseCStateSample(self._initial_cstate),
+            self._platform.ParseCStateSample(self._final_cstate))
         for cpu in frequencies:
           out[cpu] = {'frequency_percent': frequencies[cpu]}
           out[cpu]['cstate_residency_percent'] = cstates[cpu]
@@ -83,7 +89,7 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
     stats = {}
     for cpu in self._cpus:
       cpu_state_path = os.path.join(CPU_PATH, cpu, 'cpuidle/state*')
-      stats[cpu] = self._platform.RunShellCommand(
+      stats[cpu] = self._platform.RunCommand(
           'cat %s %s %s; date +%%s' % (os.path.join(cpu_state_path, 'name'),
           os.path.join(cpu_state_path, 'time'),
           os.path.join(cpu_state_path, 'latency')))
@@ -99,7 +105,13 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
     for cpu in self._cpus:
       cpu_freq_path = os.path.join(
           CPU_PATH, cpu, 'cpufreq/stats/time_in_state')
-      stats[cpu] = self._platform.RunShellCommand('cat %s' % cpu_freq_path)
+      try:
+        stats[cpu] = self._platform.GetFileContents(cpu_freq_path)
+      except Exception as e:
+        logging.warning(
+            'Cannot read cpu frequency times in %s due to error: %s' %
+            (cpu_freq_path, e.message))
+        stats[cpu] = None
     return stats
 
   @staticmethod
@@ -115,6 +127,9 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
     sample_stats = {}
     for cpu in sample:
       frequencies = {}
+      if sample[cpu] is None:
+        sample_stats[cpu] = None
+        continue
       for line in sample[cpu].splitlines():
         pair = line.split()
         freq = int(pair[0]) * 10 ** 3
@@ -147,6 +162,9 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
     for cpu in initial:
       current_cpu = {}
       total = 0
+      if not initial[cpu] or not final[cpu]:
+        cpu_stats[cpu] = collections.defaultdict(int)
+        continue
       for state in initial[cpu]:
         current_cpu[state] = final[cpu][state] - initial[cpu][state]
         total += current_cpu[state]
@@ -162,3 +180,22 @@ class SysfsPowerMonitor(power_monitor.PowerMonitor):
       average[state] = time / float(count)
     cpu_stats['whole_package'] = average
     return cpu_stats
+
+  @staticmethod
+  def CombineResults(cpu_stats, power_stats):
+    """Add frequency and c-state residency data to the power data.
+
+    Args:
+        cpu_stats: Dictionary containing CPU statistics.
+        power_stats: Dictionary containing power statistics.
+
+    Returns:
+        Dictionary in the format returned by StopMonitoringPower.
+    """
+    if not cpu_stats:
+      return power_stats
+    if 'component_utilization' not in power_stats:
+      power_stats['component_utilization'] = {}
+    for cpu in cpu_stats:
+      power_stats['component_utilization'][cpu] = cpu_stats[cpu]
+    return power_stats