Leaked source code of windows server 2003
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

// 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;
}