home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2005 October / Gamestar_77_2005-10_dvd.iso / Utility / attsetup.exe / plugins / api / vc++ / example / cpuload / PerfCounters.h < prev    next >
C/C++ Source or Header  |  2004-09-01  |  6KB  |  235 lines

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <comdef.h>    // for using bstr_t class
  4. #include <WinPerf.h>
  5. #define TOTALBYTES    100*1024
  6. #define BYTEINCREMENT 10*1024
  7.  
  8. template <class T>
  9. class CPerfCounters
  10. {
  11. public:
  12.     CPerfCounters()
  13.     {
  14.     }
  15.     ~CPerfCounters()
  16.     {
  17.     }
  18.  
  19.     T GetCounterValue(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex, LPCTSTR pInstanceName = NULL)
  20.     {
  21.         QueryPerformanceData(pPerfData, dwObjectIndex, dwCounterIndex);
  22.  
  23.         PPERF_OBJECT_TYPE pPerfObj = NULL;
  24.         T lnValue = {0};
  25.  
  26.         // Get the first object type.
  27.         pPerfObj = FirstObject( *pPerfData );
  28.  
  29.         // Look for the given object index
  30.  
  31.         for( DWORD i=0; i < (*pPerfData)->NumObjectTypes; i++ )
  32.         {
  33.  
  34.             if (pPerfObj->ObjectNameTitleIndex == dwObjectIndex)
  35.             {
  36.                 lnValue = GetCounterValue(pPerfObj, dwCounterIndex, pInstanceName);
  37.                 break;
  38.             }
  39.  
  40.             pPerfObj = NextObject( pPerfObj );
  41.         }
  42.         return lnValue;
  43.     }
  44.  
  45. protected:
  46.  
  47.     class CBuffer
  48.     {
  49.     public:
  50.         CBuffer(UINT Size)
  51.         {
  52.             m_Size = Size;
  53.             m_pBuffer = (LPBYTE) malloc( Size*sizeof(BYTE) );
  54.         }
  55.         ~CBuffer()
  56.         {
  57.             free(m_pBuffer);
  58.         }
  59.         void *Realloc(UINT Size)
  60.         {
  61.             m_Size = Size;
  62.             m_pBuffer = (LPBYTE) realloc( m_pBuffer, Size );
  63.             return m_pBuffer;
  64.         }
  65.  
  66.         void Reset()
  67.         {
  68.             memset(m_pBuffer,NULL,m_Size);
  69.         }
  70.         operator LPBYTE ()
  71.         {
  72.             return m_pBuffer;
  73.         }
  74.  
  75.         UINT GetSize()
  76.         {
  77.             return m_Size;
  78.         }
  79.     public:
  80.         LPBYTE m_pBuffer;
  81.     private:
  82.         UINT m_Size;
  83.     };
  84.  
  85.     //
  86.     //    The performance data is accessed through the registry key 
  87.     //    HKEY_PEFORMANCE_DATA.
  88.     //    However, although we use the registry to collect performance data, 
  89.     //    the data is not stored in the registry database.
  90.     //    Instead, calling the registry functions with the HKEY_PEFORMANCE_DATA key 
  91.     //    causes the system to collect the data from the appropriate system 
  92.     //    object managers.
  93.     //
  94.     //    QueryPerformanceData allocates memory block for getting the
  95.     //    performance data.
  96.     //
  97.     //
  98.     void QueryPerformanceData(PERF_DATA_BLOCK **pPerfData, DWORD dwObjectIndex, DWORD dwCounterIndex)
  99.     {
  100.         //
  101.         // Since i want to use the same allocated area for each query,
  102.         // i declare CBuffer as static.
  103.         // The allocated is changed only when RegQueryValueEx return ERROR_MORE_DATA
  104.         //
  105.         static CBuffer Buffer(TOTALBYTES);
  106.  
  107.         DWORD BufferSize = Buffer.GetSize();
  108.         LONG lRes;
  109.  
  110.         char keyName[8];
  111.         sprintf(keyName,"%d %d",dwObjectIndex, dwCounterIndex);
  112.  
  113.         Buffer.Reset();
  114.         while( (lRes = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
  115.                                    keyName,
  116.                                    NULL,
  117.                                    NULL,
  118.                                    Buffer,
  119.                                    &BufferSize )) == ERROR_MORE_DATA )
  120.         {
  121.             // Get a buffer that is big enough.
  122.  
  123.             BufferSize += BYTEINCREMENT;
  124.             Buffer.Realloc(BufferSize);
  125.         }
  126.         *pPerfData = (PPERF_DATA_BLOCK) Buffer.m_pBuffer;
  127.     }
  128.  
  129.     //
  130.     //    GetCounterValue gets performance object structure
  131.     //    and returns the value of given counter index .
  132.     //    This functions iterates through the counters of the input object
  133.     //    structure and looks for the given counter index.
  134.     //
  135.     //    For objects that have instances, this function returns the counter value
  136.     //    of the instance pInstanceName.
  137.     //
  138.     T GetCounterValue(PPERF_OBJECT_TYPE pPerfObj, DWORD dwCounterIndex, LPCTSTR pInstanceName)
  139.     {
  140.         PPERF_COUNTER_DEFINITION pPerfCntr = NULL;
  141.         PPERF_INSTANCE_DEFINITION pPerfInst = NULL;
  142.         PPERF_COUNTER_BLOCK pCounterBlock = NULL;
  143.  
  144.         // Get the first counter.
  145.  
  146.         pPerfCntr = FirstCounter( pPerfObj );
  147.  
  148.         // Look for the index of '% Total processor time'
  149.  
  150.         for( DWORD j=0; j < pPerfObj->NumCounters; j++ )
  151.         {
  152.             if (pPerfCntr->CounterNameTitleIndex == dwCounterIndex)
  153.                 break;
  154.  
  155.             // Get the next counter.
  156.  
  157.             pPerfCntr = NextCounter( pPerfCntr );
  158.         }
  159.  
  160.         if( pPerfObj->NumInstances == PERF_NO_INSTANCES )        
  161.         {
  162.             pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfObj + pPerfObj->DefinitionLength);
  163.         }
  164.         else
  165.         {
  166.             pPerfInst = FirstInstance( pPerfObj );
  167.         
  168.             // Look for instance pInstanceName
  169.             _bstr_t bstrInstance;
  170.             _bstr_t bstrInputInstance = pInstanceName;
  171.             for( int k=0; k < pPerfObj->NumInstances; k++ )
  172.             {
  173.                 bstrInstance = (wchar_t *)((PBYTE)pPerfInst + pPerfInst->NameOffset);
  174.                 if (!stricmp((LPCTSTR)bstrInstance, (LPCTSTR)bstrInputInstance))
  175.                 {
  176.                     pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst + pPerfInst->ByteLength);
  177.                     break;
  178.                 }
  179.                 
  180.                 // Get the next instance.
  181.  
  182.                 pPerfInst = NextInstance( pPerfInst );
  183.             }
  184.         }
  185.  
  186.         if (pCounterBlock)
  187.         {
  188.             T *lnValue = NULL;
  189.             lnValue = (T*)((LPBYTE) pCounterBlock + pPerfCntr->CounterOffset);
  190.             return *lnValue;
  191.         }
  192.         return -1;
  193.     }
  194.  
  195.  
  196.     /*****************************************************************
  197.      *                                                               *
  198.      * Functions used to navigate through the performance data.      *
  199.      *                                                               *
  200.      *****************************************************************/
  201.  
  202.     PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
  203.     {
  204.         return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData + PerfData->HeaderLength) );
  205.     }
  206.  
  207.     PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
  208.     {
  209.         return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj + PerfObj->TotalByteLength) );
  210.     }
  211.  
  212.     PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
  213.     {
  214.         return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj + PerfObj->HeaderLength) );
  215.     }
  216.  
  217.     PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr )
  218.     {
  219.         return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr + PerfCntr->ByteLength) );
  220.     }
  221.  
  222.     PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
  223.     {
  224.         return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj + PerfObj->DefinitionLength) );
  225.     }
  226.  
  227.     PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst )
  228.     {
  229.         PPERF_COUNTER_BLOCK PerfCntrBlk;
  230.  
  231.         PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst + PerfInst->ByteLength);
  232.  
  233.         return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength) );
  234.     }
  235. };