зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1579581, Part 1: Remove remaining CPU info off main-thread and load later on startup. r=mconley,chutten
Differential Revision: https://phabricator.services.mozilla.com/D51704 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
65962f7656
Коммит
8d905323d8
|
@ -1110,11 +1110,28 @@ EnvironmentCache.prototype = {
|
||||||
* This gets called when the delayed init completes.
|
* This gets called when the delayed init completes.
|
||||||
*/
|
*/
|
||||||
async delayedInit() {
|
async delayedInit() {
|
||||||
|
this._processData = await Services.sysinfo.processInfo;
|
||||||
|
let processData = await Services.sysinfo.processInfo;
|
||||||
|
// Remove isWow64 and isWowARM64 from processData
|
||||||
|
// to strip it down to just CPU info
|
||||||
|
delete processData.isWow64;
|
||||||
|
delete processData.isWowARM64;
|
||||||
|
|
||||||
|
let oldEnv = null;
|
||||||
|
if (!this._initTask) {
|
||||||
|
oldEnv = this.currentEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._cpuData = this._getCPUData();
|
||||||
|
// Augment the return value from the promises with cached values
|
||||||
|
this._cpuData = { ...processData, ...this._cpuData };
|
||||||
|
|
||||||
|
this._currentEnvironment.system.cpu = this._getCPUData();
|
||||||
|
|
||||||
if (AppConstants.platform == "win") {
|
if (AppConstants.platform == "win") {
|
||||||
this._hddData = await Services.sysinfo.diskInfo;
|
this._hddData = await Services.sysinfo.diskInfo;
|
||||||
this._processData = await Services.sysinfo.processInfo;
|
|
||||||
let osData = await Services.sysinfo.osInfo;
|
let osData = await Services.sysinfo.osInfo;
|
||||||
let oldEnv = null;
|
|
||||||
if (!this._initTask) {
|
if (!this._initTask) {
|
||||||
// We've finished creating the initial env, so notify for the update
|
// We've finished creating the initial env, so notify for the update
|
||||||
// This is all a bit awkward because `currentEnvironment` clones
|
// This is all a bit awkward because `currentEnvironment` clones
|
||||||
|
@ -1132,12 +1149,14 @@ EnvironmentCache.prototype = {
|
||||||
|
|
||||||
this._currentEnvironment.system.os = this._getOSData();
|
this._currentEnvironment.system.os = this._getOSData();
|
||||||
this._currentEnvironment.system.hdd = this._getHDDData();
|
this._currentEnvironment.system.hdd = this._getHDDData();
|
||||||
|
|
||||||
|
// Windows only values stored in processData
|
||||||
this._currentEnvironment.system.isWow64 = this._getProcessData().isWow64;
|
this._currentEnvironment.system.isWow64 = this._getProcessData().isWow64;
|
||||||
this._currentEnvironment.system.isWowARM64 = this._getProcessData().isWowARM64;
|
this._currentEnvironment.system.isWowARM64 = this._getProcessData().isWowARM64;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._initTask) {
|
if (!this._initTask) {
|
||||||
this._onEnvironmentChange("system-info", oldEnv);
|
this._onEnvironmentChange("system-info", oldEnv);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1859,17 +1878,7 @@ EnvironmentCache.prototype = {
|
||||||
return this._cpuData;
|
return this._cpuData;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._cpuData = {
|
this._cpuData = {};
|
||||||
count: getSysinfoProperty("cpucount", null),
|
|
||||||
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 = [
|
const CPU_EXTENSIONS = [
|
||||||
"hasMMX",
|
"hasMMX",
|
||||||
|
|
|
@ -625,26 +625,26 @@ function checkSystemSection(data, assertProcessData) {
|
||||||
"MemoryMB must be a number."
|
"MemoryMB must be a number."
|
||||||
);
|
);
|
||||||
|
|
||||||
if (gIsWindows || gIsMac || gIsLinux) {
|
if (assertProcessData) {
|
||||||
let EXTRA_CPU_FIELDS = [
|
if (gIsWindows || gIsMac || gIsLinux) {
|
||||||
"cores",
|
let EXTRA_CPU_FIELDS = [
|
||||||
"model",
|
"cores",
|
||||||
"family",
|
"model",
|
||||||
"stepping",
|
"family",
|
||||||
"l2cacheKB",
|
"stepping",
|
||||||
"l3cacheKB",
|
"l2cacheKB",
|
||||||
"speedMHz",
|
"l3cacheKB",
|
||||||
"vendor",
|
"speedMHz",
|
||||||
];
|
"vendor",
|
||||||
|
];
|
||||||
|
|
||||||
for (let f of EXTRA_CPU_FIELDS) {
|
for (let f of EXTRA_CPU_FIELDS) {
|
||||||
// Note this is testing TelemetryEnvironment.js only, not that the
|
// Note this is testing TelemetryEnvironment.js only, not that the
|
||||||
// values are valid - null is the fallback.
|
// values are valid - null is the fallback.
|
||||||
Assert.ok(f in data.system.cpu, f + " must be available under cpu.");
|
Assert.ok(f in data.system.cpu, f + " must be available under cpu.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gIsWindows) {
|
if (gIsWindows) {
|
||||||
if (assertProcessData) {
|
|
||||||
Assert.equal(
|
Assert.equal(
|
||||||
typeof data.system.isWow64,
|
typeof data.system.isWow64,
|
||||||
"boolean",
|
"boolean",
|
||||||
|
@ -655,45 +655,61 @@ function checkSystemSection(data, assertProcessData) {
|
||||||
"boolean",
|
"boolean",
|
||||||
"isWowARM64 must be available on Windows and have the correct type."
|
"isWowARM64 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."
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let f of [
|
||||||
|
"count",
|
||||||
|
"model",
|
||||||
|
"family",
|
||||||
|
"stepping",
|
||||||
|
"l2cacheKB",
|
||||||
|
"l3cacheKB",
|
||||||
|
"speedMHz",
|
||||||
|
]) {
|
||||||
|
Assert.ok(
|
||||||
|
Number.isFinite(data.system.cpu[f]),
|
||||||
|
f + " must be a number if non null."
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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
|
// These should be numbers if they are not null
|
||||||
for (let f of ["cores"]) {
|
for (let f of [
|
||||||
Assert.ok(
|
"count",
|
||||||
!(f in data.system.cpu) || Number.isFinite(data.system.cpu[f]),
|
"model",
|
||||||
f + " must be a number if non null."
|
"family",
|
||||||
);
|
"stepping",
|
||||||
}
|
"l2cacheKB",
|
||||||
|
"l3cacheKB",
|
||||||
|
"speedMHz",
|
||||||
|
]) {
|
||||||
|
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."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// These should be numbers if they are not null
|
// We insist these are available
|
||||||
for (let f of [
|
for (let f of ["cores"]) {
|
||||||
"model",
|
Assert.ok(
|
||||||
"family",
|
!(f in data.system.cpu) || Number.isFinite(data.system.cpu[f]),
|
||||||
"stepping",
|
f + " must be a number if non null."
|
||||||
"l2cacheKB",
|
);
|
||||||
"l3cacheKB",
|
}
|
||||||
"speedMHz",
|
|
||||||
]) {
|
|
||||||
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;
|
let cpuData = data.system.cpu;
|
||||||
Assert.ok(Number.isFinite(cpuData.count), "CPU count must be a number.");
|
|
||||||
Assert.ok(
|
Assert.ok(
|
||||||
Array.isArray(cpuData.extensions),
|
Array.isArray(cpuData.extensions),
|
||||||
"CPU extensions must be available."
|
"CPU extensions must be available."
|
||||||
|
@ -2520,6 +2536,28 @@ if (gIsWindows) {
|
||||||
"boolean",
|
"boolean",
|
||||||
"isWowARM64 must be a boolean."
|
"isWowARM64 must be a boolean."
|
||||||
);
|
);
|
||||||
|
// These should be numbers if they are not null
|
||||||
|
for (let f of [
|
||||||
|
"count",
|
||||||
|
"model",
|
||||||
|
"family",
|
||||||
|
"stepping",
|
||||||
|
"l2cacheKB",
|
||||||
|
"l3cacheKB",
|
||||||
|
"speedMHz",
|
||||||
|
"cores",
|
||||||
|
]) {
|
||||||
|
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."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Assert.ok(
|
||||||
|
checkString(data.system.cpu.vendor),
|
||||||
|
"vendor must be a valid string."
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_environmentOSInfo() {
|
add_task(async function test_environmentOSInfo() {
|
||||||
|
|
|
@ -100,42 +100,66 @@ static void SimpleParseKeyValuePairs(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
namespace {
|
namespace {
|
||||||
nsresult CollectProcessInfo(ProcessInfo& info) {
|
|
||||||
// IsWow64Process2 is only available on Windows 10+, so we have to dynamically
|
|
||||||
// check for its existence.
|
|
||||||
typedef BOOL(WINAPI * LPFN_IWP2)(HANDLE, USHORT*, USHORT*);
|
|
||||||
LPFN_IWP2 iwp2 = reinterpret_cast<LPFN_IWP2>(
|
|
||||||
GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2"));
|
|
||||||
BOOL isWow64 = false;
|
|
||||||
USHORT processMachine = IMAGE_FILE_MACHINE_UNKNOWN;
|
|
||||||
USHORT nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
|
|
||||||
BOOL gotWow64Value;
|
|
||||||
if (iwp2) {
|
|
||||||
gotWow64Value = iwp2(GetCurrentProcess(), &processMachine, &nativeMachine);
|
|
||||||
if (gotWow64Value) {
|
|
||||||
info.isWow64 = (processMachine != IMAGE_FILE_MACHINE_UNKNOWN);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64);
|
|
||||||
// The function only indicates a WOW64 environment if it's 32-bit x86
|
|
||||||
// running on x86-64, so emulate what IsWow64Process2 would have given.
|
|
||||||
if (gotWow64Value && info.isWow64) {
|
|
||||||
processMachine = IMAGE_FILE_MACHINE_I386;
|
|
||||||
nativeMachine = IMAGE_FILE_MACHINE_AMD64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NS_WARNING_ASSERTION(gotWow64Value, "IsWow64Process failed");
|
|
||||||
if (gotWow64Value) {
|
|
||||||
// Set this always, even for the x86-on-arm64 case.
|
|
||||||
// Additional information if we're running x86-on-arm64
|
|
||||||
info.isWowARM64 = (processMachine == IMAGE_FILE_MACHINE_I386 &&
|
|
||||||
nativeMachine == IMAGE_FILE_MACHINE_ARM64);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static nsresult GetFolderDiskInfo(nsIFile* file, FolderDiskInfo& info) {
|
static nsresult GetFolderDiskInfo(nsIFile* file, FolderDiskInfo& info) {
|
||||||
info.model.Truncate();
|
info.model.Truncate();
|
||||||
info.revision.Truncate();
|
info.revision.Truncate();
|
||||||
|
@ -458,102 +482,7 @@ static const struct PropItems {
|
||||||
{"hasARMv7", mozilla::supports_armv7},
|
{"hasARMv7", mozilla::supports_armv7},
|
||||||
{"hasNEON", mozilla::supports_neon}};
|
{"hasNEON", mozilla::supports_neon}};
|
||||||
|
|
||||||
#ifdef XP_WIN
|
nsresult CollectProcessInfo(ProcessInfo& info) {
|
||||||
// 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() {
|
|
||||||
// check that it is called from the main thread on all platforms.
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
PRSysInfo cmd;
|
|
||||||
const char* name;
|
|
||||||
} items[] = {{PR_SI_SYSNAME, "name"},
|
|
||||||
{PR_SI_ARCHITECTURE, "arch"},
|
|
||||||
{PR_SI_RELEASE, "version"}};
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < (sizeof(items) / sizeof(items[0])); i++) {
|
|
||||||
char buf[SYS_INFO_BUFFER_LENGTH];
|
|
||||||
if (PR_GetSystemInfo(items[i].cmd, buf, sizeof(buf)) == PR_SUCCESS) {
|
|
||||||
rv = SetPropertyAsACString(NS_ConvertASCIItoUTF16(items[i].name),
|
|
||||||
nsDependentCString(buf));
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NS_WARNING("PR_GetSystemInfo failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16("hasWindowsTouchInterface"),
|
|
||||||
false);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Additional informations not available through PR_GetSystemInfo.
|
|
||||||
SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize());
|
|
||||||
SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift());
|
|
||||||
SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment());
|
|
||||||
SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize());
|
|
||||||
SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask);
|
|
||||||
|
|
||||||
uint64_t virtualMem = 0;
|
|
||||||
nsAutoCString cpuVendor;
|
nsAutoCString cpuVendor;
|
||||||
int cpuSpeed = -1;
|
int cpuSpeed = -1;
|
||||||
int cpuFamily = -1;
|
int cpuFamily = -1;
|
||||||
|
@ -565,11 +494,35 @@ nsresult nsSystemInfo::Init() {
|
||||||
int cacheSizeL3 = -1;
|
int cacheSizeL3 = -1;
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
// Virtual memory:
|
// IsWow64Process2 is only available on Windows 10+, so we have to dynamically
|
||||||
MEMORYSTATUSEX memStat;
|
// check for its existence.
|
||||||
memStat.dwLength = sizeof(memStat);
|
typedef BOOL(WINAPI * LPFN_IWP2)(HANDLE, USHORT*, USHORT*);
|
||||||
if (GlobalMemoryStatusEx(&memStat)) {
|
LPFN_IWP2 iwp2 = reinterpret_cast<LPFN_IWP2>(
|
||||||
virtualMem = memStat.ullTotalVirtual;
|
GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2"));
|
||||||
|
BOOL isWow64 = false;
|
||||||
|
USHORT processMachine = IMAGE_FILE_MACHINE_UNKNOWN;
|
||||||
|
USHORT nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
|
||||||
|
BOOL gotWow64Value;
|
||||||
|
if (iwp2) {
|
||||||
|
gotWow64Value = iwp2(GetCurrentProcess(), &processMachine, &nativeMachine);
|
||||||
|
if (gotWow64Value) {
|
||||||
|
info.isWow64 = (processMachine != IMAGE_FILE_MACHINE_UNKNOWN);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gotWow64Value = IsWow64Process(GetCurrentProcess(), &isWow64);
|
||||||
|
// The function only indicates a WOW64 environment if it's 32-bit x86
|
||||||
|
// running on x86-64, so emulate what IsWow64Process2 would have given.
|
||||||
|
if (gotWow64Value && info.isWow64) {
|
||||||
|
processMachine = IMAGE_FILE_MACHINE_I386;
|
||||||
|
nativeMachine = IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NS_WARNING_ASSERTION(gotWow64Value, "IsWow64Process failed");
|
||||||
|
if (gotWow64Value) {
|
||||||
|
// Set this always, even for the x86-on-arm64 case.
|
||||||
|
// Additional information if we're running x86-on-arm64
|
||||||
|
info.isWowARM64 = (processMachine == IMAGE_FILE_MACHINE_I386 &&
|
||||||
|
nativeMachine == IMAGE_FILE_MACHINE_ARM64);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPU speed
|
// CPU speed
|
||||||
|
@ -683,7 +636,7 @@ nsresult nsSystemInfo::Init() {
|
||||||
SimpleParseKeyValuePairs("/proc/cpuinfo", keyValuePairs);
|
SimpleParseKeyValuePairs("/proc/cpuinfo", keyValuePairs);
|
||||||
|
|
||||||
// cpuVendor from "vendor_id"
|
// cpuVendor from "vendor_id"
|
||||||
cpuVendor.Assign(keyValuePairs[NS_LITERAL_CSTRING("vendor_id")]);
|
info.cpuVendor.Assign(keyValuePairs[NS_LITERAL_CSTRING("vendor_id")]);
|
||||||
|
|
||||||
{
|
{
|
||||||
// cpuFamily from "cpu family"
|
// cpuFamily from "cpu family"
|
||||||
|
@ -772,31 +725,95 @@ nsresult nsSystemInfo::Init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
|
info.cpuCount = PR_GetNumberOfProcessors();
|
||||||
#else
|
#else
|
||||||
SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
|
info.cpuCount = PR_GetNumberOfProcessors();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (cpuSpeed >= 0) {
|
||||||
|
info.cpuSpeed = cpuSpeed;
|
||||||
|
} else {
|
||||||
|
info.cpuSpeed = 0;
|
||||||
|
}
|
||||||
|
if (!cpuVendor.IsEmpty()) {
|
||||||
|
info.cpuVendor = cpuVendor;
|
||||||
|
}
|
||||||
|
if (cpuFamily >= 0) {
|
||||||
|
info.cpuFamily = cpuFamily;
|
||||||
|
}
|
||||||
|
if (cpuModel >= 0) {
|
||||||
|
info.cpuModel = cpuModel;
|
||||||
|
}
|
||||||
|
if (cpuStepping >= 0) {
|
||||||
|
info.cpuStepping = cpuStepping;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logicalCPUs >= 0) {
|
||||||
|
info.cpuCount = logicalCPUs;
|
||||||
|
}
|
||||||
|
if (physicalCPUs >= 0) {
|
||||||
|
info.cpuCores = physicalCPUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheSizeL2 >= 0) {
|
||||||
|
info.l2cacheKB = cacheSizeL2;
|
||||||
|
}
|
||||||
|
if (cacheSizeL3 >= 0) {
|
||||||
|
info.l3cacheKB = cacheSizeL3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsSystemInfo::Init() {
|
||||||
|
// check that it is called from the main thread on all platforms.
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
PRSysInfo cmd;
|
||||||
|
const char* name;
|
||||||
|
} items[] = {{PR_SI_SYSNAME, "name"},
|
||||||
|
{PR_SI_ARCHITECTURE, "arch"},
|
||||||
|
{PR_SI_RELEASE, "version"}};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < (sizeof(items) / sizeof(items[0])); i++) {
|
||||||
|
char buf[SYS_INFO_BUFFER_LENGTH];
|
||||||
|
if (PR_GetSystemInfo(items[i].cmd, buf, sizeof(buf)) == PR_SUCCESS) {
|
||||||
|
rv = SetPropertyAsACString(NS_ConvertASCIItoUTF16(items[i].name),
|
||||||
|
nsDependentCString(buf));
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NS_WARNING("PR_GetSystemInfo failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16("hasWindowsTouchInterface"),
|
||||||
|
false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Additional informations not available through PR_GetSystemInfo.
|
||||||
|
SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize());
|
||||||
|
SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift());
|
||||||
|
SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment());
|
||||||
|
SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize());
|
||||||
|
SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask);
|
||||||
|
|
||||||
|
uint64_t virtualMem = 0;
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
// Virtual memory:
|
||||||
|
MEMORYSTATUSEX memStat;
|
||||||
|
memStat.dwLength = sizeof(memStat);
|
||||||
|
if (GlobalMemoryStatusEx(&memStat)) {
|
||||||
|
virtualMem = memStat.ullTotalVirtual;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (virtualMem)
|
if (virtualMem)
|
||||||
SetUint64Property(NS_LITERAL_STRING("virtualmemsize"), 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++) {
|
for (uint32_t i = 0; i < ArrayLength(cpuPropItems); i++) {
|
||||||
rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name),
|
rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name),
|
||||||
|
@ -1097,11 +1114,43 @@ JSObject* GetJSObjForOSInfo(JSContext* aCx, const OSInfo& info) {
|
||||||
JSObject* GetJSObjForProcessInfo(JSContext* aCx, const ProcessInfo& info) {
|
JSObject* GetJSObjForProcessInfo(JSContext* aCx, const ProcessInfo& info) {
|
||||||
JS::Rooted<JSObject*> jsInfo(aCx, JS_NewPlainObject(aCx));
|
JS::Rooted<JSObject*> jsInfo(aCx, JS_NewPlainObject(aCx));
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
JS::Rooted<JS::Value> valisWow64(aCx, JS::BooleanValue(info.isWow64));
|
JS::Rooted<JS::Value> valisWow64(aCx, JS::BooleanValue(info.isWow64));
|
||||||
JS_SetProperty(aCx, jsInfo, "isWow64", valisWow64);
|
JS_SetProperty(aCx, jsInfo, "isWow64", valisWow64);
|
||||||
|
|
||||||
JS::Rooted<JS::Value> valisWowARM64(aCx, JS::BooleanValue(info.isWowARM64));
|
JS::Rooted<JS::Value> valisWowARM64(aCx, JS::BooleanValue(info.isWowARM64));
|
||||||
JS_SetProperty(aCx, jsInfo, "isWowARM64", valisWowARM64);
|
JS_SetProperty(aCx, jsInfo, "isWowARM64", valisWowARM64);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valCountInfo(aCx, JS::Int32Value(info.cpuCount));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "count", valCountInfo);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valCoreInfo(aCx, JS::Int32Value(info.cpuCores));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "cores", valCoreInfo);
|
||||||
|
|
||||||
|
JSString* strVendor =
|
||||||
|
JS_NewStringCopyN(aCx, info.cpuVendor.get(), info.cpuVendor.Length());
|
||||||
|
JS::Rooted<JS::Value> valVendor(aCx, JS::StringValue(strVendor));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "vendor", valVendor);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valFamilyInfo(aCx, JS::Int32Value(info.cpuFamily));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "family", valFamilyInfo);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valModelInfo(aCx, JS::Int32Value(info.cpuModel));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "model", valModelInfo);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valSteppingInfo(aCx, JS::Int32Value(info.cpuStepping));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "stepping", valSteppingInfo);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valL2CacheInfo(aCx, JS::Int32Value(info.l2cacheKB));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "l2cacheKB", valL2CacheInfo);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valL3CacheInfo(aCx, JS::Int32Value(info.l3cacheKB));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "l3cacheKB", valL3CacheInfo);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> valSpeedInfo(aCx, JS::Int32Value(info.cpuSpeed));
|
||||||
|
JS_SetProperty(aCx, jsInfo, "speedMHz", valSpeedInfo);
|
||||||
|
|
||||||
return jsInfo;
|
return jsInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1329,7 +1378,7 @@ nsSystemInfo::GetProcessInfo(JSContext* aCx, Promise** aResult) {
|
||||||
if (!XRE_IsParentProcess()) {
|
if (!XRE_IsParentProcess()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
#if defined(XP_WIN)
|
|
||||||
nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx);
|
nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx);
|
||||||
if (NS_WARN_IF(!global)) {
|
if (NS_WARN_IF(!global)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
@ -1375,6 +1424,6 @@ nsSystemInfo::GetProcessInfo(JSContext* aCx, Promise** aResult) {
|
||||||
});
|
});
|
||||||
|
|
||||||
promise.forget(aResult);
|
promise.forget(aResult);
|
||||||
#endif
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,15 @@ struct OSInfo {
|
||||||
struct ProcessInfo {
|
struct ProcessInfo {
|
||||||
bool isWow64;
|
bool isWow64;
|
||||||
bool isWowARM64;
|
bool isWowARM64;
|
||||||
|
uint32_t cpuCount;
|
||||||
|
uint32_t cpuCores;
|
||||||
|
nsCString cpuVendor;
|
||||||
|
uint32_t cpuFamily;
|
||||||
|
uint32_t cpuModel;
|
||||||
|
uint32_t cpuStepping;
|
||||||
|
uint32_t l2cacheKB;
|
||||||
|
uint32_t l3cacheKB;
|
||||||
|
uint32_t cpuSpeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef mozilla::MozPromise<DiskInfo, nsresult, /* IsExclusive */ false>
|
typedef mozilla::MozPromise<DiskInfo, nsresult, /* IsExclusive */ false>
|
||||||
|
|
|
@ -10,7 +10,6 @@ function run_test() {
|
||||||
"pagesize",
|
"pagesize",
|
||||||
"pageshift",
|
"pageshift",
|
||||||
"memmapalign",
|
"memmapalign",
|
||||||
"cpucount",
|
|
||||||
"memsize",
|
"memsize",
|
||||||
];
|
];
|
||||||
let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
|
let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче