You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
597 lines
15 KiB
597 lines
15 KiB
// PassportPerfMon.cpp: implementation of the PassportPerfMon class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#define _PassportExport_
|
|
#include "PassportExport.h"
|
|
|
|
#include "PassportPerfMon.h"
|
|
#include "PassportPerf.h"
|
|
|
|
#include <crtdbg.h>
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// PassportPerfMon const
|
|
//
|
|
//-------------------------------------------------------------
|
|
PassportPerfMon::PassportPerfMon( ) : PassportSharedMemory()
|
|
{
|
|
isInited = FALSE;
|
|
dwNumInstances = 0;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// ~PassportPerfMon
|
|
//
|
|
//-------------------------------------------------------------
|
|
PassportPerfMon::~PassportPerfMon()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// init
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::init( LPCTSTR lpcPerfObjectName )
|
|
{
|
|
|
|
if (isInited)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT( lpcPerfObjectName );
|
|
|
|
InitializeCriticalSection(&mInitLock);
|
|
EnterCriticalSection(&mInitLock);
|
|
|
|
// File mapped memory layout
|
|
// 1. MAX_COUNTERS of DWORD for the counter types
|
|
// 2. if dwNumInstances == 0, then
|
|
// (a) MAX_COUNTERS of DWORDS of the counter data
|
|
// else (dwNumInstances > 0)
|
|
// (b) MAX_COUNTERS of INSTANCE_DATA structures each followed
|
|
// immediately by MAX_COUNTERS of DWORDS of the counter data
|
|
DWORD dwSize = (
|
|
(MAX_COUNTERS * sizeof(DWORD)) // for counter type
|
|
+ (MAX_INSTANCES *
|
|
(sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD))))
|
|
);
|
|
|
|
if (!CreateSharedMemory(0, dwSize, lpcPerfObjectName, TRUE))
|
|
{
|
|
// raise information alert
|
|
if (!OpenSharedMemory (lpcPerfObjectName, TRUE ))
|
|
{
|
|
LeaveCriticalSection(&mInitLock);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// zero new memory
|
|
memset((void *)m_pbShMem, 0, dwSize);
|
|
|
|
// setup counter types to default, note that the counters
|
|
// start at index 1 in SHM
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)m_pbShMem;
|
|
_ASSERT(pCounterBlock);
|
|
|
|
for (DWORD i = 0; i < MAX_COUNTERS; i++)
|
|
{
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + i;
|
|
_ASSERT(pdwCounter);
|
|
*pdwCounter = (LONG)PERF_TYPE_ZERO;
|
|
}
|
|
isInited = TRUE;
|
|
|
|
LeaveCriticalSection(&mInitLock);
|
|
return isInited;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// incrementCounter
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::incrementCounter ( const DWORD &dwType, LPCSTR lpszInstanceName )
|
|
{
|
|
if (!isInited)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
|
|
_ASSERT(m_pbShMem);
|
|
|
|
DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
|
|
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
|
|
// if lpszInstanceName == NULL, select the first datablock after
|
|
// the first INSTANCE_DATA, else iterate until we find the
|
|
// right instance name
|
|
// TBD insert thread locking
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
pb += sizeof(INSTANCE_DATA);
|
|
|
|
//TODO** mikeguo -- tune up this lookup -- too expensive -- check the first character or something
|
|
if (lpszInstanceName == NULL
|
|
|| (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
|
|
{
|
|
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
|
|
_ASSERT(pCounterBlock);
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
|
|
_ASSERT(pdwCounter);
|
|
|
|
InterlockedIncrement((long *)pdwCounter);
|
|
return TRUE;
|
|
}
|
|
pb += (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// decrementCounter
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::decrementCounter ( const DWORD &dwType, LPCSTR lpszInstanceName )
|
|
{
|
|
if (!isInited)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
|
|
_ASSERT(m_pbShMem);
|
|
|
|
DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
|
|
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
|
|
// if lpszInstanceName == NULL, select the first datablock after
|
|
// the first INSTANCE_DATA, else iterate until we find the
|
|
// right instance name
|
|
// TBD insert thread locking
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
pb += sizeof(INSTANCE_DATA);
|
|
if (lpszInstanceName == NULL
|
|
|| (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
|
|
{
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
|
|
_ASSERT(pCounterBlock);
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
|
|
_ASSERT(pdwCounter);
|
|
|
|
InterlockedDecrement((long *)pdwCounter);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
pb += (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// setCounter
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::setCounter ( const DWORD &dwType,
|
|
const DWORD &dwValue,
|
|
LPCSTR lpszInstanceName )
|
|
{
|
|
if (!isInited)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
|
|
_ASSERT(m_pbShMem);
|
|
|
|
DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
|
|
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
|
|
// if lpszInstanceName == NULL, select the first datablock after
|
|
// the first INSTANCE_DATA, else iterate until we find the
|
|
// right instance name
|
|
// TBD insert thread locking
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
pb += sizeof(INSTANCE_DATA);
|
|
if (lpszInstanceName == NULL
|
|
|| (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
|
|
{
|
|
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
|
|
_ASSERT(pCounterBlock);
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
|
|
_ASSERT(pdwCounter);
|
|
|
|
InterlockedExchange((LPLONG) pdwCounter, (LONG)dwValue);
|
|
return TRUE;
|
|
|
|
}
|
|
pb += (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// getCounterValue
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::getCounterValue ( DWORD &dwValue,
|
|
const DWORD &dwType, LPCSTR lpszInstanceName )
|
|
{
|
|
if (!isInited)
|
|
{
|
|
dwValue = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
|
|
_ASSERT(m_pbShMem);
|
|
|
|
DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
|
|
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
|
|
// if lpszInstanceName == NULL, select the first datablock after
|
|
// the first INSTANCE_DATA, else iterate until we find the
|
|
// right instance name
|
|
// TBD insert thread locking
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
pb += sizeof(INSTANCE_DATA);
|
|
if (lpszInstanceName == NULL
|
|
|| (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
|
|
{
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
|
|
_ASSERT(pCounterBlock);
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
|
|
_ASSERT(pdwCounter);
|
|
|
|
//
|
|
// The counter is aligned with DWORD. Simple read does not need
|
|
// the sync operation here.
|
|
//
|
|
|
|
dwValue = (*pdwCounter);
|
|
return TRUE;
|
|
|
|
}
|
|
pb += (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// setCounterType
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::setCounterType ( const DWORD &dwType,
|
|
const PassportPerfInterface::COUNTER_SAMPLING_TYPE &counterSampleType)
|
|
{
|
|
if (!isInited)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
|
|
_ASSERT(m_pbShMem);
|
|
|
|
DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
|
|
DWORD dwPerfType = 0;
|
|
|
|
switch ( counterSampleType )
|
|
{
|
|
case (PassportPerfInterface::COUNTER_COUNTER):
|
|
dwPerfType = PERF_COUNTER_COUNTER;
|
|
break;
|
|
case (PassportPerfInterface::AVERAGE_TIMER):
|
|
dwPerfType = PERF_AVERAGE_TIMER;
|
|
break;
|
|
case (PassportPerfInterface::COUNTER_DELTA):
|
|
dwPerfType = PERF_COUNTER_DELTA;
|
|
break;
|
|
case (PassportPerfInterface::COUNTER_RAWCOUNT):
|
|
case (PassportPerfInterface::COUNTER_UNDEFINED):
|
|
default:
|
|
dwPerfType = PERF_COUNTER_RAWCOUNT;
|
|
break;
|
|
}
|
|
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)m_pbShMem;
|
|
_ASSERT(pCounterBlock);
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + (dwIndex-1);
|
|
_ASSERT(pdwCounter);
|
|
|
|
|
|
InterlockedExchange((LPLONG) pdwCounter, (LONG)dwPerfType);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// getCounterType
|
|
//
|
|
//-------------------------------------------------------------
|
|
PassportPerfInterface::COUNTER_SAMPLING_TYPE PassportPerfMon::getCounterType(
|
|
const DWORD &dwType ) const
|
|
{
|
|
if (!isInited)
|
|
{
|
|
return PassportPerfInterface::COUNTER_UNDEFINED;
|
|
}
|
|
|
|
_ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
|
|
_ASSERT(m_pbShMem);
|
|
|
|
DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
|
|
DWORD dwPerfType = 0;
|
|
|
|
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)m_pbShMem;
|
|
PDWORD pdwCounter = ((PDWORD) pCounterBlock) + (dwIndex-1);
|
|
_ASSERT(pdwCounter);
|
|
|
|
//
|
|
// Simple read does not need the sync op here
|
|
//
|
|
|
|
dwPerfType = (*pdwCounter);
|
|
|
|
switch ( dwPerfType )
|
|
{
|
|
case (PERF_COUNTER_COUNTER):
|
|
return PassportPerfInterface::COUNTER_COUNTER;
|
|
case (PERF_AVERAGE_TIMER):
|
|
return PassportPerfInterface::AVERAGE_TIMER;
|
|
case (PERF_COUNTER_DELTA):
|
|
return PassportPerfInterface::COUNTER_DELTA;
|
|
case (PERF_COUNTER_RAWCOUNT):
|
|
return PassportPerfInterface::COUNTER_RAWCOUNT;
|
|
default:
|
|
return PassportPerfInterface::COUNTER_UNDEFINED;
|
|
}
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// addInstance
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::addInstance( LPCSTR lpszInstanceName )
|
|
{
|
|
if (!isInited || lpszInstanceName == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (strlen(lpszInstanceName) >= sizeof(INSTANCENAME)) {
|
|
|
|
//
|
|
// Why not TCHAR here?
|
|
//
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
_ASSERT(m_pbShMem);
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
|
|
|
|
DWORD dw = WaitForSingleObject(m_hMutex,INFINITE);
|
|
if (dw == WAIT_OBJECT_0)
|
|
{
|
|
// find if the instance already exists, if so fail
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
if (pInst->active)
|
|
{
|
|
if (strcmp(pInst->szInstanceName, lpszInstanceName) == 0)
|
|
{
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
}
|
|
pb += sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
|
|
// insert the instance in the first available slot
|
|
pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
for (i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
if (!pInst->active)
|
|
{
|
|
strcpy(pInst->szInstanceName, lpszInstanceName);
|
|
pInst->active = TRUE;
|
|
InterlockedIncrement(&dwNumInstances);
|
|
pb += sizeof(INSTANCE_DATA);
|
|
memset(pb,0,(MAX_COUNTERS * sizeof(DWORD)));
|
|
ReleaseMutex(m_hMutex);
|
|
return TRUE;
|
|
}
|
|
pb += sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
|
|
// didn't find it, fail
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// deleteInstance
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::deleteInstance( LPCSTR lpszInstanceName )
|
|
{
|
|
if (!isInited || lpszInstanceName == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT(m_pbShMem);
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
|
|
DWORD dw = WaitForSingleObject(m_hMutex,INFINITE);
|
|
if (dw == WAIT_OBJECT_0)
|
|
{
|
|
// find if the instance already exists, if so set it inactive
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
if (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0)
|
|
{
|
|
pInst->active = FALSE;
|
|
InterlockedDecrement(&dwNumInstances);
|
|
// zero the data
|
|
pb += sizeof(INSTANCE_DATA);
|
|
memset(pb,0,(MAX_COUNTERS * sizeof(DWORD)));
|
|
ReleaseMutex(m_hMutex);
|
|
return TRUE;
|
|
}
|
|
pb += sizeof(INSTANCE_DATA)+(MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
|
|
// didn't find it, fail
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// hasInstances
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::hasInstances( void )
|
|
{
|
|
DWORD dwNum = (DWORD)InterlockedExchangeAdd(&dwNumInstances,0);
|
|
if (dwNum > 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// numInstances
|
|
//
|
|
//-------------------------------------------------------------
|
|
DWORD PassportPerfMon::numInstances( void )
|
|
{
|
|
DWORD rv = (DWORD)InterlockedExchangeAdd(&dwNumInstances,0);
|
|
return rv;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
//
|
|
// instanceExists
|
|
//
|
|
//-------------------------------------------------------------
|
|
BOOL PassportPerfMon::instanceExists ( LPCSTR lpszInstanceName )
|
|
{
|
|
|
|
if (!isInited || lpszInstanceName == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_ASSERT(m_pbShMem);
|
|
BYTE* pb = (BYTE*)m_pbShMem;
|
|
_ASSERT(pb);
|
|
|
|
DWORD dw = WaitForSingleObject(m_hMutex,INFINITE);
|
|
if (dw == WAIT_OBJECT_0)
|
|
{
|
|
pb += MAX_COUNTERS * sizeof(DWORD);
|
|
for (DWORD i = 0; i < MAX_INSTANCES; i++)
|
|
{
|
|
INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
|
|
_ASSERT(pInst);
|
|
if (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0)
|
|
{
|
|
ReleaseMutex(m_hMutex);
|
|
return TRUE;
|
|
}
|
|
pb += sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD));
|
|
}
|
|
|
|
// didn't find it, fail
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
ReleaseMutex(m_hMutex);
|
|
return FALSE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|