Bug 1128472 - Part 1. Mac and Win for model, stepping, cores, cache, cpu speed; VM max on Win only, vendor on Mac only. r=gfritzsche

This commit is contained in:
Milan Sreckovic 2015-09-01 14:48:00 +02:00
Родитель 17da24f51f
Коммит c2e36204f0
4 изменённых файлов: 251 добавлений и 13 удалений

Просмотреть файл

@ -1077,10 +1077,14 @@ EnvironmentCache.prototype = {
_getCpuData: function () {
let cpuData = {
count: getSysinfoProperty("cpucount", null),
vendor: null, // TODO: bug 1128472
family: null, // TODO: bug 1128472
model: null, // TODO: bug 1128472
stepping: null, // TODO: bug 1128472
cores: getSysinfoProperty("cpucores", null),
vendor: getSysinfoProperty("cpuvendor", null),
family: getSysinfoProperty("cpufamily", null),
model: getSysinfoProperty("cpumodel", null),
stepping: getSysinfoProperty("cpustepping", null),
l2cacheKB: getSysinfoProperty("cpucachel2", null),
l3cacheKB: getSysinfoProperty("cpucachel3", null),
speedMHz: getSysinfoProperty("cpuspeed", null),
};
const CPU_EXTENSIONS = ["hasMMX", "hasSSE", "hasSSE2", "hasSSE3", "hasSSSE3",
@ -1223,8 +1227,16 @@ EnvironmentCache.prototype = {
memoryMB = Math.round(memoryMB / 1024 / 1024);
}
let virtualMB = getSysinfoProperty("virtualmemsize", null);
if (virtualMB) {
// Send the total virtual memory size in megabytes. Rounding because
// sysinfo doesn't always provide RAM in multiples of 1024.
virtualMB = Math.round(virtualMB / 1024 / 1024);
}
return {
memoryMB: memoryMB,
virtualMaxMB: virtualMB,
#ifdef XP_WIN
isWow64: getSysinfoProperty("isWow64", null),
#endif

Просмотреть файл

@ -75,13 +75,18 @@ Structure::
},
system: {
memoryMB: <number>,
virtualMaxMB: <number>, // windows-only
isWow64: <bool>, // windows-only
cpu: {
count: <number>, // e.g. 8, or null on failure
vendor: <string>, // e.g. "GenuineIntel", or null on failure
family: <string>, // null on failure
model: <string>, // null on failure
stepping: <string>, // null on failure
count: <number>, // e.g. 8, or null on failure - logical cpus
cores: <number>, // e.g., 4, or null on failure - physical cores, only on windows & mac
vendor: <string>, // e.g. "GenuineIntel", or null on failure, only on mac
family: <string>, // null on failure, only on windows & mac
model: <string>, // null on failure, only on windows & mac
stepping: <string>, // null on failure, only on windows & mac
l2cacheKB: <number>, // L2 cache size in KB, only on windows & mac
l3cacheKB: <number>, // L3 cache size in KB, only on windows & mac
speedMHz: <number>, // cpu clock speed in MHz, only on windows & mac
extensions: [
<string>,
...

Просмотреть файл

@ -365,9 +365,42 @@ function checkSystemSection(data) {
}
Assert.ok(Number.isFinite(data.system.memoryMB), "MemoryMB must be a number.");
if (gIsWindows) {
Assert.equal(typeof data.system.isWow64, "boolean",
"isWow64 must be available on Windows and have the correct type.");
if (gIsWindows || gIsMac) {
let EXTRA_CPU_FIELDS = ["cores", "model", "family", "stepping",
"l2cacheKB", "l3cacheKB", "speedMHz"];
if (gIsMac) {
EXTRA_CPU_FIELDS.push("vendor");
}
for (let f of EXTRA_CPU_FIELDS) {
// Note this is testing TelemetryEnvironment.js only, not that the
// values are valid - null is the fallback.
Assert.ok(f in data.system.cpu, f + " must be available under cpu.");
}
if (gIsWindows) {
Assert.equal(typeof data.system.isWow64, "boolean",
"isWow64 must be available on Windows and have the correct type.");
Assert.ok("virtualMaxMB" in data.system, "virtualMaxMB must be available.");
Assert.ok(Number.isFinite(data.system.virtualMaxMB),
"virtualMaxMB must be a number.");
}
// We insist these are available
for (let f of ["cores", "speedMHz"]) {
Assert.ok(!(f in data.system.cpu) ||
Number.isFinite(data.system.cpu[f]),
f + " must be a number if non null.");
}
// These should be numbers if they are not null
for (let f of ["model", "family", "stepping", "l2cacheKB", "l3cacheKB"]) {
Assert.ok(!(f in data.system.cpu) ||
data.system.cpu[f] === null ||
Number.isFinite(data.system.cpu[f]),
f + " must be a number if non null.");
}
}
let cpuData = data.system.cpu;

Просмотреть файл

@ -49,6 +49,10 @@ NS_EXPORT int android_sdk_version;
}
#endif
#ifdef XP_MACOSX
#include <sys/sysctl.h>
#endif
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
#include "mozilla/SandboxInfo.h"
#endif
@ -235,6 +239,66 @@ static const struct PropItems
{ "hasNEON", mozilla::supports_neon }
};
#ifdef XP_WIN
// Lifted from media/webrtc/trunk/webrtc/base/systeminfo.cc,
// so keeping the _ instead of switching to camel case for now.
typedef BOOL (WINAPI *LPFN_GLPI)(
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
PDWORD);
static void
GetProcessorInformation(int* physical_cpus, int* cache_size_L2, int* cache_size_L3)
{
MOZ_ASSERT(physical_cpus && cache_size_L2 && cache_size_L3);
*physical_cpus = 0;
*cache_size_L2 = 0; // This will be in kbytes
*cache_size_L3 = 0; // This will be in kbytes
// GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond.
LPFN_GLPI glpi = reinterpret_cast<LPFN_GLPI>(GetProcAddress(
GetModuleHandle(L"kernel32"),
"GetLogicalProcessorInformation"));
if (nullptr == glpi) {
return;
}
// Determine buffer size, allocate and get processor information.
// Size can change between calls (unlikely), so a loop is done.
SYSTEM_LOGICAL_PROCESSOR_INFORMATION info_buffer[32];
SYSTEM_LOGICAL_PROCESSOR_INFORMATION* infos = &info_buffer[0];
DWORD return_length = sizeof(info_buffer);
while (!glpi(infos, &return_length)) {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && infos == &info_buffer[0]) {
infos = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)];
} else {
return;
}
}
for (size_t i = 0;
i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
if (infos[i].Relationship == RelationProcessorCore) {
++*physical_cpus;
} else if (infos[i].Relationship == RelationCache) {
// Only care about L2 and L3 cache
switch (infos[i].Cache.Level) {
case 2:
*cache_size_L2 = static_cast<int>(infos[i].Cache.Size/1024);
break;
case 3:
*cache_size_L3 = static_cast<int>(infos[i].Cache.Size/1024);
break;
default:
break;
}
}
}
if (infos != &info_buffer[0]) {
delete [] infos;
}
return;
}
#endif
nsresult
nsSystemInfo::Init()
{
@ -272,10 +336,134 @@ nsSystemInfo::Init()
SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize());
SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift());
SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment());
SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize());
SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask);
uint64_t virtualMem = 0;
nsAutoCString cpuVendor;
int cpuSpeed = -1;
int cpuFamily = -1;
int cpuModel = -1;
int cpuStepping = -1;
int logicalCPUs = -1;
int physicalCPUs = -1;
int cacheSizeL2 = -1;
int cacheSizeL3 = -1;
#if defined (XP_WIN)
// Virtual memory:
MEMORYSTATUSEX memStat;
memStat.dwLength = sizeof(memStat);
if (GlobalMemoryStatusEx(&memStat)) {
virtualMem = memStat.ullTotalVirtual;
}
// CPU speed
HKEY key;
static const WCHAR keyName[] =
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName , 0, KEY_QUERY_VALUE, &key)
== ERROR_SUCCESS) {
DWORD data, len;
len = sizeof(data);
if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast<LPBYTE>(&data),
&len) == ERROR_SUCCESS) {
cpuSpeed = static_cast<int>(data);
}
RegCloseKey(key);
}
// Other CPU attributes:
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
logicalCPUs = si.dwNumberOfProcessors;
GetProcessorInformation(&physicalCPUs, &cacheSizeL2, &cacheSizeL3);
if (physicalCPUs <= 0) {
physicalCPUs = logicalCPUs;
}
cpuFamily = si.wProcessorLevel;
cpuModel = si.wProcessorRevision >> 8;
cpuStepping = si.wProcessorRevision & 0xFF;
#elif defined (XP_MACOSX)
// CPU speed
uint64_t sysctlValue64 = 0;
uint32_t sysctlValue32 = 0;
size_t len = 0;
len = sizeof(sysctlValue64);
if (!sysctlbyname("hw.cpufrequency_max", &sysctlValue64, &len, NULL, 0)) {
cpuSpeed = static_cast<int>(sysctlValue64/1000000);
}
MOZ_ASSERT(sizeof(sysctlValue64) == len);
len = sizeof(sysctlValue32);
if (!sysctlbyname("hw.physicalcpu_max", &sysctlValue32, &len, NULL, 0)) {
physicalCPUs = static_cast<int>(sysctlValue32);
}
MOZ_ASSERT(sizeof(sysctlValue32) == len);
len = sizeof(sysctlValue32);
if (!sysctlbyname("hw.logicalcpu_max", &sysctlValue32, &len, NULL, 0)) {
logicalCPUs = static_cast<int>(sysctlValue32);
}
MOZ_ASSERT(sizeof(sysctlValue32) == len);
len = sizeof(sysctlValue64);
if (!sysctlbyname("hw.l2cachesize", &sysctlValue64, &len, NULL, 0)) {
cacheSizeL2 = static_cast<int>(sysctlValue64/1024);
}
MOZ_ASSERT(sizeof(sysctlValue64) == len);
len = sizeof(sysctlValue64);
if (!sysctlbyname("hw.l3cachesize", &sysctlValue64, &len, NULL, 0)) {
cacheSizeL3 = static_cast<int>(sysctlValue64/1024);
}
MOZ_ASSERT(sizeof(sysctlValue64) == len);
if (!sysctlbyname("machdep.cpu.vendor", NULL, &len, NULL, 0)) {
char* cpuVendorStr = new char[len];
if (!sysctlbyname("machdep.cpu.vendor", cpuVendorStr, &len, NULL, 0)) {
cpuVendor = cpuVendorStr;
}
delete [] cpuVendorStr;
}
len = sizeof(sysctlValue32);
if (!sysctlbyname("machdep.cpu.family", &sysctlValue32, &len, NULL, 0)) {
cpuFamily = static_cast<int>(sysctlValue32);
}
MOZ_ASSERT(sizeof(sysctlValue32) == len);
len = sizeof(sysctlValue32);
if (!sysctlbyname("machdep.cpu.model", &sysctlValue32, &len, NULL, 0)) {
cpuModel = static_cast<int>(sysctlValue32);
}
MOZ_ASSERT(sizeof(sysctlValue32) == len);
len = sizeof(sysctlValue32);
if (!sysctlbyname("machdep.cpu.stepping", &sysctlValue32, &len, NULL, 0)) {
cpuStepping = static_cast<int>(sysctlValue32);
}
MOZ_ASSERT(sizeof(sysctlValue32) == len);
#else
SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
#endif
if (virtualMem) SetUint64Property(NS_LITERAL_STRING("virtualmemsize"), virtualMem);
if (cpuSpeed >= 0) SetInt32Property(NS_LITERAL_STRING("cpuspeed"), cpuSpeed);
if (!cpuVendor.IsEmpty()) SetPropertyAsACString(NS_LITERAL_STRING("cpuvendor"), cpuVendor);
if (cpuFamily >= 0) SetInt32Property(NS_LITERAL_STRING("cpufamily"), cpuFamily);
if (cpuModel >= 0) SetInt32Property(NS_LITERAL_STRING("cpumodel"), cpuModel);
if (cpuStepping >= 0) SetInt32Property(NS_LITERAL_STRING("cpustepping"), cpuStepping);
if (logicalCPUs >= 0) SetInt32Property(NS_LITERAL_STRING("cpucount"), logicalCPUs);
if (physicalCPUs >= 0) SetInt32Property(NS_LITERAL_STRING("cpucores"), physicalCPUs);
if (cacheSizeL2 >= 0) SetInt32Property(NS_LITERAL_STRING("cpucachel2"), cacheSizeL2);
if (cacheSizeL3 >= 0) SetInt32Property(NS_LITERAL_STRING("cpucachel3"), cacheSizeL3);
for (uint32_t i = 0; i < ArrayLength(cpuPropItems); i++) {
rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name),
cpuPropItems[i].propfun());