Logical processors & page size potential bugs

Hi,

There is a potential bug detecting the number of logical processors and page size in Win.
A 32 bit app running under WOW64 must use GetNativeSystemInfo(…).

So the function CPUFlags() (in juce_win32_SystemStats.cpp)

SystemStats::CPUFlags::CPUFlags()
{
    hasMMX   = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0;
    hasSSE   = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0;
    hasSSE2  = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0;
   #ifdef PF_AMD3D_INSTRUCTIONS_AVAILABLE
    has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0;
   #else
    has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0;
   #endif

    SYSTEM_INFO systemInfo;
    GetSystemInfo (&systemInfo);
    numCpus = (int) systemInfo.dwNumberOfProcessors; 
}

should be:

SystemStats::CPUFlags::CPUFlags()
{
    hasMMX   = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0;
    hasSSE   = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0;
    hasSSE2  = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0;
   #ifdef PF_AMD3D_INSTRUCTIONS_AVAILABLE
    has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0;
   #else
    has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0;
   #endif

    SYSTEM_INFO systemInfo;
    BOOL isWow64 = FALSE; 
    typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); 
    LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process"); 
    if(fnIsWow64Process && fnIsWow64Process(GetCurrentProcess(), &isWow64) && isWow64) 
    { 
      // This is a 32 bit app running under WOW64 
      GetNativeSystemInfo(&systemInfo);
    } 
    else 
    { 
      GetSystemInfo(&systemInfo);
    } 
    numCpus = (int)systemInfo.dwNumberOfProcessors; 
}

And the function SystemStats::getPageSize() should also use GetNativeSystemInfo(…) with 32 bit apps under WOW64.

Ok… Although looking at the docs for GetNativeSystemInfo(), I can’t really see any reason why I shouldn’t just use it to replace all the calls to GetSystemInfo? Or am I misunderstanding…?

MSDN::GetSystemInfo: “To retrieve accurate information for an application running on WOW64, call the GetNativeSystemInfo function.”
Of course this change is only necessary for 32 bit apps running under 64 bits (WOW64).

Yeah, but that says that it works for wow64 - it doesn’t say that it ONLY works on wow64!

It sounds like it’ll work on any system that’s XP or later, so I can’t think of a reason not to just use it everywhere instead of GetSystemInfo…?

[quote=“jules”]Yeah, but that says that it works for wow64 - it doesn’t say that it ONLY works on wow64!

It sounds like it’ll work on any system that’s XP or later, so I can’t think of a reason not to just use it everywhere instead of GetSystemInfo…?[/quote]

The MSDN isn’t clear about this, I’ll check if GetNativeSystemInfo works correctly under 32 bits OS.

[quote=“Xavi”][quote=“jules”]Yeah, but that says that it works for wow64 - it doesn’t say that it ONLY works on wow64!

It sounds like it’ll work on any system that’s XP or later, so I can’t think of a reason not to just use it everywhere instead of GetSystemInfo…?[/quote]

The MSDN isn’t clear about this, I’ll check if GetNativeSystemInfo works correctly under 32 bits OS.[/quote]

Yes, I’ve tested it under XP SP3 (32 bits) and both functions return identical structs so I think it’s safe to replace GetSystemInfo by GetNativeSystemInfo.

Thanks, will do!