- NSIS Discussion
- Can I detect the number of CPUs in a multiprocessor machine?
Archive: Can I detect the number of CPUs in a multiprocessor machine?
Ythan
10th February 2004 23:27 UTC
Can I detect the number of CPUs in a multiprocessor machine?
I just started working with the NSIS and I love its power and flexibility, but I have a question. I was wondering if there's any way to detect the number of processors in a computer. It seems like it might be possible using the System plugin, but I can't figure out how. If anyone has experience in this area, I'd sure appreciate any help you can offer.
Thanks in advance!
-Y
Joost Verburg
10th February 2004 23:35 UTC
See the MSDN documentation for information about the GetSystemInfo API.
Ythan
11th February 2004 08:46 UTC
Cool, thanks so much for your help! I apologize in advance for asking what I'm sure is an obvious questions, but my background is in PHP scripting so this Windows API stuff is pretty foreign to me.
Anyway, I researched this and found that GetSystemInfo returns information in the following order: OEM ID, page size, minimum application address, maximum application address, active cpu mask, number of cpus, cpu type, allocation granularity, reserved. Given this, is my code to store the number of CPUs in $1 correct?
System::Alloc 32
Pop $0
System::Call "Kernel32::GetSystemInfo(i) v (r0)"
System::Call "*$0(v,v,v,v,v,&i4 .r1)"
System::Free $0
I tested this and I'm pretty sure it returns the right value. However, I wrote it from bits and pieces of other examples I found around the net and I'm not sure exactly what I'm doing. What I really want to know is whether the code is sloppy, or if it's 'correct' for what I'm trying to do. Hopefully someone with a little more experience using the system plugin to call DLLs can tell me whether I should make any changes.
Thanks again,
-Y
kichik
13th February 2004 09:14 UTC
SYSTEM_INFO is 36 bytes so you should allocate 36 bytes and not 32. Other than that, it all seems correct, thought just to be sure I'd replace all the v's on line 4 with i's, because it is DWORD and not void.
Ythan
13th February 2004 19:27 UTC
Awesome! That's just what I needed to know. Thanks both of you for all your help.
-Y
vicokoby
29th June 2011 23:34 UTC
why 36?, please give a explanation?
Anders
29th June 2011 23:40 UTC
Originally posted by vicokoby
why 36?, please give a explanation?
The size of SYSTEM_INFO on a 32 bit system
vicokoby
29th June 2011 23:57 UTC
How can I get the architecture?
vicokoby
30th June 2011 00:40 UTC
;This is my try to get the Processor Architecture:
System::Alloc 32
Pop $0
System::Call "Kernel32::GetSystemInfo(i r0)"
System::Call "*$0(i, &i2 .r1)"
System::Free $0
DetailPrint "Processor Architecture: $1" ; This print 4096 but it not a valid value!
Please help me!
Anders
30th June 2011 18:21 UTC
This whole thread is about using 36 as the size and you continue to use 32???
vicokoby
30th June 2011 18:26 UTC
Sorry,
Wich is the size in a 64 bit System?
Anders
30th June 2011 18:41 UTC
Originally posted by vicokoby
Sorry,
Wich is the size in a 64 bit System?
NSIS is still 32bit. (If you wanted to call GetNativeSystemInfo, then the info might change but this thread is not about the native version)
vicokoby
30th June 2011 18:48 UTC
Thanks!
TrifonovS
1st March 2012 08:20 UTC
There is still problem with this code. I tested the following lines (allocated memory is 36 bytes):
System::Alloc 36
Pop $0
${If} $0 <> 0
MessageBox MB_OK "Allocation done!"
System::Call "Kernel32::GetSystemInfo(i r0)"
System::Call "*$0(i, &i2 .r1)"
System::Free $0
${Else}
MessageBox MB_OK "Allocation failed!"
${EndIf}
MessageBox MB_OK "Results: $1" ; The result is 4096 (tested on XP and 7)
Why the result in $1 is always 4096? Little help, please!!!
Afrow UK
1st March 2012 11:37 UTC
You're trying to detect the system architecture? Just use x64.nsh.
Stu
Anders
1st March 2012 11:45 UTC
System::Call "*$0(i, &i2 .r1)"
That code makes no sense at all, you are grabbing a invalid field by doing this.
TrifonovS
1st March 2012 15:33 UTC
Originally Posted by Afrow UK You're trying to detect the system architecture? Just use x64.nsh.
Stu
I already done it and it works, but I just want to understand why I can not make it with the function GetSystemInfo().
Originally Posted by Anders That code makes no sense at all, you are grabbing a invalid field by doing this.
Yes, I saw this (sorry that I didn't mentioned it). I need the first word from the union in the beginning of the structure of type SYSTEM_INFO, because:
typedef struct _SYSTEM_INFO {
union {
DWORD dwOemId;
struct {
WORD wProcessorArchitecture;
WORD wReserved;
};
};
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO;
So if I understood correct the syntax, I have to use:
System::Call "*$0(&i2 .r1)"
I tried this and I tried also:
System::Call "*$0(i .r1)"
... and I always get 4096. Where is my mistake? When I try to get dwNumberOfProcessors and dwProcessorType, I see meaningful values.
Afrow UK
1st March 2012 15:41 UTC
The correct call is:
System::Call `*$0(&i2 .r1)`
However you will always get 0 because NSIS is 32-bit (that's what I get with the above). The correct way is how x64.nsh does it in the _RunningX64 macro.
Stu