123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- // Original code is:
- // Copyright (c) 2005 Intel Corporation
- // All Rights Reserved
- //
- // CPUCount.cpp : Detects three forms of hardware multi-threading support across IA-32 platform
- // The three forms of HW multithreading are: Multi-processor, Multi-core, and
- // HyperThreading Technology.
- // This application enumerates all the logical processors enabled by OS and BIOS,
- // determine the HW topology of these enabled logical processors in the system
- // using information provided by CPUID instruction.
- // A multi-processing system can support any combination of the three forms of HW
- // multi-threading support. The relevant topology can be identified using a
- // three level decomposition of the "initial APIC ID" into
- // Package_id, core_id, and SMT_id. Such decomposition provides a three-level map of
- // the topology of hardware resources and
- // allow multi-threaded software to manage shared hardware resources in
- // the platform to reduce resource contention
- // Multicore detection algorithm for processor and cache topology requires
- // all leaf functions of CPUID instructions be available. System administrator
- // must ensure BIOS settings is not configured to restrict CPUID functionalities.
- //-------------------------------------------------------------------------------------------------
- #include "platform/platform.h"
- #if defined( TORQUE_OS_WIN )
- #include "platform/platformCPUCount.h"
- #include <windows.h>
- #include <intrin.h>
- #include <stdio.h>
- #include <assert.h>
- namespace CPUInfo {
- // based on http://msdn.microsoft.com/en-us/library/ms683194.aspx
- // Helper function to count set bits in the processor mask.
- DWORD CountSetBits( ULONG_PTR bitMask )
- {
- DWORD LSHIFT = sizeof( ULONG_PTR ) * 8 - 1;
- DWORD bitSetCount = 0;
- ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
- DWORD i;
- for( i = 0; i <= LSHIFT; ++i )
- {
- bitSetCount += ((bitMask & bitTest) ? 1 : 0);
- bitTest /= 2;
- }
- return bitSetCount;
- }
- EConfig CPUCount( U32& TotAvailLogical, U32& TotAvailCore, U32& PhysicalNum )
- {
- EConfig StatusFlag = CONFIG_UserConfigIssue;
- TotAvailLogical = 0;
- TotAvailCore = 0;
- PhysicalNum = 0;
- PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
- DWORD returnLength = 0;
-
- // get buffer length
- DWORD rc = GetLogicalProcessorInformation( buffer, &returnLength );
- buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc( returnLength );
- rc = GetLogicalProcessorInformation( buffer, &returnLength );
- if( FALSE == rc )
- {
- free( buffer );
- return StatusFlag;
- }
- PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer;
- DWORD byteOffset = 0;
- while( byteOffset + sizeof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION ) <= returnLength )
- {
- switch( ptr->Relationship )
- {
- case RelationProcessorCore:
- TotAvailCore++;
- // A hyperthreaded core supplies more than one logical processor.
- TotAvailLogical += CountSetBits( ptr->ProcessorMask );
- break;
- case RelationProcessorPackage:
- // Logical processors share a physical package.
- PhysicalNum++;
- break;
- default:
- break;
- }
- byteOffset += sizeof( SYSTEM_LOGICAL_PROCESSOR_INFORMATION );
- ptr++;
- }
- free( buffer );
- StatusFlag = CONFIG_SingleCoreAndHTNotCapable;
- if( TotAvailCore == 1 && TotAvailLogical > TotAvailCore )
- StatusFlag = CONFIG_SingleCoreHTEnabled;
- else if( TotAvailCore > 1 && TotAvailLogical == TotAvailCore )
- StatusFlag = CONFIG_MultiCoreAndHTNotCapable;
- else if( TotAvailCore > 1 && TotAvailLogical > TotAvailCore )
- StatusFlag = CONFIG_MultiCoreAndHTEnabled;
- return StatusFlag;
- }
- } // namespace CPUInfo
- #endif
|