michael@0: /* michael@0: * Copyright 2013, Intel Corporation michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: * michael@0: * Author: Joe Olivas michael@0: */ michael@0: michael@0: #include "nsDebug.h" michael@0: #include "nsString.h" michael@0: #include "IntelPowerGadget.h" michael@0: #include "prenv.h" michael@0: michael@0: IntelPowerGadget::IntelPowerGadget() : michael@0: libpowergadget(nullptr), michael@0: Initialize(nullptr), michael@0: GetNumNodes(nullptr), michael@0: GetMsrName(nullptr), michael@0: GetMsrFunc(nullptr), michael@0: ReadMSR(nullptr), michael@0: WriteMSR(nullptr), michael@0: GetIAFrequency(nullptr), michael@0: GetTDP(nullptr), michael@0: GetMaxTemperature(nullptr), michael@0: GetThresholds(nullptr), michael@0: GetTemperature(nullptr), michael@0: ReadSample(nullptr), michael@0: GetSysTime(nullptr), michael@0: GetRDTSC(nullptr), michael@0: GetTimeInterval(nullptr), michael@0: GetBaseFrequency(nullptr), michael@0: GetPowerData(nullptr), michael@0: StartLog(nullptr), michael@0: StopLog(nullptr), michael@0: GetNumMsrs(nullptr), michael@0: packageMSR(-1), michael@0: cpuMSR(-1), michael@0: freqMSR(-1), michael@0: tempMSR(-1) michael@0: { michael@0: } michael@0: michael@0: bool michael@0: IntelPowerGadget::Init() michael@0: { michael@0: bool success = false; michael@0: const char *path = PR_GetEnv("IPG_Dir"); michael@0: nsCString ipg_library; michael@0: if (path && *path) { michael@0: ipg_library.Append(path); michael@0: ipg_library.AppendLiteral("/"); michael@0: ipg_library.AppendLiteral(PG_LIBRARY_NAME); michael@0: libpowergadget = PR_LoadLibrary(ipg_library.get()); michael@0: } michael@0: michael@0: if(libpowergadget) { michael@0: Initialize = (IPGInitialize) PR_FindFunctionSymbol(libpowergadget, "IntelEnergyLibInitialize"); michael@0: GetNumNodes = (IPGGetNumNodes) PR_FindFunctionSymbol(libpowergadget, "GetNumNodes"); michael@0: GetMsrName = (IPGGetMsrName) PR_FindFunctionSymbol(libpowergadget, "GetMsrName"); michael@0: GetMsrFunc = (IPGGetMsrFunc) PR_FindFunctionSymbol(libpowergadget, "GetMsrFunc"); michael@0: ReadMSR = (IPGReadMSR) PR_FindFunctionSymbol(libpowergadget, "ReadMSR"); michael@0: WriteMSR = (IPGWriteMSR) PR_FindFunctionSymbol(libpowergadget, "WriteMSR"); michael@0: GetIAFrequency = (IPGGetIAFrequency) PR_FindFunctionSymbol(libpowergadget, "GetIAFrequency"); michael@0: GetTDP = (IPGGetTDP) PR_FindFunctionSymbol(libpowergadget, "GetTDP"); michael@0: GetMaxTemperature = (IPGGetMaxTemperature) PR_FindFunctionSymbol(libpowergadget, "GetMaxTemperature"); michael@0: GetThresholds = (IPGGetThresholds) PR_FindFunctionSymbol(libpowergadget, "GetThresholds"); michael@0: GetTemperature = (IPGGetTemperature) PR_FindFunctionSymbol(libpowergadget, "GetTemperature"); michael@0: ReadSample = (IPGReadSample) PR_FindFunctionSymbol(libpowergadget, "ReadSample"); michael@0: GetSysTime = (IPGGetSysTime) PR_FindFunctionSymbol(libpowergadget, "GetSysTime"); michael@0: GetRDTSC = (IPGGetRDTSC) PR_FindFunctionSymbol(libpowergadget, "GetRDTSC"); michael@0: GetTimeInterval = (IPGGetTimeInterval) PR_FindFunctionSymbol(libpowergadget, "GetTimeInterval"); michael@0: GetBaseFrequency = (IPGGetBaseFrequency) PR_FindFunctionSymbol(libpowergadget, "GetBaseFrequency"); michael@0: GetPowerData = (IPGGetPowerData) PR_FindFunctionSymbol(libpowergadget, "GetPowerData"); michael@0: StartLog = (IPGStartLog) PR_FindFunctionSymbol(libpowergadget, "StartLog"); michael@0: StopLog = (IPGStopLog) PR_FindFunctionSymbol(libpowergadget, "StopLog"); michael@0: GetNumMsrs = (IPGGetNumMsrs) PR_FindFunctionSymbol(libpowergadget, "GetNumMsrs"); michael@0: } michael@0: michael@0: if(Initialize) { michael@0: Initialize(); michael@0: int msrCount = GetNumberMsrs(); michael@0: wchar_t name[1024] = {0}; michael@0: for(int i = 0; i < msrCount; ++i) { michael@0: GetMsrName(i, name); michael@0: int func = 0; michael@0: GetMsrFunc(i, &func); michael@0: // MSR for frequency michael@0: if(wcscmp(name, L"CPU Frequency") == 0 && (func == 0)) { michael@0: this->freqMSR = i; michael@0: } michael@0: // MSR for Package michael@0: else if(wcscmp(name, L"Processor") == 0 && (func == 1)) { michael@0: this->packageMSR = i; michael@0: } michael@0: // MSR for CPU michael@0: else if(wcscmp(name, L"IA") == 0 && (func == 1)) { michael@0: this->cpuMSR = i; michael@0: } michael@0: // MSR for Temperature michael@0: else if(wcscmp(name, L"Package") == 0 && (func == 2)) { michael@0: this->tempMSR = i; michael@0: } michael@0: } michael@0: // Grab one sample at startup for a diff michael@0: TakeSample(); michael@0: success = true; michael@0: } michael@0: return success; michael@0: } michael@0: michael@0: IntelPowerGadget::~IntelPowerGadget() michael@0: { michael@0: if(libpowergadget) { michael@0: NS_WARNING("Unloading PowerGadget library!\n"); michael@0: PR_UnloadLibrary(libpowergadget); michael@0: libpowergadget = nullptr; michael@0: Initialize = nullptr; michael@0: GetNumNodes = nullptr; michael@0: GetMsrName = nullptr; michael@0: GetMsrFunc = nullptr; michael@0: ReadMSR = nullptr; michael@0: WriteMSR = nullptr; michael@0: GetIAFrequency = nullptr; michael@0: GetTDP = nullptr; michael@0: GetMaxTemperature = nullptr; michael@0: GetThresholds = nullptr; michael@0: GetTemperature = nullptr; michael@0: ReadSample = nullptr; michael@0: GetSysTime = nullptr; michael@0: GetRDTSC = nullptr; michael@0: GetTimeInterval = nullptr; michael@0: GetBaseFrequency = nullptr; michael@0: GetPowerData = nullptr; michael@0: StartLog = nullptr; michael@0: StopLog = nullptr; michael@0: GetNumMsrs = nullptr; michael@0: } michael@0: } michael@0: michael@0: int michael@0: IntelPowerGadget::GetNumberNodes() michael@0: { michael@0: int nodes = 0; michael@0: if(GetNumNodes) { michael@0: int ok = GetNumNodes(&nodes); michael@0: } michael@0: return nodes; michael@0: } michael@0: michael@0: int michael@0: IntelPowerGadget::GetNumberMsrs() michael@0: { michael@0: int msrs = 0; michael@0: if(GetNumMsrs) { michael@0: int ok = GetNumMsrs(&msrs); michael@0: } michael@0: return msrs; michael@0: } michael@0: michael@0: int michael@0: IntelPowerGadget::GetCPUFrequency(int node) michael@0: { michael@0: int frequency = 0; michael@0: if(GetIAFrequency) { michael@0: int ok = GetIAFrequency(node, &frequency); michael@0: } michael@0: return frequency; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetTdp(int node) michael@0: { michael@0: double tdp = 0.0; michael@0: if(GetTDP) { michael@0: int ok = GetTDP(node, &tdp); michael@0: } michael@0: return tdp; michael@0: } michael@0: michael@0: int michael@0: IntelPowerGadget::GetMaxTemp(int node) michael@0: { michael@0: int maxTemperatureC = 0; michael@0: if(GetMaxTemperature) { michael@0: int ok = GetMaxTemperature(node, &maxTemperatureC); michael@0: } michael@0: return maxTemperatureC; michael@0: } michael@0: michael@0: int michael@0: IntelPowerGadget::GetTemp(int node) michael@0: { michael@0: int temperatureC = 0; michael@0: if(GetTemperature) { michael@0: int ok = GetTemperature(node, &temperatureC); michael@0: } michael@0: return temperatureC; michael@0: } michael@0: michael@0: int michael@0: IntelPowerGadget::TakeSample() michael@0: { michael@0: int ok = 0; michael@0: if(ReadSample) { michael@0: ok = ReadSample(); michael@0: } michael@0: return ok; michael@0: } michael@0: michael@0: uint64_t michael@0: IntelPowerGadget::GetRdtsc() michael@0: { michael@0: uint64_t rdtsc = 0; michael@0: if(GetRDTSC) { michael@0: int ok = GetRDTSC(&rdtsc); michael@0: } michael@0: return rdtsc; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetInterval() michael@0: { michael@0: double interval = 0.0; michael@0: if(GetTimeInterval) { michael@0: int ok = GetTimeInterval(&interval); michael@0: } michael@0: return interval; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetCPUBaseFrequency(int node) michael@0: { michael@0: double freq = 0.0; michael@0: if(GetBaseFrequency) { michael@0: int ok = GetBaseFrequency(node, &freq); michael@0: } michael@0: return freq; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetTotalPackagePowerInWatts() michael@0: { michael@0: int nodes = GetNumberNodes(); michael@0: double totalPower = 0.0; michael@0: for(int i = 0; i < nodes; ++i) { michael@0: totalPower += GetPackagePowerInWatts(i); michael@0: } michael@0: return totalPower; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetPackagePowerInWatts(int node) michael@0: { michael@0: int numResult = 0; michael@0: double result[] = {0.0, 0.0, 0.0}; michael@0: if(GetPowerData && packageMSR != -1) { michael@0: int ok = GetPowerData(node, packageMSR, result, &numResult); michael@0: } michael@0: return result[0]; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetTotalCPUPowerInWatts() michael@0: { michael@0: int nodes = GetNumberNodes(); michael@0: double totalPower = 0.0; michael@0: for(int i = 0; i < nodes; ++i) { michael@0: totalPower += GetCPUPowerInWatts(i); michael@0: } michael@0: return totalPower; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetCPUPowerInWatts(int node) michael@0: { michael@0: int numResult = 0; michael@0: double result[] = {0.0, 0.0, 0.0}; michael@0: if(GetPowerData && cpuMSR != -1) { michael@0: int ok = GetPowerData(node, cpuMSR, result, &numResult); michael@0: } michael@0: return result[0]; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetTotalGPUPowerInWatts() michael@0: { michael@0: int nodes = GetNumberNodes(); michael@0: double totalPower = 0.0; michael@0: for(int i = 0; i < nodes; ++i) { michael@0: totalPower += GetGPUPowerInWatts(i); michael@0: } michael@0: return totalPower; michael@0: } michael@0: michael@0: double michael@0: IntelPowerGadget::GetGPUPowerInWatts(int node) michael@0: { michael@0: return 0.0; michael@0: } michael@0: