Old 12th August 2010, 07:46   #1
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
Get # of cores AND logical processors

This is probably what I am looking for: http://msdn.microsoft.com/en-us/library/ms683194.aspx

This is actually way over my head, I don't understand a damn thing about using System plug-in even after reading the readme. I want to get the number of cores when hyperthreading is involved. It should say I have 2 cores/processors and not 4.

CPUDesc was last compiled in 2003, and it's not unicode.
redxii is offline   Reply With Quote
Old 12th August 2010, 08:27   #2
MSG
Major Dude
 
Join Date: Oct 2006
Posts: 1,892
(You can use the CallAnsiPlugin plug-in to execute ansi plugins on unicode NSIS.)
MSG is offline   Reply With Quote
Old 12th August 2010, 17:24   #3
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
Well, it also counts hyperthreading as a cpu.. even Atom processors are hyperthreaded.
redxii is offline   Reply With Quote
Old 13th August 2010, 16:28   #4
f0rt
Junior Member
 
Join Date: Jul 2009
Posts: 36
I took the challenge and came up with the following script.

PHP Code:
OutFile "cpuinfo.exe"

!include "LogicLib.nsh"

!define FALSE                     0 
!define TRUE                      1

!define ERROR_INSUFFICIENT_BUFFER 122

Size of SYSTEM_LOGICAL_PROCESSOR_INFORMATION on 32-bit systems
!define SYS_LOG_PROC_INFO_SIZE    24
Offset of Relationship in the SYSTEM_LOGICAL_PROCESSOR_INFORMATION structure
!define RELATIONSHIP_OFFSET       4
Enum value of Relationship identifying Processor Core
!define RELATIONPROCESSORCORE     0

Count the number of bits set in given value
Parametersvalue
Returnsnumber of bits set in given value
Function countbits
   Exch 
$0
   Push 
$1
   Push 
$2

   
Set initial value for number of bits set in $0
   StrCpy 
$1 0

   
${While} $0
      
Clear least significant bit set
      IntOp 
$$1
      IntOp 
$$& $2
      
Increment number of bits set
      IntOp 
$$1
   
${EndWhile}

   ; Return 
number of bits set
   StrCpy 
$$1

   Pop 
$2
   Pop 
$1
   Exch 
$0
FunctionEnd

Evaluate processor information
Paramatersbufferlength
Returnsnumber of cores
Function evalcpuinfo
   Exch 
$length
   Exch
   Exch 
$buffer
   Push 
$2
   Push 
$3
   Push 
$4
   Push 
$Processor Cores
   Push 
$Logical Processors

   
Set buffer offset at the end of the buffer
   StrCpy 
$$0

   
Initialize number of Processor Cores and Logical Processors
   StrCpy 
$5 0
   StrCpy 
$6 0

   
Iterate through buffer starting from end
   
${While} $>= ${SYS_LOG_PROC_INFO_SIZE}
       ; 
Calculate start address of an element
       IntOp 
$$- ${SYS_LOG_PROC_INFO_SIZE}
       
IntOp $$+ $2
       
Get ProcessorMask value from element
       System
::Call "*$3(i.r4)"
       
Push $4
       IntOp 
$$+ ${RELATIONSHIP_OFFSET}
       ; 
Get Relationship value from element
       System
::Call "*$3(i.r4)"
       
${If} $== ${RELATIONPROCESSORCORE}
           ; 
Increment Processor cores
           IntOp 
$$1
           
Determine number of Logical Processor by counting the bits
           
set in the value of ProcessorMask
           Call countbits
           Pop 
$4
           
Sum up Logical Processors
           IntOp 
$$+ $4
       
${Else}
           
Pop $4
       
${EndIf}
   ${EndWhile}
 
   ; 
Set processor information as return value
   StrCpy 
$"Processor Core(s): $5 Logical Processor(s): $6"
 
   
Pop $6
   Pop 
$5
   Pop 
$4
   Pop 
$3
   Pop 
$2
   Pop 
$1
   Exch 
$0
FunctionEnd

Get processor information
Returnsnumber of Processor Cores and Logical Processors
Function getcpuinfo
  Push 
$0
  Push 
$1
  Push 
$2
  Push 
$3
  Push 
$4

  
GetLogicalProcessorInformation is only available on 
  
Windows XP SP3 or its successors.

  ; 
Initialize buffer and its length
  StrCpy 
$1 0
  StrCpy 
$2 0

  
Determine required length of buffer
  System
::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
  
Pop $4
  
${If} $== ${FALSE}
     ${If} $
== ${ERROR_INSUFFICIENT_BUFFER}
         ; 
Allocate buffer
         System
::Alloc $2
         Pop 
$1
         
${If} $!= 0
             
Get processor information
             System
::Call "kernel32::GetLogicalProcessorInformation(ir1, *ir2r2) i.r3 ? e"
             
Pop $4
             
${If} $!= ${TRUE}
                 
StrCpy $"Error: $4"
             
${Else}
                 
Push $buffer
                 Push 
$length
                 Call evalcpuinfo
                 Pop 
$0
             
${EndIf}
             ; 
Deallocate buffer
             System
::Free $1
         
${Else}
             
StrCpy $"Error: memory allocation failed!"
         
${EndIf}
     ${Else}
         
StrCpy $"Error: $4"
     
${EndIf}
  ${Else}
     
StrCpy $"GetLogicalProcessorInformation is not available on your system!"
  
${EndIf}
  
  
Pop $4
  Pop 
$3
  Pop 
$2
  Pop 
$1
  Exch 
$0
FunctionEnd

Function .onInit
  InitPluginsDir
  Call getcpuinfo
  Pop 
$0
  MessageBox MB_OK 
"$0"
  
Quit
FunctionEnd

Section 
SectionEnd 
f0rt is offline   Reply With Quote
Old 13th August 2010, 19:29   #5
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
Works for me, 64-bit Win 7, reports 2 cores/4 logical . Anyone else want to test it out?
redxii is offline   Reply With Quote
Old 13th August 2010, 22:12   #6
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
I tried on my AMD Turion X2 laptop and it reported correctly, and had someone test his and it reported correctly on his Core i7.

You should wiki it since I am sure other people will find it of use.
redxii is offline   Reply With Quote
Old 14th August 2010, 07:33   #7
MSG
Major Dude
 
Join Date: Oct 2006
Posts: 1,892
"Processor core(s): 1 Logical Processor(s): 2" for my C2D E6750 on Windows Server 2003 SP2 (actual OS).
"GetLogicalProcessorInformation is not available on your system!" for same CPU on Windows 98 SE virtual machine.
"GetLogicalProcessorInformation is not available on your system!" for same CPU on Windows 2000 pro VM. (Is there an alternative here?)
"Processor core(s): 2 Logical Processor(s): 2" for same CPU on Windows Vista VM.
"Processor core(s): 2 Logical Processor(s): 2" for same CPU on Windows 7 pro x64 VM.
"Processor core(s): 2 Logical Processor(s): 2" for same CPU on Windows XP pro x64 VM.

VMs are run on VMWare Workstation. Obviously there are still some kinks that need to be solved, but the help on the SYSTEM_LOGICAL_PROCESSOR_INFORMATION struct is rather confusing... If I'm reading it correctly, Windows Server 2003 and Windows XP Professional x64 Edition should both return the same thing. So maybe it's VMWare that's simulating the two C2D cores as two physical CPUs?
MSG is offline   Reply With Quote
Old 14th August 2010, 07:53   #8
redxii
Senior Member
 
Join Date: Nov 2005
Posts: 115
Using unicode anyway, Win 2000 users in this particular application is a very very small minority, the market share of Win 2000 isn't even half a percent. The particular program being packaged does not support 9x/ME/NT.

Every system I tested had Win 7 64-bit.
redxii is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump