📄 prfdata.cpp
字号:
for (CTRORD CtrOrd = 0; CtrOrd < pPrfObj->NumCounters; CtrOrd++) { PPRFITM pPrfCtr = CvtCtrOrdToPrfItm(ObjOrd, CtrOrd); PPERF_COUNTER_DEFINITION pPCD = &pm.pPCD[(int) CtrOrd]; pPCD->ByteLength = sizeof(PERF_COUNTER_DEFINITION); pPCD->CounterNameTitleIndex = dwCounter; pPCD->CounterNameTitle = NULL; pPCD->CounterHelpTitleIndex = dwHelp; pPCD->CounterHelpTitle = NULL; pPCD->DefaultScale = pPrfCtr->dwDefaultScale; pPCD->DetailLevel = pPrfCtr->dwDetailLevel; pPCD->CounterType = pPrfCtr->dwCounterType; pPCD->CounterSize = kMaxCounterSize; pPCD->CounterOffset = sizeof(PERF_COUNTER_BLOCK) + kMaxCounterSize * (int) CtrOrd; dwCounter += 2; dwHelp += 2; } // Set the PERF_COUNTER_BLOCKs for the 1 (or each) instance if (pPrfObj->MaxInstances == (INSTID) PERF_NO_INSTANCES) { pm.pPCB->ByteLength = pm.cbPCB; } else { for (INSTID InstId = 0; InstId < pPrfObj->MaxInstances; InstId++) { CalcPrfMetrics(ObjOrd, InstId, &pm); pm.pPCB->ByteLength = pm.cbPCB; } } } m_bIsActive = (NULL != m_hfm); return(dwErr);}/////////////////////////////////////////////////////////////////////// Finds an empty instance entryCPrfData::INSTID CPrfData::FindFreeInstance(OBJORD ObjOrd) const { // Sanity check for valid object and that it support instances chASSERT(IsValidObjOrd(ObjOrd)); PRFMETRICS pm; CalcPrfMetrics(ObjOrd, 0, &pm); chASSERT(pm.fSupportsInstances); LockCtrs(); // Find an unused instance entry INSTID InstId = 0; for (; InstId < (INSTID) pm.MaxInstances; InstId++) { CalcPrfMetrics(ObjOrd, InstId, &pm); if (pm.pPIN[0] == 0) break; } UnlockCtrs(); // -1 means all instances are in use return((InstId == (INSTID) pm.MaxInstances) ? (INSTID) -1 : InstId);}/////////////////////////////////////////////////////////////////////// Adds an instance to an objectCPrfData::INSTID CPrfData::AddInstance(OBJID ObjId, LPCWSTR pszInstName, LONG lUniqueID, OBJID ObjIdParent, INSTID InstIdParent) { // Make sure that instance has a valid identity chASSERT(((pszInstName == NULL) && (lUniqueID != PERF_NO_UNIQUE_ID)) || ((pszInstName != NULL) && (lUniqueID == PERF_NO_UNIQUE_ID))); // Make sure the object is valid and supports instances OBJORD ObjOrd = CvtObjIdToObjOrd(ObjId); PRFMETRICS pm; CalcPrfMetrics(ObjOrd, 0, &pm); chASSERT(pm.fSupportsInstances); // Find a place to put this instance INSTID InstId = FindFreeInstance(ObjOrd); if (InstId != (INSTID) -1) { CalcPrfMetrics(ObjOrd, InstId, &pm); // Store the Parent Object's ID/Instance ID and Unique ID. // The Collect function converts IDs to the appropriate values. pm.pPID->ParentObjectTitleIndex = (DWORD) ObjIdParent; pm.pPID->ParentObjectInstance = (DWORD) InstIdParent; pm.pPID->UniqueID = lUniqueID; if (pszInstName == NULL) { // Instance has a string name pm.pPIN[0] = 1; // Mark instance as in use pm.pPID->NameOffset = 0; pm.pPID->NameLength = 0; } else { // Instance has no string name chASSERT(lstrlenW(pszInstName) < (int) CvtObjOrdToPrfItm(ObjOrd)->cchMaxInstName); lstrcpyW(pm.pPIN, pszInstName); // Mark instance as in use pm.pPID->NameOffset = pm.cbPID; pm.pPID->NameLength = (lstrlenW(pszInstName) + 1) * sizeof(WCHAR); } } return(InstId);}/////////////////////////////////////////////////////////////////////// Removes an instance from an objectvoid CPrfData::RemoveInstance(OBJID ObjId, INSTID InstId) { PRFMETRICS pm; CalcPrfMetrics(CvtObjIdToObjOrd(ObjId), InstId, &pm); chASSERT(pm.fSupportsInstances); chASSERT(pm.pPIN[0] != 0); // Can't remove an unassigned instance LockCtrs(); pm.pPIN[0] = 0; // Mark instance as NOT in use UnlockCtrs();}///////////////////////////////////////////////////////////////////// // Sanity checks the performance object/counter map void CPrfData::VerifyPrfItemTable() { PIINDEX piiCrntObj = (PIINDEX) -1; // Object being processed // Loop through all entries in the object/counter map for (PIINDEX pii = 0; m_pPrfItms[pii].pit != PIT_END; pii++) { chASSERT(m_pPrfItms[pii].dwId != 0); // 0 is an invalid ID m_nNumPrfItems++; switch (m_pPrfItms[pii].pit) { case PIT_END: // Make sure the current object is in a good state // i.e., object has at least one counter in it chASSERT(!((piiCrntObj != -1) && (m_pPrfItms[piiCrntObj].NumCounters < (CTRORD) 1))); break; case PIT_OBJECT: // We found a new object // Every Object ID in the table must be unique chASSERT(CvtObjIdToPrfItmIndex((OBJID) m_pPrfItms[pii].dwId) == pii); // Sanity check its parameters chASSERT((m_pPrfItms[pii].DefCounter == (CTRID) -1) || (CvtCtrIdToPrfItmIndex(m_pPrfItms[pii].DefCounter) != -1)); chASSERT((m_pPrfItms[pii].MaxInstances == (INSTID) PERF_NO_INSTANCES) || (m_pPrfItms[pii].MaxInstances > 0)); chASSERT( (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_NOVICE) || (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_ADVANCED) || (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_EXPERT) || (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_WIZARD)); m_nNumObjects++; // Finish up the object that we were just working on if (piiCrntObj != -1) { // Make sure the current object is in a good state // i.e., object has at least one counter in it chASSERT(m_pPrfItms[piiCrntObj].NumCounters > 0); // The previous object must point to the current object m_pPrfItms[piiCrntObj].IndexNextObj = pii; } piiCrntObj = pii; // Save new current object m_pPrfItms[piiCrntObj].NumCounters = 0; // Assume that this is the last object in the list m_pPrfItms[piiCrntObj].IndexNextObj = -1; break; case PIT_COUNTER: chASSERT(pii != 0); // First entry in map must be PIT_OBJECT // Every Counter ID in the table must be unique chASSERT(CvtCtrIdToPrfItmIndex( (CTRID) m_pPrfItms[pii].dwId) == pii); // Sanity check its parameters chASSERT( (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_NOVICE) || (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_ADVANCED) || (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_EXPERT) || (m_pPrfItms[pii].dwDetailLevel == PERF_DETAIL_WIZARD)); m_pPrfItms[piiCrntObj].NumCounters++; break; } }}/////////////////////////////////////////////////////////////////////// Calculates an object's performance info (addresses and sizes)void CPrfData::CalcPrfMetrics(OBJORD ObjOrd, INSTID InstId, PPRFMETRICS pPM, PPRFITM* ppPrfItm) const { chASSERT(IsValidInstId(ObjOrd, InstId)); PPRFITM pPrfItm = CvtObjOrdToPrfItm(ObjOrd); if (ppPrfItm != NULL) *ppPrfItm = pPrfItm; ZeroMemory(pPM, sizeof(*pPM)); pPM->fSupportsInstances = (pPrfItm->MaxInstances != (INSTID) PERF_NO_INSTANCES); pPM->MaxInstances = (long) pPrfItm->MaxInstances; // Find the start of this object's performance data DWORD cb = 0; PIINDEX pii = 0; for (; 0 != ObjOrd--; pii = m_pPrfItms[pii].IndexNextObj) cb += m_pPrfItms[pii].cbOffsetToNextObj; // This object's PERF_OBJECT_TYPE structure & size pPM->pPOT = (PPERF_OBJECT_TYPE) (m_pPrfData + cb); pPM->cbPOT = sizeof(PERF_OBJECT_TYPE); // PERF_COUNTER_DEFINITIONs follow PERF_OBJECT_TYPE pPM->pPCD = (PPERF_COUNTER_DEFINITION) (&pPM->pPOT[1]); pPM->cbPCD = (int) pPrfItm->NumCounters * sizeof(PERF_COUNTER_DEFINITION); if (pPrfItm->MaxInstances != (INSTID) PERF_NO_INSTANCES) { long MaxInstances = (long) pPrfItm->MaxInstances; PBYTE pbEndOfCtrDefs = (PBYTE) pPM->pPCD + pPM->cbPCD; // PERF_INSTANCE_DEFINITIONs follow PERF_COUNTER_DEFINITIONs pPM->pPID = (PPERF_INSTANCE_DEFINITION) pbEndOfCtrDefs; pPM->pPID = &pPM->pPID[(int) InstId]; pPM->cbPID = sizeof(PERF_INSTANCE_DEFINITION); // PERF_COUNTER_BLOCKs follow PERF_INSTANCE_DEFINITIONs pPM->pPCB = (PPERF_COUNTER_BLOCK) (pbEndOfCtrDefs + sizeof(PERF_INSTANCE_DEFINITION) * MaxInstances); pPM->cbPCB = sizeof(PERF_COUNTER_BLOCK) + (long) pPrfItm->NumCounters * kMaxCounterSize; pPM->pPCB = (PPERF_COUNTER_BLOCK) ((PBYTE) pPM->pPCB + (int) InstId * pPM->cbPCB); // Instance names follow PERF_COUNTER_BLOCKs pPM->pPIN = (LPWSTR) (pbEndOfCtrDefs + (sizeof(PERF_INSTANCE_DEFINITION) + pPM->cbPCB) * MaxInstances); pPM->cbPIN = pPrfItm->cchMaxInstName * sizeof(WCHAR); pPM->pPIN += pPrfItm->cchMaxInstName * (int) InstId; } else { // PERF_COUNTER_BLOCK follows PERF_COUNTER_DEFINITION pPM->pPCB = (PPERF_COUNTER_BLOCK) ((PBYTE) pPM->pPCD + pPM->cbPCD); pPM->cbPCB = sizeof(PERF_COUNTER_BLOCK) + (int) pPrfItm->NumCounters * kMaxCounterSize; }}/////////////////////////////////////////////////////////////////////// Returns the address of a counter in the shared data blockPBYTE CPrfData::GetCtr(CTRID CtrId, INSTID InstId) const { int nCtrNum; OBJORD ObjOrd = CvtCtrIdToObjOrd(CtrId, &nCtrNum); PRFMETRICS pm; CalcPrfMetrics(ObjOrd, InstId, &pm); // NOTE: for convenience, all counters are 64-bit values return((PBYTE) pm.pPCB + sizeof(PERF_COUNTER_BLOCK) + nCtrNum * kMaxCounterSize);}/////////////////////////////////////////////////////////////////////// Converts an object/counter ID to its map indexCPrfData::PIINDEX CPrfData::CvtIdToPrfItmIndex( BOOL fObjectId, DWORD dwId) const { for (PIINDEX pii = 0; m_pPrfItms[pii].pit != PIT_END; pii++) { if (fObjectId && (m_pPrfItms[pii].pit == PIT_OBJECT) && (m_pPrfItms[pii].dwId == dwId)) return(pii); if (!fObjectId && (m_pPrfItms[pii].pit == PIT_COUNTER) && (m_pPrfItms[pii].dwId == dwId)) return(pii); } return(-1); // Not found}/////////////////////////////////////////////////////////////////////// Converts an object ID to its map ordinalCPrfData::OBJORD CPrfData::CvtObjIdToObjOrd(OBJID ObjId) const { for (OBJORD ObjOrd = 0; ObjOrd < m_nNumObjects; ObjOrd++) { if (CvtObjOrdToPrfItm(ObjOrd)->dwId == (DWORD) ObjId) return(ObjOrd); } chASSERTFAIL(__FILE__, __LINE__, "Object ID Not in list"); return((OBJORD) -1);}/////////////////////////////////////////////////////////////////////// Converts an objeict ordinal to its map indexCPrfData::PIINDEX CPrfData::CvtObjOrdToPrfItmIndex( OBJORD ObjOrd) const { chASSERT(IsValidObjOrd(ObjOrd)); PIINDEX pii = 0; for (; 0 != ObjOrd--; pii = m_pPrfItms[pii].IndexNextObj) ; return(pii);}/////////////////////////////////////////////////////////////////////// Converts an object's ordinal to the address of its map infoCPrfData::PPRFITM CPrfData::CvtObjOrdToPrfItm(OBJORD ObjOrd) const { return(&m_pPrfItms[CvtObjOrdToPrfItmIndex(ObjOrd)]);}/////////////////////////////////////////////////////////////////////// Converts a counter's ID to its map indexCPrfData::PIINDEX CPrfData::CvtCtrIdToPrfItmIndex( CTRID CtrId, int* pnCtrIndexInObj) const { int nCtrIndexInObj = 0; PIINDEX pii = CvtIdToPrfItmIndex(FALSE, (DWORD) CtrId); if (pii != -1) { PIINDEX piiT = pii; while (m_pPrfItms[--piiT].pit != PIT_OBJECT) nCtrIndexInObj++; } if (pnCtrIndexInObj != NULL) *pnCtrIndexInObj = nCtrIndexInObj; return(pii); // -1 if not found}/////////////////////////////////////////////////////////////////////// Converts a counter's ordinal to the address of its map infoCPrfData::PPRFITM CPrfData::CvtCtrOrdToPrfItm( OBJORD ObjOrd, CTRORD CtrOrd) const { PPRFITM pPrfItm = CvtObjOrdToPrfItm(ObjOrd); return(&pPrfItm[(int) CtrOrd + 1]);}/////////////////////////////////////////////////////////////////////// Converts a counter's ID its owning object's ordinalCPrfData::OBJORD CPrfData::CvtCtrIdToObjOrd( CTRID CtrId, int* pnCtrIndexInObj) const { PIINDEX pii = CvtCtrIdToPrfItmIndex(CtrId, pnCtrIndexInObj); OBJORD ObjOrd = 0; while (--pii > 0) { if (m_pPrfItms[pii].pit == PIT_OBJECT) ObjOrd++; } return(ObjOrd);}/////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -