Index: tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py |
diff --git a/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py b/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py |
index 80b9f5f26838a4f67e879d172f7c0f0a2fbb27c1..038346dfebad4fa71614f4f346a388ca514833f9 100644 |
--- a/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py |
+++ b/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py |
@@ -2,19 +2,12 @@ |
# Use of this source code is governed by a BSD-style license that can be |
# found in the LICENSE file. |
-import atexit |
-import ctypes |
import logging |
-import os |
import platform |
import re |
-import sys |
-import zipfile |
from telemetry import decorators |
from telemetry.core.platform import power_monitor |
-from telemetry.util import cloud_storage |
-from telemetry.util import path |
MSR_RAPL_POWER_UNIT = 0x606 |
@@ -26,100 +19,6 @@ IA32_PACKAGE_THERM_STATUS = 0x1b1 |
IA32_TEMPERATURE_TARGET = 0x1a2 |
-WINRING0_STATUS_MESSAGES = ( |
- 'No error', |
- 'Unsupported platform', |
- 'Driver not loaded. You may need to run as Administrator', |
- 'Driver not found', |
- 'Driver unloaded by other process', |
- 'Driver not loaded because of executing on Network Drive', |
- 'Unknown error', |
-) |
- |
- |
-# The DLL initialization is global, so put it in a global variable. |
-_winring0 = None |
- |
- |
-class WinRing0Error(OSError): |
- pass |
- |
- |
-@decorators.Cache |
-def WinRing0Path(): |
- python_is_64_bit = sys.maxsize > 2 ** 32 |
- win_binary_dir = os.path.join(path.GetTelemetryDir(), 'bin', 'win') |
- dll_file_name = 'WinRing0x64.dll' if python_is_64_bit else 'WinRing0.dll' |
- dll_path = os.path.join(win_binary_dir, dll_file_name) |
- |
- os_is_64_bit = 'PROGRAMFILES(X86)' in os.environ |
- executable_dir = os.path.dirname(sys.executable) |
- driver_file_name = 'WinRing0x64.sys' if os_is_64_bit else 'WinRing0.sys' |
- driver_path = os.path.join(executable_dir, driver_file_name) |
- |
- # Check for WinRing0 and download if needed. |
- if not (os.path.exists(dll_path) and os.path.exists(driver_path)): |
- zip_path = os.path.join(win_binary_dir, 'winring0.zip') |
- cloud_storage.GetIfChanged(zip_path, bucket=cloud_storage.PUBLIC_BUCKET) |
- try: |
- with zipfile.ZipFile(zip_path, 'r') as zip_file: |
- # Install DLL. |
- if not os.path.exists(dll_path): |
- zip_file.extract(dll_file_name, win_binary_dir) |
- # Install kernel driver. |
- if not os.path.exists(driver_path): |
- zip_file.extract(driver_file_name, executable_dir) |
- finally: |
- os.remove(zip_path) |
- |
- return dll_path |
- |
- |
-def _Initialize(): |
- global _winring0 |
- if not _winring0: |
- winring0 = ctypes.WinDLL(WinRing0Path()) |
- if not winring0.InitializeOls(): |
- winring0_status = winring0.GetDllStatus() |
- raise WinRing0Error(winring0_status, |
- 'Unable to initialize WinRing0: %s' % |
- WINRING0_STATUS_MESSAGES[winring0_status]) |
- _winring0 = winring0 |
- atexit.register(_Deinitialize) |
- |
- |
-def _Deinitialize(): |
- global _winring0 |
- if _winring0: |
- _winring0.DeinitializeOls() |
- _winring0 = None |
- |
- |
-def _ReadMsr(msr_number): |
- low = ctypes.c_uint() |
- high = ctypes.c_uint() |
- _winring0.Rdmsr(ctypes.c_uint(msr_number), |
- ctypes.byref(low), ctypes.byref(high)) |
- return high.value << 32 | low.value |
- |
- |
-@decorators.Cache |
-def _EnergyMultiplier(): |
- return 0.5 ** ((_ReadMsr(MSR_RAPL_POWER_UNIT) >> 8) & 0x1f) |
- |
- |
-def _PackageEnergyJoules(): |
- return _ReadMsr(MSR_PKG_ENERGY_STATUS) * _EnergyMultiplier() |
- |
- |
-def _TemperatureCelsius(): |
- tcc_activation_temp = _ReadMsr(IA32_TEMPERATURE_TARGET) >> 16 & 0x7f |
- if tcc_activation_temp <= 0: |
- tcc_activation_temp = 105 |
- package_temp_headroom = _ReadMsr(IA32_PACKAGE_THERM_STATUS) >> 16 & 0x7f |
- return tcc_activation_temp - package_temp_headroom |
- |
- |
def _JoulesToMilliwattHours(value_joules): |
return value_joules * 1000 / 3600. |
@@ -149,16 +48,15 @@ class MsrPowerMonitor(power_monitor.PowerMonitor): |
return False |
try: |
- _Initialize() |
- except OSError: |
- return False |
- |
- if _PackageEnergyJoules() <= 0: |
- logging.info('Cannot monitor power: no energy readings.') |
- return False |
- |
- if _TemperatureCelsius() <= 0: |
- logging.info('Cannot monitor power: no temperature readings.') |
+ if self._PackageEnergyJoules() <= 0: |
+ logging.info('Cannot monitor power: no energy readings.') |
+ return False |
+ |
+ if self._TemperatureCelsius() <= 0: |
+ logging.info('Cannot monitor power: no temperature readings.') |
+ return False |
+ except OSError as e: |
+ logging.info('Cannot monitor power: %s' % e) |
return False |
return True |
@@ -166,16 +64,15 @@ class MsrPowerMonitor(power_monitor.PowerMonitor): |
def StartMonitoringPower(self, browser): |
assert self._start_energy_j is None and self._start_temp_c is None, ( |
'Called StartMonitoringPower() twice.') |
- _Initialize() |
- self._start_energy_j = _PackageEnergyJoules() |
- self._start_temp_c = _TemperatureCelsius() |
+ self._start_energy_j = self._PackageEnergyJoules() |
+ self._start_temp_c = self._TemperatureCelsius() |
def StopMonitoringPower(self): |
assert not(self._start_energy_j is None or self._start_temp_c is None), ( |
'Called StopMonitoringPower() before StartMonitoringPower().') |
- energy_consumption_j = _PackageEnergyJoules() - self._start_energy_j |
- average_temp_c = (_TemperatureCelsius() + self._start_temp_c) / 2. |
+ energy_consumption_j = self._PackageEnergyJoules() - self._start_energy_j |
+ average_temp_c = (self._TemperatureCelsius() + self._start_temp_c) / 2. |
assert energy_consumption_j >= 0, ('Negative energy consumption. (Starting ' |
'energy was %s.)' % self._start_energy_j) |
@@ -191,3 +88,20 @@ class MsrPowerMonitor(power_monitor.PowerMonitor): |
}, |
}, |
} |
+ |
+ @decorators.Cache |
+ def _EnergyMultiplier(self): |
+ return 0.5 ** ((self._backend.ReadMsr(MSR_RAPL_POWER_UNIT) >> 8) & 0x1f) |
+ |
+ def _PackageEnergyJoules(self): |
+ return (self._backend.ReadMsr(MSR_PKG_ENERGY_STATUS) * |
+ self._EnergyMultiplier()) |
+ |
+ def _TemperatureCelsius(self): |
+ tcc_activation_temp = ( |
+ self._backend.ReadMsr(IA32_TEMPERATURE_TARGET) >> 16 & 0x7f) |
+ if tcc_activation_temp <= 0: |
+ tcc_activation_temp = 105 |
+ package_temp_headroom = ( |
+ self._backend.ReadMsr(IA32_PACKAGE_THERM_STATUS) >> 16 & 0x7f) |
+ return tcc_activation_temp - package_temp_headroom |