1// Copyright (c) 2014, Intel Corporation 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Intel Corporation nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30#include "PowerGadgetLib.h" 31#include <vector> 32 33using namespace std; 34 35string g_lastError; 36HMODULE g_hModule = NULL; 37 38static bool split(const wstring& s, wstring &path) 39{ 40 bool bResult = false; 41 vector<wstring> output; 42 43 wstring::size_type prev_pos = 0, pos = 0; 44 45 while((pos = s.find(L';', pos)) != wstring::npos) 46 { 47 wstring substring( s.substr(prev_pos, pos-prev_pos) ); 48 if (substring.find(L"Power Gadget 2.") != wstring::npos) 49 { 50 path = substring; 51 bResult = true; 52 break; 53 } 54 prev_pos = ++pos; 55 } 56 57 if (!bResult) 58 { 59 wstring substring(s.substr(prev_pos, pos-prev_pos)); 60 61 if (substring.find(L"Power Gadget 2.") != wstring::npos) 62 { 63 path = substring; 64 bResult = true; 65 } 66 } 67 68 if (bResult) 69 { 70 basic_string <char>::size_type pos = path.rfind(L" "); 71 wstring version = path.substr(pos+1, path.length()); 72 double fVer = _wtof(version.c_str()); 73 if (fVer > 2.6) 74 bResult = true; 75 } 76 77 return bResult; 78} 79 80static bool GetLibraryLocation(wstring& strLocation) 81{ 82 TCHAR *pszPath = _wgetenv(L"IPG_Dir"); 83 if (pszPath == NULL || wcslen(pszPath) == 0) 84 return false; 85 86 TCHAR *pszVersion = _wgetenv(L"IPG_Ver"); 87 if (pszVersion == NULL || wcslen(pszVersion) == 0) 88 return false; 89 90 int version = _wtof(pszVersion) * 100; 91 if (version >= 270) 92 { 93#if _M_X64 94 strLocation = wstring(pszPath) + L"\\EnergyLib64.dll"; 95#else 96 strLocation = wstring(pszPath) + L"\\EnergyLib32.dll"; 97#endif 98 return true; 99 } 100 else 101 return false; 102} 103 104CIntelPowerGadgetLib::CIntelPowerGadgetLib(void) : 105 pInitialize(NULL), 106 pGetNumNodes(NULL), 107 pGetMsrName(NULL), 108 pGetMsrFunc(NULL), 109 pGetIAFrequency(NULL), 110 pGetTDP(NULL), 111 pGetMaxTemperature(NULL), 112 pGetTemperature(NULL), 113 pReadSample(NULL), 114 pGetSysTime(NULL), 115 pGetRDTSC(NULL), 116 pGetTimeInterval(NULL), 117 pGetBaseFrequency(NULL), 118 pGetPowerData(NULL), 119 pStartLog(NULL), 120 pStopLog(NULL), 121 pGetNumMsrs(NULL) 122{ 123 wstring strLocation; 124 if (GetLibraryLocation(strLocation) == false) 125 { 126 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"; 127 return; 128 } 129 130 g_hModule = LoadLibrary(strLocation.c_str()); 131 if (g_hModule == NULL) 132 { 133 g_lastError = "LoadLibrary failed"; 134 return; 135 } 136 137 pInitialize = (IPGInitialize) GetProcAddress(g_hModule, "IntelEnergyLibInitialize"); 138 pGetNumNodes = (IPGGetNumNodes) GetProcAddress(g_hModule, "GetNumNodes"); 139 pGetMsrName = (IPGGetMsrName) GetProcAddress(g_hModule, "GetMsrName"); 140 pGetMsrFunc = (IPGGetMsrFunc) GetProcAddress(g_hModule, "GetMsrFunc"); 141 pGetIAFrequency = (IPGGetIAFrequency) GetProcAddress(g_hModule, "GetIAFrequency"); 142 pGetTDP = (IPGGetTDP) GetProcAddress(g_hModule, "GetTDP"); 143 pGetMaxTemperature = (IPGGetMaxTemperature) GetProcAddress(g_hModule, "GetMaxTemperature"); 144 pGetTemperature = (IPGGetTemperature) GetProcAddress(g_hModule, "GetTemperature"); 145 pReadSample = (IPGReadSample) GetProcAddress(g_hModule, "ReadSample"); 146 pGetSysTime = (IPGGetSysTime) GetProcAddress(g_hModule, "GetSysTime"); 147 pGetRDTSC = (IPGGetRDTSC) GetProcAddress(g_hModule, "GetRDTSC"); 148 pGetTimeInterval = (IPGGetTimeInterval) GetProcAddress(g_hModule, "GetTimeInterval"); 149 pGetBaseFrequency = (IPGGetBaseFrequency) GetProcAddress(g_hModule, "GetBaseFrequency"); 150 pGetPowerData = (IPGGetPowerData) GetProcAddress(g_hModule, "GetPowerData"); 151 pStartLog = (IPGStartLog) GetProcAddress(g_hModule, "StartLog"); 152 pStopLog = (IPGStopLog) GetProcAddress(g_hModule, "StopLog"); 153 pGetNumMsrs = (IPGGetNumMsrs) GetProcAddress(g_hModule, "GetNumMsrs"); 154} 155 156 157CIntelPowerGadgetLib::~CIntelPowerGadgetLib(void) 158{ 159 if (g_hModule != NULL) 160 FreeLibrary(g_hModule); 161} 162 163 164 165string CIntelPowerGadgetLib::GetLastError() 166{ 167 return g_lastError; 168} 169 170bool CIntelPowerGadgetLib::IntelEnergyLibInitialize(void) 171{ 172 if (pInitialize == NULL) 173 return false; 174 175 bool bSuccess = pInitialize(); 176 if (!bSuccess) 177 { 178 g_lastError = "Initializing the energy library failed"; 179 return false; 180 } 181 182 return true; 183} 184 185 186bool CIntelPowerGadgetLib::GetNumNodes(int * nNodes) 187{ 188 return pGetNumNodes(nNodes); 189} 190 191bool CIntelPowerGadgetLib::GetNumMsrs(int * nMsrs) 192{ 193 return pGetNumMsrs(nMsrs); 194} 195 196bool CIntelPowerGadgetLib::GetMsrName(int iMsr, wchar_t *pszName) 197{ 198 return pGetMsrName(iMsr, pszName); 199} 200 201bool CIntelPowerGadgetLib::GetMsrFunc(int iMsr, int *funcID) 202{ 203 return pGetMsrFunc(iMsr, funcID); 204} 205 206bool CIntelPowerGadgetLib::GetIAFrequency(int iNode, int *freqInMHz) 207{ 208 return pGetIAFrequency(iNode, freqInMHz); 209} 210 211bool CIntelPowerGadgetLib::GetTDP(int iNode, double *TDP) 212{ 213 return pGetTDP(iNode, TDP); 214} 215 216bool CIntelPowerGadgetLib::GetMaxTemperature(int iNode, int *degreeC) 217{ 218 return pGetMaxTemperature(iNode, degreeC); 219} 220 221bool CIntelPowerGadgetLib::GetTemperature(int iNode, int *degreeC) 222{ 223 return pGetTemperature(iNode, degreeC); 224} 225 226bool CIntelPowerGadgetLib::ReadSample() 227{ 228 bool bSuccess = pReadSample(); 229 if (bSuccess == false) 230 g_lastError = "MSR overflowed. You can safely discard this sample"; 231 return bSuccess; 232} 233 234bool CIntelPowerGadgetLib::GetSysTime(SYSTEMTIME *sysTime) 235{ 236 return pGetSysTime(sysTime); 237} 238 239bool CIntelPowerGadgetLib::GetRDTSC(UINT64 *TSC) 240{ 241 return pGetRDTSC(TSC); 242} 243 244bool CIntelPowerGadgetLib::GetTimeInterval(double *offset) 245{ 246 return pGetTimeInterval(offset); 247} 248 249bool CIntelPowerGadgetLib::GetBaseFrequency(int iNode, double *baseFrequency) 250{ 251 return pGetBaseFrequency(iNode, baseFrequency); 252} 253 254bool CIntelPowerGadgetLib::GetPowerData(int iNode, int iMSR, double *results, int *nResult) 255{ 256 return pGetPowerData(iNode, iMSR, results, nResult); 257} 258 259bool CIntelPowerGadgetLib::StartLog(wchar_t *szFilename) 260{ 261 return pStartLog(szFilename); 262} 263 264bool CIntelPowerGadgetLib::StopLog() 265{ 266 return pStopLog(); 267} 268