C++程序  |  270行  |  7.14 KB

// 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 <Windows.h>
#include <string>
#include <vector>

using namespace std;

string g_lastError;
HMODULE g_hModule = NULL;

static bool split(const wstring& s, wstring &path)
{
	bool bResult = false;
	vector<wstring> 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 <char>::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();
}