Code:
#include <windows.h>
#include <stdio.h>
#include <pdh.h>
#include <atltime.h>
#pragma comment(lib, "pdh")
PDH_STATUS ps;
CHAR wsPath[256];
CHAR vbPath[256];
DWORD wsItems = 0;
DWORD wsSize = 0;
DWORD vbItems = 0;
DWORD vbSize = 0;
FILE* fLog = fopen("perfcount.log", "w+");
CHAR processModule[MAX_PATH] = {0};
CHAR* GetProcModuleName()
{
if (GetModuleFileName(GetModuleHandle(NULL), processModule, sizeof(processModule)))
{
CHAR* p = strrchr(processModule, '.');
if (p)
*p = '\0';
else
return NULL;
p = strrchr(processModule, '\\');
if (p)
return (p + 1);
}
return NULL;
}
void GetCounters(DWORD sectionIndex)
{
HQUERY hQuery;
HCOUNTER hWsCount;
HCOUNTER hVbCount;
ps = PdhOpenQuery(NULL, 0, &hQuery);
ps = PdhAddCounter(hQuery, wsPath, 0, &hWsCount);
ps = PdhAddCounter(hQuery, vbPath, 0, &hVbCount);
ps = PdhCollectQueryData(hQuery);
wsItems = 0;
wsSize = 0;
vbItems = 0;
vbSize = 0;
PDH_RAW_COUNTER_ITEM* pWS = NULL;
PDH_RAW_COUNTER_ITEM* pVB = NULL;
ps = PdhGetRawCounterArray(hWsCount, &wsSize, &wsItems, NULL);
pWS = (PDH_RAW_COUNTER_ITEM*)LocalAlloc(LPTR, wsSize);
ps = PdhGetRawCounterArray(hVbCount, &vbSize, &vbItems, NULL);
pVB = (PDH_RAW_COUNTER_ITEM*)LocalAlloc(LPTR, vbSize);
ps = PdhGetRawCounterArray(hWsCount, &wsSize, &wsItems, pWS);
ps = PdhGetRawCounterArray(hVbCount, &vbSize, &vbItems, pVB);
ps = PdhCloseQuery(hQuery);
CTime t = pWS->RawValue.TimeStamp;
fprintf(fLog, "[%s] SI: %6d\t WS: %.2f Mb\tVB: %.2f Mb\n",
t.Format("%c"),
sectionIndex,
double(pWS->RawValue.FirstValue) /1024 /1024,
double(pVB->RawValue.FirstValue) /1024 /1024);
LocalFree(pWS);
LocalFree(pVB);
fflush(fLog);
}
int main(int argc, char* argv[])
{
LARGE_INTEGER start,end;
LARGE_INTEGER freq;
QueryPerformanceCounter(&start);
QueryPerformanceFrequency(&freq);
MEMORYSTATUS memstat;
void** map;
int sectionIndex = 0;
memstat.dwLength = sizeof(memstat);
GlobalMemoryStatus(&memstat);
// basic file mapping test (512 MB)
long long size = 512*1024*1024;
DWORD nsize = 0;
CHAR poName[256];
CHAR wsName[256];
CHAR vbName[256];
nsize = sizeof(poName);
ps = PdhLookupPerfNameByIndex(NULL, 230, poName, &nsize); // Process object
nsize = sizeof(wsName);
ps = PdhLookupPerfNameByIndex(NULL, 180, wsName, &nsize); // Working Set counter
nsize = sizeof(vbName);
ps = PdhLookupPerfNameByIndex(NULL, 174, vbName, &nsize); // Virtual Bytes counter
PDH_COUNTER_PATH_ELEMENTS pcpe = {0};
pcpe.szObjectName = poName;
pcpe.szInstanceName = GetProcModuleName();
pcpe.szCounterName = wsName;
nsize = sizeof(wsPath);
ps = PdhMakeCounterPath(&pcpe, wsPath, &nsize, 0);
pcpe.szCounterName = vbName;
nsize = sizeof(vbPath);
ps = PdhMakeCounterPath(&pcpe, vbPath, &nsize, 0);
HANDLE mapping =
CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE|SEC_COMMIT,(DWORD)(size>>32),DWORD(size),NULL);
if (mapping)
{
// create and destroy temporary views
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
const int allocSize = sysInfo.dwAllocationGranularity;
GlobalMemoryStatus(&memstat);
void *mem = new char[allocSize];
memset(mem,0x11,allocSize);
map = (void**) new char [sizeof(void*) * size / allocSize];
for (int i=0; i<1; i++)
{
sectionIndex = 0;
for (long long offset=0; offset<=size-allocSize; offset+=allocSize)
{
map [sectionIndex] =
MapViewOfFile(mapping,FILE_MAP_WRITE,(DWORD)(offset>>32),(DWORD)offset,allocSize);
if (map [sectionIndex])
{
memcpy(map [sectionIndex],mem,allocSize);
GetCounters(sectionIndex);
// UnmapViewOfFile(map);
}
sectionIndex++;
} // for (long long offset=0; offset<=size-allocSize; offset+=allocSize)
// close mapped files to avoid leak
for (sectionIndex = 0; sectionIndex < size/allocSize; sectionIndex++)
{
if (map [sectionIndex])
{
UnmapViewOfFile(map [sectionIndex]);
}
}
GlobalMemoryStatus(&memstat);
sectionIndex = 0;
for (long long offset=0; offset<=size-allocSize; offset+=allocSize)
{
map [sectionIndex] =
MapViewOfFile(mapping,FILE_MAP_READ,(DWORD)(offset>>32),(DWORD)offset,allocSize);
if (map [sectionIndex])
{
for (int t=0; t<allocSize; t++)
{
if (((char *)(map [sectionIndex]))[t]!=0x11)
{
OutputDebugString("Memory read failed\n");
}
}
GetCounters(sectionIndex);
}
UnmapViewOfFile(map [sectionIndex]);
sectionIndex++;
}
// close mapped files to avoid leak
/*
for (sectionIndex = 0; sectionIndex < size/allocSize; sectionIndex++)
{
if (map [sectionIndex])
{
UnmapViewOfFile(map [sectionIndex]);
}
}
*/
GlobalMemoryStatus(&memstat);
} // for (int i=0; i<10; i++)
QueryPerformanceCounter(&end);
GlobalMemoryStatus(&memstat);
printf("Time %.3f\n",
double(end.QuadPart-start.QuadPart)/double(freq.QuadPart));
CloseHandle(mapping);
delete[] mem;
GlobalMemoryStatus(&memstat);
} //if (mapping)
fclose(fLog);
return 0;
}