Torque3D Documentation / _generateds / winPlatformCPUCount.cpp

winPlatformCPUCount.cpp

Engine/source/platformWin32/winPlatformCPUCount.cpp

More...

Detailed Description

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