Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

596 lines
16 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1993 - 2000.
//
// File: perfobj.cxx
//
// Contents: Performance Data Object
//
// Classes : CPerfMon, PPerfCounter,
// CPerfCount, CPerfTime,
// CReadUserPerfData
//
// History: 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <mutex.hxx>
#include <perfci.hxx>
#include "perfobj2.hxx"
extern CI_DATA_DEFINITION CIDataDefinition;
extern FILTER_DATA_DEFINITION FILTERDataDefinition;
#define FILTERTOTALCOUNTER ((int) FILTERDataDefinition.FILTERObjectType.NumCounters)
#define CITOTALCOUNTER ((int) CIDataDefinition.CIObjectType.NumCounters)
//
// Total size occupied by the counters
//
#define TOTALCOUNTERSIZE ( (FILTERTOTALCOUNTER + CITOTALCOUNTER ) * sizeof(DWORD) )
//+---------------------------------------------------------------------------
//
// Function : CReadUserPerfData::CReadUserPerfData
//
// Purpose : Constructor
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
CReadUserPerfData::CReadUserPerfData() :
_cInstances( 0 ),
_finitOK( FALSE ),
_cCounters( 0 ),
_pSeqNo( 0 ),
_cMaxCats( 0 ),
_cbPerfHeader( 0 )
{
}
//+---------------------------------------------------------------------------
//
// Function : CReadUserPerfData::Finish
//
// Purpose : Close and clean up the handles
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
// Note: Must execute when done with getting the data
//
//----------------------------------------------------------------------------
void CReadUserPerfData::Finish()
{
CleanupForReInit();
_xSharedMemObj.Free();
}
//+---------------------------------------------------------------------------
//
// Member: CReadUserPerfData::CleanupForReInit
//
// Synopsis: Cleans up the data structures in preparation for a
// re-initialization. Only the data which needs to be re-read
// and initialized is thrown away. The Shared memory object is
// NOT deleted because it is system-wide state and there is no
// need to throw it away.
//
// History: 6-21-96 srikants Created
//
//----------------------------------------------------------------------------
void CReadUserPerfData::CleanupForReInit()
{
}
//+---------------------------------------------------------------------------
//
// Function : CReadUserPerfData::InitforRead
//
// Purpose : Initialize to be ready for reading the perf. data
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
// Note: Must be executed before any operations
//
// Return : TRUE -- success, FALSE -- failed
//
//----------------------------------------------------------------------------
BOOL CReadUserPerfData::InitForRead()
{
if ( _xSharedMemObj.IsNull() )
{
ULONG cbCatBitfield, cbSharedMem;
ComputeCIPerfmonVars( _cMaxCats, cbCatBitfield, _cbPerfHeader, cbSharedMem );
//
// Open the shared memory
//
_xSharedMemObj.Set( new CNamedSharedMem() );
BOOL fOK = _xSharedMemObj->OpenForRead( CI_PERF_MEM_NAME );
if ( !fOK )
return FALSE;
_pSeqNo = (UINT *) (((BYTE *)_xSharedMemObj->Get())+sizeof(int) + cbCatBitfield);
}
if ( _finitOK )
CleanupForReInit();
_finitOK = FALSE;
if ( _xSharedMemObj->Ok() )
{
_cInstances = *((int *)_xSharedMemObj->Get());
PerfDebugOut(( DEB_ITRACE, "!!! Reader : No. of Instance : %d\n", _cInstances ));
_cCounters = FILTERTOTALCOUNTER;
_finitOK = TRUE;
return TRUE;
}
return FALSE;
} //InitForRead
//+---------------------------------------------------------------------------
//
// Function : CReadUserPerfData::NumberOfInstance
//
// Purpose : Return the number of existing instances
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
int CReadUserPerfData::NumberOfInstance()
{
return _cInstances;
}
UINT CReadUserPerfData::GetSeqNo() const
{
return _pSeqNo ? *_pSeqNo : 0;
}
//+---------------------------------------------------------------------------
//
// Function : CReadUserPerfData::GetInstanceName
//
// Purpose : Return the specified instance's name
//
// Arguments : [iWhichOne] -- which instance
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
WCHAR * CReadUserPerfData::GetInstanceName ( int iWhichOne )
{
if ( !_xSharedMemObj.IsNull() && _xSharedMemObj->Ok() )
{
//
// Find the corresponding slot in the shared memory
//
BYTE * pbBitfield = (BYTE *) _xSharedMemObj->Get() + sizeof(int);
CBitfield bits( pbBitfield );
int i = 0;
for ( int j = 0; j <= iWhichOne && i < (int) _cMaxCats; i++ )
{
if ( bits.IsBitSet( i ) )
j++;
}
iWhichOne = i - 1;
ULONG ByteToSkip = _cbPerfHeader +
( iWhichOne * cbPerfCatalogSlot ) +
sizeof(int);
return( (WCHAR *)((BYTE *)_xSharedMemObj->Get() + ByteToSkip) );
}
return 0;
} //GetInstanceName
//+---------------------------------------------------------------------------
//
// Function : CReadUserPerfData::GetCounterValue
//
// Purpose : Return the value of the specified counter
//
// Arguments : [iWhichInstance] -- which instance of object does the
// counter belong to
// [iWhichCounter] -- which counter
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
DWORD CReadUserPerfData::GetCounterValue( int iWhichInstance, int iWhichCounter )
{
if ( !_xSharedMemObj.IsNull() && _xSharedMemObj->Ok() )
{
//
// Find the corresponding slot
//
BYTE * pbBitfield = (BYTE *) _xSharedMemObj->Get() + sizeof(int);
CBitfield bits( pbBitfield );
int i = 0;
for ( int j = 0; j <= iWhichInstance && i < (int) _cMaxCats; i++ )
{
if ( bits.IsBitSet( i ) )
j++;
}
int iWhichSlot = i - 1;
PerfDebugOut(( DEB_ITRACE, "Choose slot %i\n", iWhichSlot));
ULONG ByteToSkip = _cbPerfHeader
+ ( iWhichSlot * cbPerfCatalogSlot )
+ sizeof(int)
+ ( CI_PERF_MAX_CATALOG_LEN * sizeof(WCHAR) ) // Name of the instance
+ ( iWhichCounter * sizeof(DWORD) );
return *(DWORD *)((BYTE *)_xSharedMemObj->Get() + ByteToSkip);
}
return 0;
} //GetCounterValue
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::CReadKernelPerfData
//
// Purpose : Constructor
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
CReadKernelPerfData::CReadKernelPerfData() :
_pSeqNo(0),
_cInstance( 0 ),
_finitOK( FALSE ),
_cCounters( 0 ),
_cMaxCats( 0 ),
_cbPerfHeader( 0 ),
_cbSharedMem( 0 )
{
}
UINT CReadKernelPerfData::GetSeqNo() const
{
return _pSeqNo ? *_pSeqNo : 0;
}
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::Finish
//
// Purpose : Close and clean up the handles
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
// Note: Must execute when done with getting the data
//
//----------------------------------------------------------------------------
void CReadKernelPerfData::Finish()
{
CleanupForReInit();
_xSharedMemory.Free();
_xMemory.Free();
_xCatalogs.Free();
_xCatalogMem.Free();
}
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::FindDownlevelDrives
//
// Purpose : Find the remote drive
//
// History : 23-Mar-94 t-joshh Created
// 31-Jan-96 KyleP Look for all downlevel drives
//
//----------------------------------------------------------------------------
void CReadKernelPerfData::FindDownlevelDrives()
{
if ( _xSharedMemory->Ok() )
{
//
// Get active drive count and active bit array.
//
int cCount = * (int *) _xSharedMemory->Get();
BYTE * pbBitfield = (BYTE *) _xSharedMemory->Get() + sizeof(int);
CBitfield bits( pbBitfield );
//
// Loop through looking for drives.
//
for (int i = 0; cCount > 0 ; cCount--, i++)
{
for (; i < (int) _cMaxCats && !bits.IsBitSet( i ); i++) {}
if ( (int) _cMaxCats == i )
{
PerfDebugOut(( DEB_ITRACE, "!!! Error in the empty slot\n"));
return;
}
else
{
//
// Find offset of drive name in shared memory buffer.
//
ULONG oCounters = _cbPerfHeader +
(i * cbPerfCatalogSlot) +
sizeof(int);
WCHAR * wszTmp = (WCHAR *) ((BYTE *) _xSharedMemory->Get() + oCounters);
//
// Make sure this isn't already in the list
//
for ( int j = 0; j < cCount; j++ )
{
if ( 0 != _xCatalogs[j] && wcscmp( _xCatalogs[j], wszTmp ) == 0 )
break;
}
//
// Add downlevel drive.
//
if ( j == cCount )
{
PerfDebugOut(( DEB_ITRACE, "!!! Kernel Reader : Downlevel Drive %ws\n", wszTmp ));
//
// Find offset of first counter.
//
oCounters += ((sizeof(DWORD) * NUM_KERNEL_AND_USER_COUNTER)
+ (CI_PERF_MAX_CATALOG_LEN * sizeof(WCHAR)));
_xCatalogMem[_cInstance] = (void *) ((BYTE *) _xSharedMemory->Get() + oCounters);
_xCatalogs[_cInstance] = new WCHAR[wcslen(wszTmp) + 1];
wcscpy(_xCatalogs[_cInstance++], wszTmp);
}
}
}
}
} //FindDownlevelDrives
//+---------------------------------------------------------------------------
//
// Member: CReadKernelPerfData::CleanupForReInit
//
// Synopsis: Cleans up the state and makes it ready for re-initialization.
//
// History: 6-21-96 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
void CReadKernelPerfData::CleanupForReInit()
{
for ( int i = 0; i < _cInstance; i++)
{
delete _xCatalogs[i];
_xCatalogs[i] = 0;
}
_cInstance = 0;
}
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::InitForRead
//
// Purpose : Initialize to be ready for reading the perf. data
//
// Arguments : none
//
// History : 23-Mar-94 t-joshh Created
// 31-Jan-96 KyleP Improvements for downlevel CI
//
// Note: Must be executed before any operations
//
//----------------------------------------------------------------------------
BOOL CReadKernelPerfData::InitForRead()
{
if ( _xSharedMemory.IsNull() )
{
ULONG cbCatBitfield;
ComputeCIPerfmonVars( _cMaxCats, cbCatBitfield, _cbPerfHeader, _cbSharedMem );
//
// Open the shared memory
//
_xSharedMemory.Set( new CNamedSharedMem() );
BOOL fOK = _xSharedMemory->OpenForRead( CI_PERF_MEM_NAME );
if ( !fOK )
return FALSE;
_pSeqNo = (UINT *) (((BYTE *)_xSharedMemory->Get())+sizeof(int) + cbCatBitfield);
}
//
// Initialize the drive list
//
if ( _finitOK )
CleanupForReInit();
_finitOK = FALSE;
if ( _xCatalogs.IsNull() )
_xCatalogs.Init( _cMaxCats );
if ( _xCatalogMem.IsNull() )
_xCatalogMem.Init( _cMaxCats );
for ( unsigned j = 0; j < _cMaxCats; j++)
{
_xCatalogs[j] = 0;
_xCatalogMem[j] = 0;
}
FindDownlevelDrives();
_cCounters = CITOTALCOUNTER;
_finitOK = TRUE;
return TRUE;
PerfDebugOut(( DEB_ITRACE, "!!! Kernel Reader : Initialize finish\n"));
} //InitForRead
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::NumberOfInstance
//
// Purpose : Return the number of existing instances
//
// Arguments : none
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
int CReadKernelPerfData::NumberOfInstance()
{
return _cInstance;
}
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::GetInstanceName
//
// Purpose : Return the specified instance's name
//
// Arguments : [iWhichOne] -- which instance
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
WCHAR * CReadKernelPerfData::GetInstanceName ( int iWhichOne )
{
return _xCatalogs[iWhichOne];
}
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::Refresh
//
// Purpose : Retrieve the most updated data
//
// Arguments : [iWhichInstance] -- which instance of object does the
// counter belong to
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
BOOL CReadKernelPerfData::Refresh( int iWhichInstance )
{
//
// the instance is either downlevel drive or remote drive
//
Win4Assert( 0 != _cbSharedMem );
if ( _xMemory.IsNull() )
_xMemory.Init( _cbSharedMem );
ULONG oCounters = _cbPerfHeader +
sizeof(int) +
(CI_PERF_MAX_CATALOG_LEN * sizeof WCHAR);
if ( _xCatalogMem.IsNull() )
_xCatalogMem.Init( _cMaxCats );
void * pvTmp = _xCatalogMem[iWhichInstance];
for ( int j = 0; j < CITOTALCOUNTER; j++)
{
*(DWORD *)(_xMemory.GetPointer() + oCounters) = *(DWORD *)pvTmp;
oCounters += sizeof(DWORD);
pvTmp = (void *)((BYTE *)pvTmp + sizeof(DWORD));
}
return TRUE;
} //Refresh
//+---------------------------------------------------------------------------
//
// Function : CReadKernelPerfData::GetCounterValue
//
// Purpose : Return the value of the specified counter
//
// Arguments : [iWhichCounter] -- which counter
//
// History : 23-March-94 t-joshh Created
//
//----------------------------------------------------------------------------
DWORD CReadKernelPerfData::GetCounterValue( int iWhichCounter )
{
if ( !_xMemory.IsNull() )
{
ULONG ByteToSkip = _cbPerfHeader
+ sizeof(int)
+ (CI_PERF_MAX_CATALOG_LEN * sizeof WCHAR) // Name of the instance
+ ( iWhichCounter * sizeof(DWORD) );
return *(DWORD *)(_xMemory.GetPointer() + ByteToSkip);
}
return 0;
} //GetCounterValue