diff options
Diffstat (limited to 'MistyCore/node_modules/systeminformation/lib/cpu.js')
-rw-r--r-- | MistyCore/node_modules/systeminformation/lib/cpu.js | 1702 |
1 files changed, 1702 insertions, 0 deletions
diff --git a/MistyCore/node_modules/systeminformation/lib/cpu.js b/MistyCore/node_modules/systeminformation/lib/cpu.js new file mode 100644 index 0000000..eea5dbf --- /dev/null +++ b/MistyCore/node_modules/systeminformation/lib/cpu.js @@ -0,0 +1,1702 @@ +'use strict'; +// @ts-check +// ================================================================================== +// cpu.js +// ---------------------------------------------------------------------------------- +// Description: System Information - library +// for Node.js +// Copyright: (c) 2014 - 2022 +// Author: Sebastian Hildebrandt +// ---------------------------------------------------------------------------------- +// License: MIT +// ================================================================================== +// 4. CPU +// ---------------------------------------------------------------------------------- + +const os = require('os'); +const exec = require('child_process').exec; +const execSync = require('child_process').execSync; +const fs = require('fs'); +const util = require('./util'); + +let _platform = process.platform; + +const _linux = (_platform === 'linux' || _platform === 'android'); +const _darwin = (_platform === 'darwin'); +const _windows = (_platform === 'win32'); +const _freebsd = (_platform === 'freebsd'); +const _openbsd = (_platform === 'openbsd'); +const _netbsd = (_platform === 'netbsd'); +const _sunos = (_platform === 'sunos'); + +let _cpu_speed = 0; +let _current_cpu = { + user: 0, + nice: 0, + system: 0, + idle: 0, + irq: 0, + load: 0, + tick: 0, + ms: 0, + currentLoad: 0, + currentLoadUser: 0, + currentLoadSystem: 0, + currentLoadNice: 0, + currentLoadIdle: 0, + currentLoadIrq: 0, + rawCurrentLoad: 0, + rawCurrentLoadUser: 0, + rawCurrentLoadSystem: 0, + rawCurrentLoadNice: 0, + rawCurrentLoadIdle: 0, + rawCurrentLoadIrq: 0 +}; +let _cpus = []; +let _corecount = 0; + +const AMDBaseFrequencies = { + '8346': '1.8', + '8347': '1.9', + '8350': '2.0', + '8354': '2.2', + '8356|SE': '2.4', + '8356': '2.3', + '8360': '2.5', + '2372': '2.1', + '2373': '2.1', + '2374': '2.2', + '2376': '2.3', + '2377': '2.3', + '2378': '2.4', + '2379': '2.4', + '2380': '2.5', + '2381': '2.5', + '2382': '2.6', + '2384': '2.7', + '2386': '2.8', + '2387': '2.8', + '2389': '2.9', + '2393': '3.1', + '8374': '2.2', + '8376': '2.3', + '8378': '2.4', + '8379': '2.4', + '8380': '2.5', + '8381': '2.5', + '8382': '2.6', + '8384': '2.7', + '8386': '2.8', + '8387': '2.8', + '8389': '2.9', + '8393': '3.1', + '2419EE': '1.8', + '2423HE': '2.0', + '2425HE': '2.1', + '2427': '2.2', + '2431': '2.4', + '2435': '2.6', + '2439SE': '2.8', + '8425HE': '2.1', + '8431': '2.4', + '8435': '2.6', + '8439SE': '2.8', + '4122': '2.2', + '4130': '2.6', + '4162EE': '1.7', + '4164EE': '1.8', + '4170HE': '2.1', + '4174HE': '2.3', + '4176HE': '2.4', + '4180': '2.6', + '4184': '2.8', + '6124HE': '1.8', + '6128HE': '2.0', + '6132HE': '2.2', + '6128': '2.0', + '6134': '2.3', + '6136': '2.4', + '6140': '2.6', + '6164HE': '1.7', + '6166HE': '1.8', + '6168': '1.9', + '6172': '2.1', + '6174': '2.2', + '6176': '2.3', + '6176SE': '2.3', + '6180SE': '2.5', + '3250': '2.5', + '3260': '2.7', + '3280': '2.4', + '4226': '2.7', + '4228': '2.8', + '4230': '2.9', + '4234': '3.1', + '4238': '3.3', + '4240': '3.4', + '4256': '1.6', + '4274': '2.5', + '4276': '2.6', + '4280': '2.8', + '4284': '3.0', + '6204': '3.3', + '6212': '2.6', + '6220': '3.0', + '6234': '2.4', + '6238': '2.6', + '6262HE': '1.6', + '6272': '2.1', + '6274': '2.2', + '6276': '2.3', + '6278': '2.4', + '6282SE': '2.6', + '6284SE': '2.7', + '6308': '3.5', + '6320': '2.8', + '6328': '3.2', + '6338P': '2.3', + '6344': '2.6', + '6348': '2.8', + '6366': '1.8', + '6370P': '2.0', + '6376': '2.3', + '6378': '2.4', + '6380': '2.5', + '6386': '2.8', + 'FX|4100': '3.6', + 'FX|4120': '3.9', + 'FX|4130': '3.8', + 'FX|4150': '3.8', + 'FX|4170': '4.2', + 'FX|6100': '3.3', + 'FX|6120': '3.6', + 'FX|6130': '3.6', + 'FX|6200': '3.8', + 'FX|8100': '2.8', + 'FX|8120': '3.1', + 'FX|8140': '3.2', + 'FX|8150': '3.6', + 'FX|8170': '3.9', + 'FX|4300': '3.8', + 'FX|4320': '4.0', + 'FX|4350': '4.2', + 'FX|6300': '3.5', + 'FX|6350': '3.9', + 'FX|8300': '3.3', + 'FX|8310': '3.4', + 'FX|8320': '3.5', + 'FX|8350': '4.0', + 'FX|8370': '4.0', + 'FX|9370': '4.4', + 'FX|9590': '4.7', + 'FX|8320E': '3.2', + 'FX|8370E': '3.3', + + // ZEN Desktop CPUs + '1200': '3.1', + 'Pro 1200': '3.1', + '1300X': '3.5', + 'Pro 1300': '3.5', + '1400': '3.2', + '1500X': '3.5', + 'Pro 1500': '3.5', + '1600': '3.2', + '1600X': '3.6', + 'Pro 1600': '3.2', + '1700': '3.0', + 'Pro 1700': '3.0', + '1700X': '3.4', + 'Pro 1700X': '3.4', + '1800X': '3.6', + '1900X': '3.8', + '1920': '3.2', + '1920X': '3.5', + '1950X': '3.4', + + // ZEN Desktop APUs + '200GE': '3.2', + 'Pro 200GE': '3.2', + '220GE': '3.4', + '240GE': '3.5', + '3000G': '3.5', + '300GE': '3.4', + '3050GE': '3.4', + '2200G': '3.5', + 'Pro 2200G': '3.5', + '2200GE': '3.2', + 'Pro 2200GE': '3.2', + '2400G': '3.6', + 'Pro 2400G': '3.6', + '2400GE': '3.2', + 'Pro 2400GE': '3.2', + + // ZEN Mobile APUs + 'Pro 200U': '2.3', + '300U': '2.4', + '2200U': '2.5', + '3200U': '2.6', + '2300U': '2.0', + 'Pro 2300U': '2.0', + '2500U': '2.0', + 'Pro 2500U': '2.2', + '2600H': '3.2', + '2700U': '2.0', + 'Pro 2700U': '2.2', + '2800H': '3.3', + + // ZEN Server Processors + '7351': '2.4', + '7351P': '2.4', + '7401': '2.0', + '7401P': '2.0', + '7551P': '2.0', + '7551': '2.0', + '7251': '2.1', + '7261': '2.5', + '7281': '2.1', + '7301': '2.2', + '7371': '3.1', + '7451': '2.3', + '7501': '2.0', + '7571': '2.2', + '7601': '2.2', + + // ZEN Embedded Processors + 'V1500B': '2.2', + 'V1780B': '3.35', + 'V1202B': '2.3', + 'V1404I': '2.0', + 'V1605B': '2.0', + 'V1756B': '3.25', + 'V1807B': '3.35', + + '3101': '2.1', + '3151': '2.7', + '3201': '1.5', + '3251': '2.5', + '3255': '2.5', + '3301': '2.0', + '3351': '1.9', + '3401': '1.85', + '3451': '2.15', + + // ZEN+ Desktop + '1200|AF': '3.1', + '2300X': '3.5', + '2500X': '3.6', + '2600': '3.4', + '2600E': '3.1', + '1600|AF': '3.2', + '2600X': '3.6', + '2700': '3.2', + '2700E': '2.8', + 'Pro 2700': '3.2', + '2700X': '3.7', + 'Pro 2700X': '3.6', + '2920X': '3.5', + '2950X': '3.5', + '2970WX': '3.0', + '2990WX': '3.0', + + // ZEN+ Desktop APU + 'Pro 300GE': '3.4', + 'Pro 3125GE': '3.4', + '3150G': '3.5', + 'Pro 3150G': '3.5', + '3150GE': '3.3', + 'Pro 3150GE': '3.3', + '3200G': '3.6', + 'Pro 3200G': '3.6', + '3200GE': '3.3', + 'Pro 3200GE': '3.3', + '3350G': '3.6', + 'Pro 3350G': '3.6', + '3350GE': '3.3', + 'Pro 3350GE': '3.3', + '3400G': '3.7', + 'Pro 3400G': '3.7', + '3400GE': '3.3', + 'Pro 3400GE': '3.3', + + // ZEN+ Mobile + '3300U': '2.1', + 'PRO 3300U': '2.1', + '3450U': '2.1', + '3500U': '2.1', + 'PRO 3500U': '2.1', + '3500C': '2.1', + '3550H': '2.1', + '3580U': '2.1', + '3700U': '2.3', + 'PRO 3700U': '2.3', + '3700C': '2.3', + '3750H': '2.3', + '3780U': '2.3', + + // ZEN2 Desktop CPUS + '3100': '3.6', + '3300X': '3.8', + '3500': '3.6', + '3500X': '3.6', + '3600': '3.6', + 'Pro 3600': '3.6', + '3600X': '3.8', + '3600XT': '3.8', + 'Pro 3700': '3.6', + '3700X': '3.6', + '3800X': '3.9', + '3800XT': '3.9', + '3900': '3.1', + 'Pro 3900': '3.1', + '3900X': '3.8', + '3900XT': '3.8', + '3950X': '3.5', + '3960X': '3.8', + '3970X': '3.7', + '3990X': '2.9', + '3945WX': '4.0', + '3955WX': '3.9', + '3975WX': '3.5', + '3995WX': '2.7', + + // ZEN2 Desktop APUs + '4300GE': '3.5', + 'Pro 4300GE': '3.5', + '4300G': '3.8', + 'Pro 4300G': '3.8', + '4600GE': '3.3', + 'Pro 4650GE': '3.3', + '4600G': '3.7', + 'Pro 4650G': '3.7', + '4700GE': '3.1', + 'Pro 4750GE': '3.1', + '4700G': '3.6', + 'Pro 4750G': '3.6', + '4300U': '2.7', + '4450U': '2.5', + 'Pro 4450U': '2.5', + '4500U': '2.3', + '4600U': '2.1', + 'PRO 4650U': '2.1', + '4680U': '2.1', + '4600HS': '3.0', + '4600H': '3.0', + '4700U': '2.0', + 'PRO 4750U': '1.7', + '4800U': '1.8', + '4800HS': '2.9', + '4800H': '2.9', + '4900HS': '3.0', + '4900H': '3.3', + '5300U': '2.6', + '5500U': '2.1', + '5700U': '1.8', + + // ZEN2 - EPYC + '7232P': '3.1', + '7302P': '3.0', + '7402P': '2.8', + '7502P': '2.5', + '7702P': '2.0', + '7252': '3.1', + '7262': '3.2', + '7272': '2.9', + '7282': '2.8', + '7302': '3.0', + '7352': '2.3', + '7402': '2.8', + '7452': '2.35', + '7502': '2.5', + '7532': '2.4', + '7542': '2.9', + '7552': '2.2', + '7642': '2.3', + '7662': '2.0', + '7702': '2.0', + '7742': '2.25', + '7H12': '2.6', + '7F32': '3.7', + '7F52': '3.5', + '7F72': '3.2', + + // Epyc (Milan) + + '7763': '2.45', + '7713': '2.0', + '7713P': '2.0', + '7663': '2.0', + '7643': '2.3', + '75F3': '2.95', + '7543': '2.8', + '7543P': '2.8', + '7513': '2.6', + '7453': '2.75', + '74F3': '3.2', + '7443': '2.85', + '7443P': '2.85', + '7413': '2.65', + '73F3': '3.5', + '7343': '3.2', + '7313': '3.0', + '7313P': '3.0', + '72F3': '3.7', + + // ZEN3 + '5600X': '3.7', + '5800X': '3.8', + '5900X': '3.7', + '5950X': '3.4' +}; + + +const socketTypes = { + 1: 'Other', + 2: 'Unknown', + 3: 'Daughter Board', + 4: 'ZIF Socket', + 5: 'Replacement/Piggy Back', + 6: 'None', + 7: 'LIF Socket', + 8: 'Slot 1', + 9: 'Slot 2', + 10: '370 Pin Socket', + 11: 'Slot A', + 12: 'Slot M', + 13: '423', + 14: 'A (Socket 462)', + 15: '478', + 16: '754', + 17: '940', + 18: '939', + 19: 'mPGA604', + 20: 'LGA771', + 21: 'LGA775', + 22: 'S1', + 23: 'AM2', + 24: 'F (1207)', + 25: 'LGA1366', + 26: 'G34', + 27: 'AM3', + 28: 'C32', + 29: 'LGA1156', + 30: 'LGA1567', + 31: 'PGA988A', + 32: 'BGA1288', + 33: 'rPGA988B', + 34: 'BGA1023', + 35: 'BGA1224', + 36: 'LGA1155', + 37: 'LGA1356', + 38: 'LGA2011', + 39: 'FS1', + 40: 'FS2', + 41: 'FM1', + 42: 'FM2', + 43: 'LGA2011-3', + 44: 'LGA1356-3', + 45: 'LGA1150', + 46: 'BGA1168', + 47: 'BGA1234', + 48: 'BGA1364', + 49: 'AM4', + 50: 'LGA1151', + 51: 'BGA1356', + 52: 'BGA1440', + 53: 'BGA1515', + 54: 'LGA3647-1', + 55: 'SP3', + 56: 'SP3r2', + 57: 'LGA2066', + 58: 'BGA1392', + 59: 'BGA1510', + 60: 'BGA1528', + 61: 'LGA4189', + 62: 'LGA1200', + 63: 'LGA4677', +}; + +const socketTypesByName = { + 'LGA1150': 'i7-5775C i3-4340 i3-4170 G3250 i3-4160T i3-4160 E3-1231 G3258 G3240 i7-4790S i7-4790K i7-4790 i5-4690K i5-4690 i5-4590T i5-4590S i5-4590 i5-4460 i3-4360 i3-4150 G1820 G3420 G3220 i7-4771 i5-4440 i3-4330 i3-4130T i3-4130 E3-1230 i7-4770S i7-4770K i7-4770 i5-4670K i5-4670 i5-4570T i5-4570S i5-4570 i5-4430', + 'LGA1151': 'i9-9900KS E-2288G E-2224 G5420 i9-9900T i9-9900 i7-9700T i7-9700F i7-9700E i7-9700 i5-9600 i5-9500T i5-9500F i5-9500 i5-9400T i3-9350K i3-9300 i3-9100T i3-9100F i3-9100 G4930 i9-9900KF i7-9700KF i5-9600KF i5-9400F i5-9400 i3-9350KF i9-9900K i7-9700K i5-9600K G5500 G5400 i7-8700T i7-8086K i5-8600 i5-8500T i5-8500 i5-8400T i3-8300 i3-8100T G4900 i7-8700K i7-8700 i5-8600K i5-8400 i3-8350K i3-8100 E3-1270 G4600 G4560 i7-7700T i7-7700K i7-7700 i5-7600K i5-7600 i5-7500T i5-7500 i5-7400 i3-7350K i3-7300 i3-7100T i3-7100 G3930 G3900 G4400 i7-6700T i7-6700K i7-6700 i5-6600K i5-6600 i5-6500T i5-6500 i5-6400T i5-6400 i3-6300 i3-6100T i3-6100 E3-1270 E3-1270 T4500 T4400', + '1155': 'G440 G460 G465 G470 G530T G540T G550T G1610T G1620T G530 G540 G1610 G550 G1620 G555 G1630 i3-2100T i3-2120T i3-3220T i3-3240T i3-3250T i3-2100 i3-2105 i3-2102 i3-3210 i3-3220 i3-2125 i3-2120 i3-3225 i3-2130 i3-3245 i3-3240 i3-3250 i5-3570T i5-2500T i5-2400S i5-2405S i5-2390T i5-3330S i5-2500S i5-3335S i5-2300 i5-3450S i5-3340S i5-3470S i5-3475S i5-3470T i5-2310 i5-3550S i5-2320 i5-3330 i5-3350P i5-3450 i5-2400 i5-3340 i5-3570S i5-2380P i5-2450P i5-3470 i5-2500K i5-3550 i5-2500 i5-3570 i5-3570K i5-2550K i7-3770T i7-2600S i7-3770S i7-2600K i7-2600 i7-3770 i7-3770K i7-2700K G620T G630T G640T G2020T G645T G2100T G2030T G622 G860T G620 G632 G2120T G630 G640 G2010 G840 G2020 G850 G645 G2030 G860 G2120 G870 G2130 G2140 E3-1220L E3-1220L E3-1260L E3-1265L E3-1220 E3-1225 E3-1220 E3-1235 E3-1225 E3-1230 E3-1230 E3-1240 E3-1245 E3-1270 E3-1275 E3-1240 E3-1245 E3-1270 E3-1280 E3-1275 E3-1290 E3-1280 E3-1290' +}; + +function getSocketTypesByName(str) { + let result = ''; + for (const key in socketTypesByName) { + const names = socketTypesByName[key].split(' '); + for (let i = 0; i < names.length; i++) { + if (str.indexOf(names[i]) >= 0) { + result = key; + } + } + } + return result; +} + +function cpuManufacturer(str) { + let result = str; + str = str.toLowerCase(); + + if (str.indexOf('intel') >= 0) { result = 'Intel'; } + if (str.indexOf('amd') >= 0) { result = 'AMD'; } + if (str.indexOf('qemu') >= 0) { result = 'QEMU'; } + if (str.indexOf('hygon') >= 0) { result = 'Hygon'; } + if (str.indexOf('centaur') >= 0) { result = 'WinChip/Via'; } + if (str.indexOf('vmware') >= 0) { result = 'VMware'; } + if (str.indexOf('Xen') >= 0) { result = 'Xen Hypervisor'; } + if (str.indexOf('tcg') >= 0) { result = 'QEMU'; } + if (str.indexOf('apple') >= 0) { result = 'Apple'; } + + return result; +} + +function cpuBrandManufacturer(res) { + res.brand = res.brand.replace(/\(R\)+/g, '®').replace(/\s+/g, ' ').trim(); + res.brand = res.brand.replace(/\(TM\)+/g, '™').replace(/\s+/g, ' ').trim(); + res.brand = res.brand.replace(/\(C\)+/g, '©').replace(/\s+/g, ' ').trim(); + res.brand = res.brand.replace(/CPU+/g, '').replace(/\s+/g, ' ').trim(); + res.manufacturer = cpuManufacturer(res.brand); + + let parts = res.brand.split(' '); + parts.shift(); + res.brand = parts.join(' '); + return res; +} + +function getAMDSpeed(brand) { + let result = '0'; + for (let key in AMDBaseFrequencies) { + if ({}.hasOwnProperty.call(AMDBaseFrequencies, key)) { + let parts = key.split('|'); + let found = 0; + parts.forEach(item => { + if (brand.indexOf(item) > -1) { + found++; + } + }); + if (found === parts.length) { + result = AMDBaseFrequencies[key]; + } + } + } + return parseFloat(result); +} + +// -------------------------- +// CPU - brand, speed + +function getCpu() { + + return new Promise((resolve) => { + process.nextTick(() => { + const UNKNOWN = 'unknown'; + let result = { + manufacturer: UNKNOWN, + brand: UNKNOWN, + vendor: '', + family: '', + model: '', + stepping: '', + revision: '', + voltage: '', + speed: 0, + speedMin: 0, + speedMax: 0, + governor: '', + cores: util.cores(), + physicalCores: util.cores(), + performanceCores: util.cores(), + efficiencyCores: 0, + processors: 1, + socket: '', + flags: '', + virtualization: false, + cache: {} + }; + cpuFlags().then(flags => { + result.flags = flags; + result.virtualization = flags.indexOf('vmx') > -1 || flags.indexOf('svm') > -1; + if (_darwin) { + exec('sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min hw.packages hw.physicalcpu_max hw.ncpu hw.tbfrequency hw.cpufamily hw.cpusubfamily', function (error, stdout) { + let lines = stdout.toString().split('\n'); + const modelline = util.getValue(lines, 'machdep.cpu.brand_string'); + const modellineParts = modelline.split('@'); + result.brand = modellineParts[0].trim(); + const speed = modellineParts[1] ? modellineParts[1].trim() : '0'; + result.speed = parseFloat(speed.replace(/GHz+/g, '')); + let tbFrequency = util.getValue(lines, 'hw.tbfrequency') / 1000000000.0; + tbFrequency = tbFrequency < 0.1 ? tbFrequency * 100 : tbFrequency; + result.speed = result.speed === 0 ? tbFrequency : result.speed; + + _cpu_speed = result.speed; + result = cpuBrandManufacturer(result); + result.speedMin = util.getValue(lines, 'hw.cpufrequency_min') ? (util.getValue(lines, 'hw.cpufrequency_min') / 1000000000.0) : result.speed; + result.speedMax = util.getValue(lines, 'hw.cpufrequency_max') ? (util.getValue(lines, 'hw.cpufrequency_max') / 1000000000.0) : result.speed; + result.vendor = util.getValue(lines, 'machdep.cpu.vendor') || 'Apple'; + result.family = util.getValue(lines, 'machdep.cpu.family') || util.getValue(lines, 'hw.cpufamily'); + result.model = util.getValue(lines, 'machdep.cpu.model'); + result.stepping = util.getValue(lines, 'machdep.cpu.stepping') || util.getValue(lines, 'hw.cpusubfamily'); + result.virtualization = true; + const countProcessors = util.getValue(lines, 'hw.packages'); + const countCores = util.getValue(lines, 'hw.physicalcpu_max'); + const countThreads = util.getValue(lines, 'hw.ncpu'); + if (os.arch() === 'arm64') { + const clusters = execSync('ioreg -c IOPlatformDevice -d 3 -r | grep cluster-type').toString().split('\n'); + const efficiencyCores = clusters.filter(line => line.indexOf('"E"') >= 0).length; + const performanceCores = clusters.filter(line => line.indexOf('"P"') >= 0).length; + result.socket = 'SOC'; + result.efficiencyCores = efficiencyCores; + result.performanceCores = performanceCores; + } + if (countProcessors) { + result.processors = parseInt(countProcessors) || 1; + } + if (countCores && countThreads) { + result.cores = parseInt(countThreads) || util.cores(); + result.physicalCores = parseInt(countCores) || util.cores(); + } + cpuCache().then((res) => { + result.cache = res; + resolve(result); + }); + }); + } + if (_linux) { + let modelline = ''; + let lines = []; + if (os.cpus()[0] && os.cpus()[0].model) { modelline = os.cpus()[0].model; } + exec('export LC_ALL=C; lscpu; echo -n "Governor: "; cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 2>/dev/null; echo; unset LC_ALL', function (error, stdout) { + if (!error) { + lines = stdout.toString().split('\n'); + } + modelline = util.getValue(lines, 'model name') || modelline; + const modellineParts = modelline.split('@'); + result.brand = modellineParts[0].trim(); + result.speed = modellineParts[1] ? parseFloat(modellineParts[1].trim()) : 0; + if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) { + result.speed = getAMDSpeed(result.brand); + } + if (result.speed === 0) { + const current = getCpuCurrentSpeedSync(); + if (current.avg !== 0) { result.speed = current.avg; } + } + _cpu_speed = result.speed; + result.speedMin = Math.round(parseFloat(util.getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100; + result.speedMax = Math.round(parseFloat(util.getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100; + + result = cpuBrandManufacturer(result); + result.vendor = cpuManufacturer(util.getValue(lines, 'vendor id')); + + result.family = util.getValue(lines, 'cpu family'); + result.model = util.getValue(lines, 'model:'); + result.stepping = util.getValue(lines, 'stepping'); + result.revision = util.getValue(lines, 'cpu revision'); + result.cache.l1d = util.getValue(lines, 'l1d cache'); + if (result.cache.l1d) { result.cache.l1d = parseInt(result.cache.l1d) * (result.cache.l1d.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l1d.indexOf('K') !== -1 ? 1024 : 1)); } + result.cache.l1i = util.getValue(lines, 'l1i cache'); + if (result.cache.l1i) { result.cache.l1i = parseInt(result.cache.l1i) * (result.cache.l1i.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l1i.indexOf('K') !== -1 ? 1024 : 1)); } + result.cache.l2 = util.getValue(lines, 'l2 cache'); + if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * (result.cache.l2.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l2.indexOf('K') !== -1 ? 1024 : 1)); } + result.cache.l3 = util.getValue(lines, 'l3 cache'); + if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * (result.cache.l3.indexOf('M') !== -1 ? 1024 * 1024 : (result.cache.l3.indexOf('K') !== -1 ? 1024 : 1)); } + + const threadsPerCore = util.getValue(lines, 'thread(s) per core') || '1'; + const processors = util.getValue(lines, 'socket(s)') || '1'; + let threadsPerCoreInt = parseInt(threadsPerCore, 10); // threads per code (normally only for performance cores) + let processorsInt = parseInt(processors, 10) || 1; // number of sockets / processor units in machine (normally 1) + const coresPerSocket = parseInt(util.getValue(lines, 'core(s) per socket'), 10); // number of cores (e.g. 16 on i12900) + result.physicalCores = coresPerSocket ? coresPerSocket * processorsInt : result.cores / threadsPerCoreInt; + result.performanceCores = threadsPerCoreInt > 1 ? result.cores - result.physicalCores : result.cores; + result.efficiencyCores = threadsPerCoreInt > 1 ? result.cores - (threadsPerCoreInt * result.performanceCores) : 0; + result.processors = processorsInt; + result.governor = util.getValue(lines, 'governor') || ''; + + // Test Raspberry + if (result.vendor === 'ARM') { + const linesRpi = fs.readFileSync('/proc/cpuinfo').toString().split('\n'); + const rPIRevision = util.decodePiCpuinfo(linesRpi); + if (rPIRevision.model.toLowerCase().indexOf('raspberry') >= 0) { + result.family = result.manufacturer; + result.manufacturer = rPIRevision.manufacturer; + result.brand = rPIRevision.processor; + result.revision = rPIRevision.revisionCode; + result.socket = 'SOC'; + } + } + + // socket type + let lines2 = []; + exec('export LC_ALL=C; dmidecode –t 4 2>/dev/null | grep "Upgrade: Socket"; unset LC_ALL', function (error2, stdout2) { + lines2 = stdout2.toString().split('\n'); + if (lines2 && lines2.length) { + result.socket = util.getValue(lines2, 'Upgrade').replace('Socket', '').trim() || result.socket; + } + resolve(result); + }); + }); + } + if (_freebsd || _openbsd || _netbsd) { + let modelline = ''; + let lines = []; + if (os.cpus()[0] && os.cpus()[0].model) { modelline = os.cpus()[0].model; } + exec('export LC_ALL=C; dmidecode -t 4; dmidecode -t 7 unset LC_ALL', function (error, stdout) { + let cache = []; + if (!error) { + const data = stdout.toString().split('# dmidecode'); + const processor = data.length > 1 ? data[1] : ''; + cache = data.length > 2 ? data[2].split('Cache Information') : []; + + lines = processor.split('\n'); + } + result.brand = modelline.split('@')[0].trim(); + result.speed = modelline.split('@')[1] ? parseFloat(modelline.split('@')[1].trim()) : 0; + if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) { + result.speed = getAMDSpeed(result.brand); + } + if (result.speed === 0) { + const current = getCpuCurrentSpeedSync(); + if (current.avg !== 0) { result.speed = current.avg; } + } + _cpu_speed = result.speed; + result.speedMin = result.speed; + result.speedMax = Math.round(parseFloat(util.getValue(lines, 'max speed').replace(/Mhz/g, '')) / 10.0) / 100; + + result = cpuBrandManufacturer(result); + result.vendor = cpuManufacturer(util.getValue(lines, 'manufacturer')); + let sig = util.getValue(lines, 'signature'); + sig = sig.split(','); + for (let i = 0; i < sig.length; i++) { + sig[i] = sig[i].trim(); + } + result.family = util.getValue(sig, 'Family', ' ', true); + result.model = util.getValue(sig, 'Model', ' ', true); + result.stepping = util.getValue(sig, 'Stepping', ' ', true); + result.revision = ''; + const voltage = parseFloat(util.getValue(lines, 'voltage')); + result.voltage = isNaN(voltage) ? '' : voltage.toFixed(2); + for (let i = 0; i < cache.length; i++) { + lines = cache[i].split('\n'); + let cacheType = util.getValue(lines, 'Socket Designation').toLowerCase().replace(' ', '-').split('-'); + cacheType = cacheType.length ? cacheType[0] : ''; + const sizeParts = util.getValue(lines, 'Installed Size').split(' '); + let size = parseInt(sizeParts[0], 10); + const unit = sizeParts.length > 1 ? sizeParts[1] : 'kb'; + size = size * (unit === 'kb' ? 1024 : (unit === 'mb' ? 1024 * 1024 : (unit === 'gb' ? 1024 * 1024 * 1024 : 1))); + if (cacheType) { + if (cacheType === 'l1') { + result.cache[cacheType + 'd'] = size / 2; + result.cache[cacheType + 'i'] = size / 2; + } else { + result.cache[cacheType] = size; + } + } + } + // socket type + result.socket = util.getValue(lines, 'Upgrade').replace('Socket', '').trim(); + // # threads / # cores + const threadCount = util.getValue(lines, 'thread count').trim(); + const coreCount = util.getValue(lines, 'core count').trim(); + if (coreCount && threadCount) { + result.cores = parseInt(threadCount, 10); + result.physicalCores = parseInt(coreCount, 10); + } + resolve(result); + }); + } + if (_sunos) { + resolve(result); + } + if (_windows) { + try { + const workload = []; + workload.push(util.powerShell('Get-WmiObject Win32_processor | select Name, Revision, L2CacheSize, L3CacheSize, Manufacturer, MaxClockSpeed, Description, UpgradeMethod, Caption, NumberOfLogicalProcessors, NumberOfCores | fl')); + workload.push(util.powerShell('Get-WmiObject Win32_CacheMemory | select CacheType,InstalledSize,Level | fl')); + workload.push(util.powerShell('(Get-CimInstance Win32_ComputerSystem).HypervisorPresent')); + + Promise.all( + workload + ).then((data) => { + let lines = data[0].split('\r\n'); + let name = util.getValue(lines, 'name', ':') || ''; + if (name.indexOf('@') >= 0) { + result.brand = name.split('@')[0].trim(); + result.speed = name.split('@')[1] ? parseFloat(name.split('@')[1].trim()) : 0; + _cpu_speed = result.speed; + } else { + result.brand = name.trim(); + result.speed = 0; + } + result = cpuBrandManufacturer(result); + result.revision = util.getValue(lines, 'revision', ':'); + result.cache.l1d = 0; + result.cache.l1i = 0; + result.cache.l2 = util.getValue(lines, 'l2cachesize', ':'); + result.cache.l3 = util.getValue(lines, 'l3cachesize', ':'); + if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2, 10) * 1024; } + if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3, 10) * 1024; } + result.vendor = util.getValue(lines, 'manufacturer', ':'); + result.speedMax = Math.round(parseFloat(util.getValue(lines, 'maxclockspeed', ':').replace(/,/g, '.')) / 10.0) / 100; + if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) { + result.speed = getAMDSpeed(result.brand); + } + if (result.speed === 0) { + result.speed = result.speedMax; + } + result.speedMin = result.speed; + + let description = util.getValue(lines, 'description', ':').split(' '); + for (let i = 0; i < description.length; i++) { + if (description[i].toLowerCase().startsWith('family') && (i + 1) < description.length && description[i + 1]) { + result.family = description[i + 1]; + } + if (description[i].toLowerCase().startsWith('model') && (i + 1) < description.length && description[i + 1]) { + result.model = description[i + 1]; + } + if (description[i].toLowerCase().startsWith('stepping') && (i + 1) < description.length && description[i + 1]) { + result.stepping = description[i + 1]; + } + } + // socket type + const socketId = util.getValue(lines, 'UpgradeMethod', ':'); + if (socketTypes[socketId]) { + result.socket = socketTypes[socketId]; + } + const socketByName = getSocketTypesByName(name); + if (socketByName) { + result.socket = socketByName; + } + // # threads / # cores + const countProcessors = util.countLines(lines, 'Caption'); + const countThreads = util.getValue(lines, 'NumberOfLogicalProcessors', ':'); + const countCores = util.getValue(lines, 'NumberOfCores', ':'); + if (countProcessors) { + result.processors = parseInt(countProcessors) || 1; + } + if (countCores && countThreads) { + result.cores = parseInt(countThreads) || util.cores(); + result.physicalCores = parseInt(countCores) || util.cores(); + } + if (countProcessors > 1) { + result.cores = result.cores * countProcessors; + result.physicalCores = result.physicalCores * countProcessors; + } + const parts = data[1].split(/\n\s*\n/); + parts.forEach(function (part) { + lines = part.split('\r\n'); + const cacheType = util.getValue(lines, 'CacheType'); + const level = util.getValue(lines, 'Level'); + const installedSize = util.getValue(lines, 'InstalledSize'); + // L1 Instructions + if (level === '3' && cacheType === '3') { + result.cache.l1i = parseInt(installedSize, 10); + } + // L1 Data + if (level === '3' && cacheType === '4') { + result.cache.l1d = parseInt(installedSize, 10); + } + // L1 all + if (level === '3' && cacheType === '5' && !result.cache.l1i && !result.cache.l1d) { + result.cache.l1i = parseInt(installedSize, 10) / 2; + result.cache.l1d = parseInt(installedSize, 10) / 2; + } + }); + const hyperv = data[2] ? data[2].toString().toLowerCase() : ''; + result.virtualization = hyperv.indexOf('true') !== -1; + + resolve(result); + }); + } catch (e) { + resolve(result); + } + } + }); + }); + }); +} + +// -------------------------- +// CPU - Processor Data + +function cpu(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + getCpu().then(result => { + if (callback) { callback(result); } + resolve(result); + }); + }); + }); +} + +exports.cpu = cpu; + +// -------------------------- +// CPU - current speed - in GHz + +function getCpuCurrentSpeedSync() { + + let cpus = os.cpus(); + let minFreq = 999999999; + let maxFreq = 0; + let avgFreq = 0; + let cores = []; + + if (cpus && cpus.length) { + for (let i in cpus) { + if ({}.hasOwnProperty.call(cpus, i)) { + let freq = cpus[i].speed > 100 ? (cpus[i].speed + 1) / 1000 : cpus[i].speed / 10; + avgFreq = avgFreq + freq; + if (freq > maxFreq) { maxFreq = freq; } + if (freq < minFreq) { minFreq = freq; } + cores.push(parseFloat(freq.toFixed(2))); + } + } + avgFreq = avgFreq / cpus.length; + return { + min: parseFloat(minFreq.toFixed(2)), + max: parseFloat(maxFreq.toFixed(2)), + avg: parseFloat((avgFreq).toFixed(2)), + cores: cores + }; + } else { + return { + min: 0, + max: 0, + avg: 0, + cores: cores + }; + } +} + +function cpuCurrentSpeed(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + let result = getCpuCurrentSpeedSync(); + if (result.avg === 0 && _cpu_speed !== 0) { + const currCpuSpeed = parseFloat(_cpu_speed); + result = { + min: currCpuSpeed, + max: currCpuSpeed, + avg: currCpuSpeed, + cores: [] + }; + } + if (callback) { callback(result); } + resolve(result); + }); + }); +} + +exports.cpuCurrentSpeed = cpuCurrentSpeed; + +// -------------------------- +// CPU - temperature +// if sensors are installed + +function cpuTemperature(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + let result = { + main: null, + cores: [], + max: null, + socket: [], + chipset: null + }; + if (_linux) { + // CPU Chipset, Socket + try { + const cmd = 'cat /sys/class/thermal/thermal_zone*/type 2>/dev/null; echo "-----"; cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null;'; + const parts = execSync(cmd).toString().split('-----\n'); + if (parts.length === 2) { + const lines = parts[0].split('\n'); + const lines2 = parts[1].split('\n'); + for (let i = 0; i < lines.length; i++) { + const line = lines[i].trim(); + if (line.startsWith('acpi') && lines2[i]) { + result.socket.push(Math.round(parseInt(lines2[i], 10) / 100) / 10); + } + if (line.startsWith('pch') && lines2[i]) { + result.chipset = Math.round(parseInt(lines2[i], 10) / 100) / 10; + } + } + } + } catch (e) { + util.noop(); + } + + const cmd = 'for mon in /sys/class/hwmon/hwmon*; do for label in "$mon"/temp*_label; do if [ -f $label ]; then value=${label%_*}_input; echo $(cat "$label")___$(cat "$value"); fi; done; done;'; + try { + exec(cmd, function (error, stdout) { + stdout = stdout.toString(); + const tdiePos = stdout.toLowerCase().indexOf('tdie'); + if (tdiePos !== -1) { + stdout = stdout.substring(tdiePos); + } + let lines = stdout.split('\n'); + lines.forEach(line => { + const parts = line.split('___'); + const label = parts[0]; + const value = parts.length > 1 && parts[1] ? parts[1] : '0'; + if (value && (label === undefined || (label && label.toLowerCase().startsWith('core')))) { + result.cores.push(Math.round(parseInt(value, 10) / 100) / 10); + } else if (value && label && result.main === null) { + result.main = Math.round(parseInt(value, 10) / 100) / 10; + } + }); + + if (result.cores.length > 0) { + result.main = Math.round(result.cores.reduce((a, b) => a + b, 0) / result.cores.length); + let maxtmp = Math.max.apply(Math, result.cores); + result.max = (maxtmp > result.main) ? maxtmp : result.main; + } + if (result.main !== null) { + if (result.max === null) { + result.max = result.main; + } + if (callback) { callback(result); } + resolve(result); + return; + } + exec('sensors', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + let tdieTemp = null; + let newSectionStarts = true; + let section = ''; + lines.forEach(function (line) { + // determine section + if (line.trim() === '') { + newSectionStarts = true; + } else if (newSectionStarts) { + if (line.trim().toLowerCase().startsWith('acpi')) { section = 'acpi'; } + if (line.trim().toLowerCase().startsWith('pch')) { section = 'pch'; } + if (line.trim().toLowerCase().startsWith('core')) { section = 'core'; } + newSectionStarts = false; + } + let regex = /[+-]([^°]*)/g; + let temps = line.match(regex); + let firstPart = line.split(':')[0].toUpperCase(); + if (section === 'acpi') { + // socket temp + if (firstPart.indexOf('TEMP') !== -1) { + result.socket.push(parseFloat(temps)); + } + } else if (section === 'pch') { + // chipset temp + if (firstPart.indexOf('TEMP') !== -1) { + result.chipset = parseFloat(temps); + } + } + // cpu temp + if (firstPart.indexOf('PHYSICAL') !== -1 || firstPart.indexOf('PACKAGE') !== -1) { + result.main = parseFloat(temps); + } + if (firstPart.indexOf('CORE ') !== -1) { + result.cores.push(parseFloat(temps)); + } + if (firstPart.indexOf('TDIE') !== -1 && tdieTemp === null) { + tdieTemp = parseFloat(temps); + } + }); + if (result.cores.length > 0) { + result.main = Math.round(result.cores.reduce((a, b) => a + b, 0) / result.cores.length); + let maxtmp = Math.max.apply(Math, result.cores); + result.max = (maxtmp > result.main) ? maxtmp : result.main; + } else { + if (result.main === null && tdieTemp !== null) { + result.main = tdieTemp; + result.max = tdieTemp; + } + } + if (result.main !== null || result.max !== null) { + if (callback) { callback(result); } + resolve(result); + return; + } + } + fs.stat('/sys/class/thermal/thermal_zone0/temp', function (err) { + if (err === null) { + fs.readFile('/sys/class/thermal/thermal_zone0/temp', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + if (lines.length > 0) { + result.main = parseFloat(lines[0]) / 1000.0; + result.max = result.main; + } + } + if (callback) { callback(result); } + resolve(result); + }); + } else { + exec('/opt/vc/bin/vcgencmd measure_temp', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + if (lines.length > 0 && lines[0].indexOf('=')) { + result.main = parseFloat(lines[0].split('=')[1]); + result.max = result.main; + } + } + if (callback) { callback(result); } + resolve(result); + }); + } + }); + }); + }); + } catch (er) { + if (callback) { callback(result); } + resolve(result); + } + } + if (_freebsd || _openbsd || _netbsd) { + exec('sysctl dev.cpu | grep temp', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + let sum = 0; + lines.forEach(function (line) { + const parts = line.split(':'); + if (parts.length > 1) { + const temp = parseFloat(parts[1].replace(',', '.')); + if (temp > result.max) { result.max = temp; } + sum = sum + temp; + result.cores.push(temp); + } + }); + if (result.cores.length) { + result.main = Math.round(sum / result.cores.length * 100) / 100; + } + } + if (callback) { callback(result); } + resolve(result); + }); + } + if (_darwin) { + let osxTemp = null; + try { + osxTemp = require('osx-temperature-sensor'); + } catch (er) { + osxTemp = null; + } + if (osxTemp) { + result = osxTemp.cpuTemperature(); + // round to 2 digits + if (result.main) { + result.main = Math.round(result.main * 100) / 100; + } + if (result.max) { + result.max = Math.round(result.max * 100) / 100; + } + if (result.cores && result.cores.length) { + for (let i = 0; i < result.cores.length; i++) { + result.cores[i] = Math.round(result.cores[i] * 100) / 100; + } + } + } + + if (callback) { callback(result); } + resolve(result); + } + if (_sunos) { + if (callback) { callback(result); } + resolve(result); + } + if (_windows) { + try { + util.powerShell('Get-WmiObject MSAcpi_ThermalZoneTemperature -Namespace "root/wmi" | Select CurrentTemperature').then((stdout, error) => { + if (!error) { + let sum = 0; + let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0); + lines.forEach(function (line) { + let value = (parseInt(line, 10) - 2732) / 10; + if (!isNaN(value)) { + sum = sum + value; + if (value > result.max) { result.max = value; } + result.cores.push(value); + } + }); + if (result.cores.length) { + result.main = sum / result.cores.length; + } + } + if (callback) { callback(result); } + resolve(result); + }); + } catch (e) { + if (callback) { callback(result); } + resolve(result); + } + } + }); + }); +} + +exports.cpuTemperature = cpuTemperature; + +// -------------------------- +// CPU Flags + +function cpuFlags(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + let result = ''; + if (_windows) { + try { + exec('reg query "HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" /v FeatureSet', util.execOptsWin, function (error, stdout) { + if (!error) { + let flag_hex = stdout.split('0x').pop().trim(); + let flag_bin_unpadded = parseInt(flag_hex, 16).toString(2); + let flag_bin = '0'.repeat(32 - flag_bin_unpadded.length) + flag_bin_unpadded; + // empty flags are the reserved fields in the CPUID feature bit list + // as found on wikipedia: + // https://en.wikipedia.org/wiki/CPUID + let all_flags = [ + 'fpu', 'vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce', 'cx8', 'apic', + '', 'sep', 'mtrr', 'pge', 'mca', 'cmov', 'pat', 'pse-36', 'psn', 'clfsh', + '', 'ds', 'acpi', 'mmx', 'fxsr', 'sse', 'sse2', 'ss', 'htt', 'tm', 'ia64', 'pbe' + ]; + for (let f = 0; f < all_flags.length; f++) { + if (flag_bin[f] === '1' && all_flags[f] !== '') { + result += ' ' + all_flags[f]; + } + } + result = result.trim().toLowerCase(); + } + if (callback) { callback(result); } + resolve(result); + }); + } catch (e) { + if (callback) { callback(result); } + resolve(result); + } + } + if (_linux) { + try { + + exec('export LC_ALL=C; lscpu; unset LC_ALL', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + lines.forEach(function (line) { + if (line.split(':')[0].toUpperCase().indexOf('FLAGS') !== -1) { + result = line.split(':')[1].trim().toLowerCase(); + } + }); + } + if (!result) { + fs.readFile('/proc/cpuinfo', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + result = util.getValue(lines, 'features', ':', true).toLowerCase(); + } + if (callback) { callback(result); } + resolve(result); + }); + } else { + if (callback) { callback(result); } + resolve(result); + } + }); + } catch (e) { + if (callback) { callback(result); } + resolve(result); + } + } + if (_freebsd || _openbsd || _netbsd) { + exec('export LC_ALL=C; dmidecode -t 4 2>/dev/null; unset LC_ALL', function (error, stdout) { + let flags = []; + if (!error) { + let parts = stdout.toString().split('\tFlags:'); + const lines = parts.length > 1 ? parts[1].split('\tVersion:')[0].split('\n') : []; + lines.forEach(function (line) { + let flag = (line.indexOf('(') ? line.split('(')[0].toLowerCase() : '').trim().replace(/\t/g, ''); + if (flag) { + flags.push(flag); + } + }); + } + result = flags.join(' ').trim().toLowerCase(); + if (callback) { callback(result); } + resolve(result); + }); + } + if (_darwin) { + exec('sysctl machdep.cpu.features', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + if (lines.length > 0 && lines[0].indexOf('machdep.cpu.features:') !== -1) { + result = lines[0].split(':')[1].trim().toLowerCase(); + } + } + if (callback) { callback(result); } + resolve(result); + }); + } + if (_sunos) { + if (callback) { callback(result); } + resolve(result); + } + }); + }); +} + +exports.cpuFlags = cpuFlags; + +// -------------------------- +// CPU Cache + +function cpuCache(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + + let result = { + l1d: null, + l1i: null, + l2: null, + l3: null, + }; + if (_linux) { + try { + exec('export LC_ALL=C; lscpu; unset LC_ALL', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + lines.forEach(function (line) { + let parts = line.split(':'); + if (parts[0].toUpperCase().indexOf('L1D CACHE') !== -1) { + result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1)); + } + if (parts[0].toUpperCase().indexOf('L1I CACHE') !== -1) { + result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1)); + } + if (parts[0].toUpperCase().indexOf('L2 CACHE') !== -1) { + result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1)); + } + if (parts[0].toUpperCase().indexOf('L3 CACHE') !== -1) { + result.l3 = parseInt(parts[1].trim()) * (parts[1].indexOf('M') !== -1 ? 1024 * 1024 : (parts[1].indexOf('K') !== -1 ? 1024 : 1)); + } + }); + } + if (callback) { callback(result); } + resolve(result); + }); + } catch (e) { + if (callback) { callback(result); } + resolve(result); + } + } + if (_freebsd || _openbsd || _netbsd) { + exec('export LC_ALL=C; dmidecode -t 7 2>/dev/null; unset LC_ALL', function (error, stdout) { + let cache = []; + if (!error) { + const data = stdout.toString(); + cache = data.split('Cache Information'); + cache.shift(); + } + for (let i = 0; i < cache.length; i++) { + const lines = cache[i].split('\n'); + let cacheType = util.getValue(lines, 'Socket Designation').toLowerCase().replace(' ', '-').split('-'); + cacheType = cacheType.length ? cacheType[0] : ''; + const sizeParts = util.getValue(lines, 'Installed Size').split(' '); + let size = parseInt(sizeParts[0], 10); + const unit = sizeParts.length > 1 ? sizeParts[1] : 'kb'; + size = size * (unit === 'kb' ? 1024 : (unit === 'mb' ? 1024 * 1024 : (unit === 'gb' ? 1024 * 1024 * 1024 : 1))); + if (cacheType) { + if (cacheType === 'l1') { + result.cache[cacheType + 'd'] = size / 2; + result.cache[cacheType + 'i'] = size / 2; + } else { + result.cache[cacheType] = size; + } + } + } + if (callback) { callback(result); } + resolve(result); + }); + } + if (_darwin) { + exec('sysctl hw.l1icachesize hw.l1dcachesize hw.l2cachesize hw.l3cachesize', function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + lines.forEach(function (line) { + let parts = line.split(':'); + if (parts[0].toLowerCase().indexOf('hw.l1icachesize') !== -1) { + result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1); + } + if (parts[0].toLowerCase().indexOf('hw.l1dcachesize') !== -1) { + result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1); + } + if (parts[0].toLowerCase().indexOf('hw.l2cachesize') !== -1) { + result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1); + } + if (parts[0].toLowerCase().indexOf('hw.l3cachesize') !== -1) { + result.l3 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1); + } + }); + } + if (callback) { callback(result); } + resolve(result); + }); + } + if (_sunos) { + if (callback) { callback(result); } + resolve(result); + } + if (_windows) { + try { + util.powerShell('Get-WmiObject Win32_processor | select L2CacheSize, L3CacheSize | fl').then((stdout, error) => { + if (!error) { + let lines = stdout.split('\r\n'); + result.l1d = 0; + result.l1i = 0; + result.l2 = util.getValue(lines, 'l2cachesize', ':'); + result.l3 = util.getValue(lines, 'l3cachesize', ':'); + if (result.l2) { result.l2 = parseInt(result.l2, 10) * 1024; } + if (result.l3) { result.l3 = parseInt(result.l3, 10) * 1024; } + } + util.powerShell('Get-WmiObject Win32_CacheMemory | select CacheType,InstalledSize,Level | fl').then((stdout, error) => { + if (!error) { + const parts = stdout.split(/\n\s*\n/); + parts.forEach(function (part) { + const lines = part.split('\r\n'); + const cacheType = util.getValue(lines, 'CacheType'); + const level = util.getValue(lines, 'Level'); + const installedSize = util.getValue(lines, 'InstalledSize'); + // L1 Instructions + if (level === '3' && cacheType === '3') { + result.l1i = parseInt(installedSize, 10); + } + // L1 Data + if (level === '3' && cacheType === '4') { + result.l1d = parseInt(installedSize, 10); + } + // L1 all + if (level === '3' && cacheType === '5' && !result.l1i && !result.l1d) { + result.l1i = parseInt(installedSize, 10) / 2; + result.l1d = parseInt(installedSize, 10) / 2; + } + }); + } + if (callback) { callback(result); } + resolve(result); + }); + }); + } catch (e) { + if (callback) { callback(result); } + resolve(result); + } + } + }); + }); +} + +exports.cpuCache = cpuCache; + +// -------------------------- +// CPU - current load - in % + +function getLoad() { + + return new Promise((resolve) => { + process.nextTick(() => { + let loads = os.loadavg().map(function (x) { return x / util.cores(); }); + let avgLoad = parseFloat((Math.max.apply(Math, loads)).toFixed(2)); + let result = {}; + + let now = Date.now() - _current_cpu.ms; + if (now >= 200) { + _current_cpu.ms = Date.now(); + const cpus = os.cpus(); + let totalUser = 0; + let totalSystem = 0; + let totalNice = 0; + let totalIrq = 0; + let totalIdle = 0; + let cores = []; + _corecount = (cpus && cpus.length) ? cpus.length : 0; + + for (let i = 0; i < _corecount; i++) { + const cpu = cpus[i].times; + totalUser += cpu.user; + totalSystem += cpu.sys; + totalNice += cpu.nice; + totalIdle += cpu.idle; + totalIrq += cpu.irq; + let tmpTick = (_cpus && _cpus[i] && _cpus[i].totalTick ? _cpus[i].totalTick : 0); + let tmpLoad = (_cpus && _cpus[i] && _cpus[i].totalLoad ? _cpus[i].totalLoad : 0); + let tmpUser = (_cpus && _cpus[i] && _cpus[i].user ? _cpus[i].user : 0); + let tmpSystem = (_cpus && _cpus[i] && _cpus[i].sys ? _cpus[i].sys : 0); + let tmpNice = (_cpus && _cpus[i] && _cpus[i].nice ? _cpus[i].nice : 0); + let tmpIdle = (_cpus && _cpus[i] && _cpus[i].idle ? _cpus[i].idle : 0); + let tmpIrq = (_cpus && _cpus[i] && _cpus[i].irq ? _cpus[i].irq : 0); + _cpus[i] = cpu; + _cpus[i].totalTick = _cpus[i].user + _cpus[i].sys + _cpus[i].nice + _cpus[i].irq + _cpus[i].idle; + _cpus[i].totalLoad = _cpus[i].user + _cpus[i].sys + _cpus[i].nice + _cpus[i].irq; + _cpus[i].currentTick = _cpus[i].totalTick - tmpTick; + _cpus[i].load = (_cpus[i].totalLoad - tmpLoad); + _cpus[i].loadUser = (_cpus[i].user - tmpUser); + _cpus[i].loadSystem = (_cpus[i].sys - tmpSystem); + _cpus[i].loadNice = (_cpus[i].nice - tmpNice); + _cpus[i].loadIdle = (_cpus[i].idle - tmpIdle); + _cpus[i].loadIrq = (_cpus[i].irq - tmpIrq); + cores[i] = {}; + cores[i].load = _cpus[i].load / _cpus[i].currentTick * 100; + cores[i].loadUser = _cpus[i].loadUser / _cpus[i].currentTick * 100; + cores[i].loadSystem = _cpus[i].loadSystem / _cpus[i].currentTick * 100; + cores[i].loadNice = _cpus[i].loadNice / _cpus[i].currentTick * 100; + cores[i].loadIdle = _cpus[i].loadIdle / _cpus[i].currentTick * 100; + cores[i].loadIrq = _cpus[i].loadIrq / _cpus[i].currentTick * 100; + cores[i].rawLoad = _cpus[i].load; + cores[i].rawLoadUser = _cpus[i].loadUser; + cores[i].rawLoadSystem = _cpus[i].loadSystem; + cores[i].rawLoadNice = _cpus[i].loadNice; + cores[i].rawLoadIdle = _cpus[i].loadIdle; + cores[i].rawLoadIrq = _cpus[i].loadIrq; + } + let totalTick = totalUser + totalSystem + totalNice + totalIrq + totalIdle; + let totalLoad = totalUser + totalSystem + totalNice + totalIrq; + let currentTick = totalTick - _current_cpu.tick; + result = { + avgLoad: avgLoad, + currentLoad: (totalLoad - _current_cpu.load) / currentTick * 100, + currentLoadUser: (totalUser - _current_cpu.user) / currentTick * 100, + currentLoadSystem: (totalSystem - _current_cpu.system) / currentTick * 100, + currentLoadNice: (totalNice - _current_cpu.nice) / currentTick * 100, + currentLoadIdle: (totalIdle - _current_cpu.idle) / currentTick * 100, + currentLoadIrq: (totalIrq - _current_cpu.irq) / currentTick * 100, + rawCurrentLoad: (totalLoad - _current_cpu.load), + rawCurrentLoadUser: (totalUser - _current_cpu.user), + rawCurrentLoadSystem: (totalSystem - _current_cpu.system), + rawCurrentLoadNice: (totalNice - _current_cpu.nice), + rawCurrentLoadIdle: (totalIdle - _current_cpu.idle), + rawCurrentLoadIrq: (totalIrq - _current_cpu.irq), + cpus: cores + }; + _current_cpu = { + user: totalUser, + nice: totalNice, + system: totalSystem, + idle: totalIdle, + irq: totalIrq, + tick: totalTick, + load: totalLoad, + ms: _current_cpu.ms, + currentLoad: result.currentLoad, + currentLoadUser: result.currentLoadUser, + currentLoadSystem: result.currentLoadSystem, + currentLoadNice: result.currentLoadNice, + currentLoadIdle: result.currentLoadIdle, + currentLoadIrq: result.currentLoadIrq, + rawCurrentLoad: result.rawCurrentLoad, + rawCurrentLoadUser: result.rawCurrentLoadUser, + rawCurrentLoadSystem: result.rawCurrentLoadSystem, + rawCurrentLoadNice: result.rawCurrentLoadNice, + rawCurrentLoadIdle: result.rawCurrentLoadIdle, + rawCurrentLoadIrq: result.rawCurrentLoadIrq, + }; + } else { + let cores = []; + for (let i = 0; i < _corecount; i++) { + cores[i] = {}; + cores[i].load = _cpus[i].load / _cpus[i].currentTick * 100; + cores[i].loadUser = _cpus[i].loadUser / _cpus[i].currentTick * 100; + cores[i].loadSystem = _cpus[i].loadSystem / _cpus[i].currentTick * 100; + cores[i].loadNice = _cpus[i].loadNice / _cpus[i].currentTick * 100; + cores[i].loadIdle = _cpus[i].loadIdle / _cpus[i].currentTick * 100; + cores[i].loadIrq = _cpus[i].loadIrq / _cpus[i].currentTick * 100; + cores[i].rawLoad = _cpus[i].load; + cores[i].rawLoadUser = _cpus[i].loadUser; + cores[i].rawLoadSystem = _cpus[i].loadSystem; + cores[i].rawLoadNice = _cpus[i].loadNice; + cores[i].rawLoadIdle = _cpus[i].loadIdle; + cores[i].rawLoadIrq = _cpus[i].loadIrq; + } + result = { + avgLoad: avgLoad, + currentLoad: _current_cpu.currentLoad, + currentLoadUser: _current_cpu.currentLoadUser, + currentLoadSystem: _current_cpu.currentLoadSystem, + currentLoadNice: _current_cpu.currentLoadNice, + currentLoadIdle: _current_cpu.currentLoadIdle, + currentLoadIrq: _current_cpu.currentLoadIrq, + rawCurrentLoad: _current_cpu.rawCurrentLoad, + rawCurrentLoadUser: _current_cpu.rawCurrentLoadUser, + rawCurrentLoadSystem: _current_cpu.rawCurrentLoadSystem, + rawCurrentLoadNice: _current_cpu.rawCurrentLoadNice, + rawCurrentLoadIdle: _current_cpu.rawCurrentLoadIdle, + rawCurrentLoadIrq: _current_cpu.rawCurrentLoadIrq, + cpus: cores + }; + } + resolve(result); + }); + }); +} + +function currentLoad(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + getLoad().then(result => { + if (callback) { callback(result); } + resolve(result); + }); + }); + }); +} + +exports.currentLoad = currentLoad; + +// -------------------------- +// PS - full load +// since bootup + +function getFullLoad() { + + return new Promise((resolve) => { + process.nextTick(() => { + + const cpus = os.cpus(); + let totalUser = 0; + let totalSystem = 0; + let totalNice = 0; + let totalIrq = 0; + let totalIdle = 0; + + let result = 0; + + if (cpus && cpus.length) { + for (let i = 0, len = cpus.length; i < len; i++) { + const cpu = cpus[i].times; + totalUser += cpu.user; + totalSystem += cpu.sys; + totalNice += cpu.nice; + totalIrq += cpu.irq; + totalIdle += cpu.idle; + } + let totalTicks = totalIdle + totalIrq + totalNice + totalSystem + totalUser; + result = (totalTicks - totalIdle) / totalTicks * 100.0; + + } + resolve(result); + }); + }); +} + +function fullLoad(callback) { + + return new Promise((resolve) => { + process.nextTick(() => { + getFullLoad().then(result => { + if (callback) { callback(result); } + resolve(result); + }); + }); + }); +} + +exports.fullLoad = fullLoad; |