winPlatformCPUCount.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Original code is:
  2. // Copyright (c) 2005 Intel Corporation
  3. // All Rights Reserved
  4. //
  5. // CPUCount.cpp : Detects three forms of hardware multi-threading support across IA-32 platform
  6. // The three forms of HW multithreading are: Multi-processor, Multi-core, and
  7. // HyperThreading Technology.
  8. // This application enumerates all the logical processors enabled by OS and BIOS,
  9. // determine the HW topology of these enabled logical processors in the system
  10. // using information provided by CPUID instruction.
  11. // A multi-processing system can support any combination of the three forms of HW
  12. // multi-threading support. The relevant topology can be identified using a
  13. // three level decomposition of the "initial APIC ID" into
  14. // Package_id, core_id, and SMT_id. Such decomposition provides a three-level map of
  15. // the topology of hardware resources and
  16. // allow multi-threaded software to manage shared hardware resources in
  17. // the platform to reduce resource contention
  18. // Multicore detection algorithm for processor and cache topology requires
  19. // all leaf functions of CPUID instructions be available. System administrator
  20. // must ensure BIOS settings is not configured to restrict CPUID functionalities.
  21. //-------------------------------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #if defined( TORQUE_OS_WIN )
  24. #include "platform/platformCPUCount.h"
  25. #include <windows.h>
  26. #include <intrin.h>
  27. #include <stdio.h>
  28. #include <assert.h>
  29. namespace CPUInfo {
  30. // based on http://msdn.microsoft.com/en-us/library/ms683194.aspx
  31. // Helper function to count set bits in the processor mask.
  32. DWORD CountSetBits( ULONG_PTR bitMask )
  33. {
  34. DWORD LSHIFT = sizeof( ULONG_PTR ) * 8 - 1;
  35. DWORD bitSetCount = 0;
  36. ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
  37. DWORD i;
  38. for( i = 0; i <= LSHIFT; ++i )
  39. {
  40. bitSetCount += ((bitMask & bitTest) ? 1 : 0);
  41. bitTest /= 2;
  42. }
  43. return bitSetCount;
  44. }
  45. EConfig CPUCount( U32& TotAvailLogical, U32& TotAvailCore, U32& PhysicalNum )
  46. {
  47. EConfig StatusFlag = CONFIG_UserConfigIssue;
  48. TotAvailLogical = 0;
  49. TotAvailCore = 0;
  50. PhysicalNum = 0;
  51. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
  52. DWORD returnLength = 0;
  53. // get buffer length
  54. DWORD rc = GetLogicalProcessorInformation( buffer, &returnLength );
  55. buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc( returnLength );
  56. rc = GetLogicalProcessorInformation( buffer, &returnLength );
  57. if( FALSE == rc )
  58. {
  59. free( buffer );
  60. return StatusFlag;
  61. }
  62. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer;
  63. DWORD byteOffset = 0;
  64. while( byteOffset + sizeof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION ) <= returnLength )
  65. {
  66. switch( ptr->Relationship )
  67. {
  68. case RelationProcessorCore:
  69. TotAvailCore++;
  70. // A hyperthreaded core supplies more than one logical processor.
  71. TotAvailLogical += CountSetBits( ptr->ProcessorMask );
  72. break;
  73. case RelationProcessorPackage:
  74. // Logical processors share a physical package.
  75. PhysicalNum++;
  76. break;
  77. default:
  78. break;
  79. }
  80. byteOffset += sizeof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION );
  81. ptr++;
  82. }
  83. free( buffer );
  84. StatusFlag = CONFIG_SingleCoreAndHTNotCapable;
  85. if( TotAvailCore == 1 && TotAvailLogical > TotAvailCore )
  86. StatusFlag = CONFIG_SingleCoreHTEnabled;
  87. else if( TotAvailCore > 1 && TotAvailLogical == TotAvailCore )
  88. StatusFlag = CONFIG_MultiCoreAndHTNotCapable;
  89. else if( TotAvailCore > 1 && TotAvailLogical > TotAvailCore )
  90. StatusFlag = CONFIG_MultiCoreAndHTEnabled;
  91. return StatusFlag;
  92. }
  93. } // namespace CPUInfo
  94. #endif