Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / telemetry / internal / platform / power_monitor / msr_power_monitor.py
blob5cf3d16e5d3aa97e7041a97dd093b521876c86a7
1 # Copyright 2014 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.
5 import logging
6 import platform
7 import re
9 from telemetry import decorators
10 from telemetry.internal.platform import power_monitor
13 MSR_RAPL_POWER_UNIT = 0x606
14 MSR_PKG_ENERGY_STATUS = 0x611 # Whole package
15 MSR_PP0_ENERGY_STATUS = 0x639 # Core
16 MSR_PP1_ENERGY_STATUS = 0x641 # Uncore
17 MSR_DRAM_ENERGY_STATUS = 0x619
18 IA32_PACKAGE_THERM_STATUS = 0x1b1
19 IA32_TEMPERATURE_TARGET = 0x1a2
22 def _JoulesToMilliwattHours(value_joules):
23 return value_joules * 1000 / 3600.
26 def _IsSandyBridgeOrLater(vendor, family, model):
27 # Model numbers from:
28 # https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
29 # http://www.speedtraq.com
30 return ('Intel' in vendor and family == 6 and
31 (model in (0x2A, 0x2D) or model >= 0x30))
34 class MsrPowerMonitor(power_monitor.PowerMonitor):
35 def __init__(self, backend):
36 super(MsrPowerMonitor, self).__init__()
37 self._backend = backend
38 self._start_energy_j = None
39 self._start_temp_c = None
41 def CanMonitorPower(self):
42 raise NotImplementedError()
44 def StartMonitoringPower(self, browser):
45 self._CheckStart()
46 self._start_energy_j = self._PackageEnergyJoules()
47 self._start_temp_c = self._TemperatureCelsius()
49 def StopMonitoringPower(self):
50 self._CheckStop()
51 energy_consumption_j = self._PackageEnergyJoules() - self._start_energy_j
52 average_temp_c = (self._TemperatureCelsius() + self._start_temp_c) / 2.
53 if energy_consumption_j < 0: # Correct overflow.
54 # The energy portion of the MSR is 4 bytes.
55 energy_consumption_j += 2 ** 32 * self._EnergyMultiplier()
57 self._start_energy_j = None
58 self._start_temp_c = None
60 return {
61 'identifier': 'msr',
62 'energy_consumption_mwh': _JoulesToMilliwattHours(energy_consumption_j),
63 'platform_info': {
64 'average_temperature_c': average_temp_c,
68 @decorators.Cache
69 def _EnergyMultiplier(self):
70 return 0.5 ** self._backend.ReadMsr(MSR_RAPL_POWER_UNIT, 8, 5)
72 def _PackageEnergyJoules(self):
73 return (self._backend.ReadMsr(MSR_PKG_ENERGY_STATUS, 0, 32) *
74 self._EnergyMultiplier())
76 def _TemperatureCelsius(self):
77 tcc_activation_temp = self._backend.ReadMsr(IA32_TEMPERATURE_TARGET, 16, 7)
78 if tcc_activation_temp <= 0:
79 tcc_activation_temp = 105
80 package_temp_headroom = self._backend.ReadMsr(
81 IA32_PACKAGE_THERM_STATUS, 16, 7)
82 return tcc_activation_temp - package_temp_headroom
84 def _CheckMSRs(self):
85 try:
86 if self._PackageEnergyJoules() <= 0:
87 logging.info('Cannot monitor power: no energy readings.')
88 return False
90 if self._TemperatureCelsius() <= 0:
91 logging.info('Cannot monitor power: no temperature readings.')
92 return False
93 except OSError as e:
94 logging.info('Cannot monitor power: %s' % e)
95 return False
96 return True
99 class MsrPowerMonitorLinux(MsrPowerMonitor):
100 def CanMonitorPower(self):
101 vendor = None
102 family = None
103 model = None
104 cpuinfo = open('/proc/cpuinfo').read().splitlines()
105 for line in cpuinfo:
106 if vendor and family and model:
107 break
108 if line.startswith('vendor_id'):
109 vendor = line.split('\t')[1]
110 elif line.startswith('cpu family'):
111 family = int(line.split(' ')[2])
112 elif line.startswith('model\t\t'):
113 model = int(line.split(' ')[1])
114 if not _IsSandyBridgeOrLater(vendor, family, model):
115 logging.info('Cannot monitor power: pre-Sandy Bridge CPU.')
116 return False
118 if not self._CheckMSRs():
119 logging.info('Try running tools/telemetry/build/linux_setup_msr.py.')
120 return False
122 return True
125 class MsrPowerMonitorWin(MsrPowerMonitor):
126 def CanMonitorPower(self):
127 family, model = map(int, re.match('.+ Family ([0-9]+) Model ([0-9]+)',
128 platform.processor()).groups())
129 if not _IsSandyBridgeOrLater(platform.processor(), family, model):
130 logging.info('Cannot monitor power: pre-Sandy Bridge CPU.')
131 return False
133 try:
134 return self._CheckMSRs()
135 finally:
136 # Since _CheckMSRs() starts the MSR server on win platform, we must close
137 # it after checking to avoid leaking msr server process.
138 self._backend.CloseMsrServer()
140 def StopMonitoringPower(self):
141 power_statistics = super(MsrPowerMonitorWin, self).StopMonitoringPower()
142 self._backend.CloseMsrServer()
143 return power_statistics