Team Fortress 2 Source Code as on 22/4/2020
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.

132 lines
3.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: return the cpu usage as a float value
  4. //
  5. // On win32 this is 0.0 to 1.0 indicating the amount of CPU time used
  6. // On posix its the load avg from the last minute
  7. //
  8. // On win32 you need to call this once in a while. Every few seconds.
  9. // First call returns zero
  10. //=============================================================================//
  11. #include "pch_tier0.h"
  12. #include "tier0/platform.h"
  13. #ifdef WIN32
  14. #include <windows.h>
  15. #define SystemBasicInformation 0
  16. #define SystemPerformanceInformation 2
  17. #define SystemTimeInformation 3
  18. #define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
  19. typedef struct
  20. {
  21. DWORD dwUnknown1;
  22. ULONG uKeMaximumIncrement;
  23. ULONG uPageSize;
  24. ULONG uMmNumberOfPhysicalPages;
  25. ULONG uMmLowestPhysicalPage;
  26. ULONG uMmHighestPhysicalPage;
  27. ULONG uAllocationGranularity;
  28. PVOID pLowestUserAddress;
  29. PVOID pMmHighestUserAddress;
  30. ULONG uKeActiveProcessors;
  31. BYTE bKeNumberProcessors;
  32. BYTE bUnknown2;
  33. WORD wUnknown3;
  34. } SYSTEM_BASIC_INFORMATION;
  35. typedef struct
  36. {
  37. LARGE_INTEGER liIdleTime;
  38. DWORD dwSpare[80];
  39. } SYSTEM_PERFORMANCE_INFORMATION;
  40. typedef struct
  41. {
  42. LARGE_INTEGER liKeBootTime;
  43. LARGE_INTEGER liKeSystemTime;
  44. LARGE_INTEGER liExpTimeZoneBias;
  45. ULONG uCurrentTimeZoneId;
  46. DWORD dwReserved;
  47. } SYSTEM_TIME_INFORMATION;
  48. typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
  49. static PROCNTQSI NtQuerySystemInformation;
  50. float GetCPUUsage()
  51. {
  52. SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
  53. SYSTEM_TIME_INFORMATION SysTimeInfo;
  54. SYSTEM_BASIC_INFORMATION SysBaseInfo;
  55. double dbIdleTime;
  56. double dbSystemTime;
  57. LONG status;
  58. static LARGE_INTEGER liOldIdleTime = {0,0};
  59. static LARGE_INTEGER liOldSystemTime = {0,0};
  60. if ( !NtQuerySystemInformation)
  61. {
  62. NtQuerySystemInformation = (PROCNTQSI)GetProcAddress( GetModuleHandle("ntdll"), "NtQuerySystemInformation" );
  63. if ( !NtQuerySystemInformation )
  64. return(0);
  65. }
  66. // get number of processors in the system
  67. status = NtQuerySystemInformation( SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL );
  68. if ( status != NO_ERROR )
  69. return(0);
  70. // get new system time
  71. status = NtQuerySystemInformation( SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0 );
  72. if ( status!=NO_ERROR )
  73. return(0);
  74. // get new CPU's idle time
  75. status = NtQuerySystemInformation( SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL );
  76. if ( status != NO_ERROR )
  77. return(0);
  78. // if it's a first call - skip it
  79. if ( liOldIdleTime.QuadPart != 0 )
  80. {
  81. // CurrentValue = NewValue - OldValue
  82. dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
  83. dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
  84. // CurrentCpuIdle = IdleTime / SystemTime
  85. dbIdleTime = dbIdleTime / dbSystemTime / (double)SysBaseInfo.bKeNumberProcessors;
  86. // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
  87. // dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;
  88. }
  89. else
  90. {
  91. dbIdleTime = 1.0f;
  92. }
  93. // store new CPU's idle and system time
  94. liOldIdleTime = SysPerfInfo.liIdleTime;
  95. liOldSystemTime = SysTimeInfo.liKeSystemTime;
  96. return (float)(1.0f - dbIdleTime);
  97. }
  98. #endif // WIN32
  99. #ifdef POSIX
  100. #include <stdlib.h>
  101. float GetCPUUsage()
  102. {
  103. double loadavg[3];
  104. getloadavg( loadavg, 3 );
  105. return loadavg[0];
  106. }
  107. #endif //POSIX