// Copyright (c) 2014, Intel Corporation // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Intel Corporation nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "PowerGadgetLib.h" #include using namespace std; string g_lastError; HMODULE g_hModule = NULL; static bool split(const wstring& s, wstring &path) { bool bResult = false; vector output; wstring::size_type prev_pos = 0, pos = 0; while((pos = s.find(L';', pos)) != wstring::npos) { wstring substring( s.substr(prev_pos, pos-prev_pos) ); if (substring.find(L"Power Gadget 2.") != wstring::npos) { path = substring; bResult = true; break; } prev_pos = ++pos; } if (!bResult) { wstring substring(s.substr(prev_pos, pos-prev_pos)); if (substring.find(L"Power Gadget 2.") != wstring::npos) { path = substring; bResult = true; } } if (bResult) { basic_string ::size_type pos = path.rfind(L" "); wstring version = path.substr(pos+1, path.length()); double fVer = _wtof(version.c_str()); if (fVer > 2.6) bResult = true; } return bResult; } static bool GetLibraryLocation(wstring& strLocation) { TCHAR *pszPath = _wgetenv(L"IPG_Dir"); if (pszPath == NULL || wcslen(pszPath) == 0) return false; TCHAR *pszVersion = _wgetenv(L"IPG_Ver"); if (pszVersion == NULL || wcslen(pszVersion) == 0) return false; int version = _wtof(pszVersion) * 100; if (version >= 270) { #if _M_X64 strLocation = wstring(pszPath) + L"\\EnergyLib64.dll"; #else strLocation = wstring(pszPath) + L"\\EnergyLib32.dll"; #endif return true; } else return false; } CIntelPowerGadgetLib::CIntelPowerGadgetLib(void) : pInitialize(NULL), pGetNumNodes(NULL), pGetMsrName(NULL), pGetMsrFunc(NULL), pGetIAFrequency(NULL), pGetTDP(NULL), pGetMaxTemperature(NULL), pGetTemperature(NULL), pReadSample(NULL), pGetSysTime(NULL), pGetRDTSC(NULL), pGetTimeInterval(NULL), pGetBaseFrequency(NULL), pGetPowerData(NULL), pStartLog(NULL), pStopLog(NULL), pGetNumMsrs(NULL) { wstring strLocation; if (GetLibraryLocation(strLocation) == false) { g_lastError = "Intel Power Gadget 2.7 or higher not found. If unsure, check if the path is in the user's path environment variable"; return; } g_hModule = LoadLibrary(strLocation.c_str()); if (g_hModule == NULL) { g_lastError = "LoadLibrary failed"; return; } pInitialize = (IPGInitialize) GetProcAddress(g_hModule, "IntelEnergyLibInitialize"); pGetNumNodes = (IPGGetNumNodes) GetProcAddress(g_hModule, "GetNumNodes"); pGetMsrName = (IPGGetMsrName) GetProcAddress(g_hModule, "GetMsrName"); pGetMsrFunc = (IPGGetMsrFunc) GetProcAddress(g_hModule, "GetMsrFunc"); pGetIAFrequency = (IPGGetIAFrequency) GetProcAddress(g_hModule, "GetIAFrequency"); pGetTDP = (IPGGetTDP) GetProcAddress(g_hModule, "GetTDP"); pGetMaxTemperature = (IPGGetMaxTemperature) GetProcAddress(g_hModule, "GetMaxTemperature"); pGetTemperature = (IPGGetTemperature) GetProcAddress(g_hModule, "GetTemperature"); pReadSample = (IPGReadSample) GetProcAddress(g_hModule, "ReadSample"); pGetSysTime = (IPGGetSysTime) GetProcAddress(g_hModule, "GetSysTime"); pGetRDTSC = (IPGGetRDTSC) GetProcAddress(g_hModule, "GetRDTSC"); pGetTimeInterval = (IPGGetTimeInterval) GetProcAddress(g_hModule, "GetTimeInterval"); pGetBaseFrequency = (IPGGetBaseFrequency) GetProcAddress(g_hModule, "GetBaseFrequency"); pGetPowerData = (IPGGetPowerData) GetProcAddress(g_hModule, "GetPowerData"); pStartLog = (IPGStartLog) GetProcAddress(g_hModule, "StartLog"); pStopLog = (IPGStopLog) GetProcAddress(g_hModule, "StopLog"); pGetNumMsrs = (IPGGetNumMsrs) GetProcAddress(g_hModule, "GetNumMsrs"); } CIntelPowerGadgetLib::~CIntelPowerGadgetLib(void) { if (g_hModule != NULL) FreeLibrary(g_hModule); } string CIntelPowerGadgetLib::GetLastError() { return g_lastError; } bool CIntelPowerGadgetLib::IntelEnergyLibInitialize(void) { if (pInitialize == NULL) return false; bool bSuccess = pInitialize(); if (!bSuccess) { g_lastError = "Initializing the energy library failed"; return false; } return true; } bool CIntelPowerGadgetLib::GetNumNodes(int * nNodes) { return pGetNumNodes(nNodes); } bool CIntelPowerGadgetLib::GetNumMsrs(int * nMsrs) { return pGetNumMsrs(nMsrs); } bool CIntelPowerGadgetLib::GetMsrName(int iMsr, wchar_t *pszName) { return pGetMsrName(iMsr, pszName); } bool CIntelPowerGadgetLib::GetMsrFunc(int iMsr, int *funcID) { return pGetMsrFunc(iMsr, funcID); } bool CIntelPowerGadgetLib::GetIAFrequency(int iNode, int *freqInMHz) { return pGetIAFrequency(iNode, freqInMHz); } bool CIntelPowerGadgetLib::GetTDP(int iNode, double *TDP) { return pGetTDP(iNode, TDP); } bool CIntelPowerGadgetLib::GetMaxTemperature(int iNode, int *degreeC) { return pGetMaxTemperature(iNode, degreeC); } bool CIntelPowerGadgetLib::GetTemperature(int iNode, int *degreeC) { return pGetTemperature(iNode, degreeC); } bool CIntelPowerGadgetLib::ReadSample() { bool bSuccess = pReadSample(); if (bSuccess == false) g_lastError = "MSR overflowed. You can safely discard this sample"; return bSuccess; } bool CIntelPowerGadgetLib::GetSysTime(SYSTEMTIME *sysTime) { return pGetSysTime(sysTime); } bool CIntelPowerGadgetLib::GetRDTSC(UINT64 *TSC) { return pGetRDTSC(TSC); } bool CIntelPowerGadgetLib::GetTimeInterval(double *offset) { return pGetTimeInterval(offset); } bool CIntelPowerGadgetLib::GetBaseFrequency(int iNode, double *baseFrequency) { return pGetBaseFrequency(iNode, baseFrequency); } bool CIntelPowerGadgetLib::GetPowerData(int iNode, int iMSR, double *results, int *nResult) { return pGetPowerData(iNode, iMSR, results, nResult); } bool CIntelPowerGadgetLib::StartLog(wchar_t *szFilename) { return pStartLog(szFilename); } bool CIntelPowerGadgetLib::StopLog() { return pStopLog(); }