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

  1. #include "stdafx.h"
  2. #include <atlbase.h>    // for CRegKey use
  3. #include "CpuUsage.h"
  4.  
  5. #pragma pack(push,8)
  6. #include "PerfCounters.h"
  7. #pragma pack(pop)
  8.  
  9. #define SYSTEM_OBJECT_INDEX                    2        // 'System' object
  10. #define PROCESS_OBJECT_INDEX                230        // 'Process' object
  11. #define PROCESSOR_OBJECT_INDEX                238        // 'Processor' object
  12. #define TOTAL_PROCESSOR_TIME_COUNTER_INDEX    240        // '% Total processor time' counter (valid in WinNT under 'System' object)
  13. #define PROCESSOR_TIME_COUNTER_INDEX        6        // '% processor time' counter (for Win2K/XP)
  14.  
  15. ///////////////////////////////////////////////////////////////////
  16. //
  17. //        GetCpuUsage uses the performance counters to retrieve the
  18. //        system cpu usage.
  19. //        The cpu usage counter is of type PERF_100NSEC_TIMER_INV
  20. //        which as the following calculation:
  21. //
  22. //        Element        Value 
  23. //        =======        ===========
  24. //        X            CounterData 
  25. //        Y            100NsTime 
  26. //        Data Size    8 Bytes
  27. //        Time base    100Ns
  28. //        Calculation 100*(1-(X1-X0)/(Y1-Y0)) 
  29. //
  30. //      where the denominator (Y) represents the total elapsed time of the 
  31. //      sample interval and the numerator (X) represents the time during 
  32. //      the interval when the monitored components were inactive.
  33. //
  34. //
  35. //        Note:
  36. //        ====
  37. //        On windows NT, cpu usage counter is '% Total processor time'
  38. //        under 'System' object. However, in Win2K/XP Microsoft moved
  39. //        that counter to '% processor time' under '_Total' instance
  40. //        of 'Processor' object.
  41. //        Read 'INFO: Percent Total Performance Counter Changes on Windows 2000'
  42. //        Q259390 in MSDN.
  43. //
  44. ///////////////////////////////////////////////////////////////////
  45.  
  46. typedef enum
  47. {
  48.     WINNT,    WIN2K_XP, WIN9X, UNKNOWN
  49. }PLATFORM;
  50.  
  51. PLATFORM GetPlatform()
  52. {
  53.     OSVERSIONINFO osvi;
  54.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  55.     if (!GetVersionEx(&osvi))
  56.         return UNKNOWN;
  57.     switch (osvi.dwPlatformId)
  58.     {
  59.     case VER_PLATFORM_WIN32_WINDOWS:
  60.         return WIN9X;
  61.     case VER_PLATFORM_WIN32_NT:
  62.         if (osvi.dwMajorVersion == 4)
  63.             return WINNT;
  64.         else
  65.             return WIN2K_XP;
  66.     }
  67.     return UNKNOWN;
  68. }
  69.  
  70. CCpuUsage::CCpuUsage()
  71. {
  72.     m_bFirstTime = true;
  73.     m_lnOldValue = 0;
  74.     memset(&m_OldPerfTime100nSec, 0, sizeof(m_OldPerfTime100nSec));
  75. }
  76.  
  77. CCpuUsage::~CCpuUsage()
  78. {
  79. }
  80.  
  81. BOOL CCpuUsage::EnablePerformaceCounters(BOOL bEnable)
  82. {
  83.     if (GetPlatform() != WIN2K_XP)
  84.         return TRUE;
  85.  
  86.     CRegKey regKey;
  87.     if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfOS\\Performance") != ERROR_SUCCESS)
  88.         return FALSE;
  89.  
  90.     regKey.SetValue(!bEnable, "Disable Performance Counters");
  91.     regKey.Close();
  92.  
  93.     if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfProc\\Performance") != ERROR_SUCCESS)
  94.         return FALSE;
  95.  
  96.     regKey.SetValue(!bEnable, "Disable Performance Counters");
  97.     regKey.Close();
  98.  
  99.     return TRUE;
  100. }
  101.  
  102. //
  103. //    GetCpuUsage returns the system-wide cpu usage.
  104. //    Since we calculate the cpu usage by two samplings, the first
  105. //    call to GetCpuUsage() returns 0 and keeps the values for the next
  106. //    sampling.
  107. //  Read the comment at the beginning of this file for the formula.
  108. //
  109. int CCpuUsage::GetCpuUsage()
  110. {
  111.     static PLATFORM Platform = GetPlatform();
  112.  
  113.     if (m_bFirstTime)
  114.         EnablePerformaceCounters();
  115.     
  116.     // Cpu usage counter is 8 byte length.
  117.     CPerfCounters<LONGLONG> PerfCounters;
  118.     char szInstance[256] = {0};
  119.  
  120. //        Note:
  121. //        ====
  122. //        On windows NT, cpu usage counter is '% Total processor time'
  123. //        under 'System' object. However, in Win2K/XP Microsoft moved
  124. //        that counter to '% processor time' under '_Total' instance
  125. //        of 'Processor' object.
  126. //        Read 'INFO: Percent Total Performance Counter Changes on Windows 2000'
  127. //        Q259390 in MSDN.
  128.  
  129.     DWORD dwObjectIndex;
  130.     DWORD dwCpuUsageIndex;
  131.     switch (Platform)
  132.     {
  133.     case WINNT:
  134.         dwObjectIndex = SYSTEM_OBJECT_INDEX;
  135.         dwCpuUsageIndex = TOTAL_PROCESSOR_TIME_COUNTER_INDEX;
  136.         break;
  137.     case WIN2K_XP:
  138.         dwObjectIndex = PROCESSOR_OBJECT_INDEX;
  139.         dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX;
  140.         strcpy(szInstance,"_Total");
  141.         break;
  142.     default:
  143.         return -1;
  144.     }
  145.  
  146.     int                CpuUsage = 0;
  147.     LONGLONG        lnNewValue = 0;
  148.     PPERF_DATA_BLOCK pPerfData = NULL;
  149.     LARGE_INTEGER    NewPerfTime100nSec = {0};
  150.  
  151.     lnNewValue = PerfCounters.GetCounterValue(&pPerfData, dwObjectIndex, dwCpuUsageIndex, szInstance);
  152.     NewPerfTime100nSec = pPerfData->PerfTime100nSec;
  153.  
  154.     if (m_bFirstTime)
  155.     {
  156.         m_bFirstTime = false;
  157.         m_lnOldValue = lnNewValue;
  158.         m_OldPerfTime100nSec = NewPerfTime100nSec;
  159.         return 0;
  160.     }
  161.  
  162.     LONGLONG lnValueDelta = lnNewValue - m_lnOldValue;
  163.     double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart;
  164.  
  165.     m_lnOldValue = lnNewValue;
  166.     m_OldPerfTime100nSec = NewPerfTime100nSec;
  167.  
  168.     double a = (double)lnValueDelta / DeltaPerfTime100nSec;
  169.  
  170.     double f = (1.0 - a) * 100.0;
  171.     CpuUsage = (int)(f + 0.5);    // rounding the result
  172.     if (CpuUsage < 0)
  173.         return 0;
  174.     return CpuUsage;
  175. }
  176.  
  177. int CCpuUsage::GetCpuUsage(LPCTSTR pProcessName)
  178. {
  179.     static PLATFORM Platform = GetPlatform();
  180.     
  181.     if (m_bFirstTime)
  182.         EnablePerformaceCounters();
  183.  
  184.     // Cpu usage counter is 8 byte length.
  185.     CPerfCounters<LONGLONG> PerfCounters;
  186.     char szInstance[256] = {0};
  187.  
  188.  
  189.     DWORD dwObjectIndex = PROCESS_OBJECT_INDEX;
  190.     DWORD dwCpuUsageIndex = PROCESSOR_TIME_COUNTER_INDEX;
  191.     strcpy(szInstance,pProcessName);
  192.  
  193.     int                CpuUsage = 0;
  194.     LONGLONG        lnNewValue = 0;
  195.     PPERF_DATA_BLOCK pPerfData = NULL;
  196.     LARGE_INTEGER    NewPerfTime100nSec = {0};
  197.  
  198.     lnNewValue = PerfCounters.GetCounterValue(&pPerfData, dwObjectIndex, dwCpuUsageIndex, szInstance);
  199.     NewPerfTime100nSec = pPerfData->PerfTime100nSec;
  200.  
  201.     if (m_bFirstTime)
  202.     {
  203.         m_bFirstTime = false;
  204.         m_lnOldValue = lnNewValue;
  205.         m_OldPerfTime100nSec = NewPerfTime100nSec;
  206.         return 0;
  207.     }
  208.  
  209.     LONGLONG lnValueDelta = lnNewValue - m_lnOldValue;
  210.     double DeltaPerfTime100nSec = (double)NewPerfTime100nSec.QuadPart - (double)m_OldPerfTime100nSec.QuadPart;
  211.  
  212.     m_lnOldValue = lnNewValue;
  213.     m_OldPerfTime100nSec = NewPerfTime100nSec;
  214.  
  215.     double a = (double)lnValueDelta / DeltaPerfTime100nSec;
  216.  
  217.     CpuUsage = (int) (a*100);
  218.     if (CpuUsage < 0)
  219.         return 0;
  220.     return CpuUsage;
  221. }
  222.  
  223.  
  224.