oshi.hardware.platform.windows.WindowsCentralProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of driver-cql-shaded Show documentation
Show all versions of driver-cql-shaded Show documentation
A Shaded CQL ActivityType driver for http://nosqlbench.io/
/**
* MIT License
*
* Copyright (c) 2010 - 2020 The OSHI Project Contributors: https://github.com/oshi/oshi/graphs/contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package oshi.hardware.platform.windows;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.Memory; // NOSONAR squid:S1191
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.PowrProf.POWER_INFORMATION_LEVEL;
import com.sun.jna.platform.win32.VersionHelpers;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;
import com.sun.jna.platform.win32.WinReg;
import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiResult;
import oshi.annotation.concurrent.ThreadSafe;
import oshi.driver.windows.LogicalProcessorInformation;
import oshi.driver.windows.perfmon.ProcessorInformation;
import oshi.driver.windows.perfmon.ProcessorInformation.InterruptsProperty;
import oshi.driver.windows.perfmon.ProcessorInformation.ProcessorFrequencyProperty;
import oshi.driver.windows.perfmon.ProcessorInformation.ProcessorTickCountProperty;
import oshi.driver.windows.perfmon.ProcessorInformation.SystemTickCountProperty;
import oshi.driver.windows.perfmon.SystemInformation;
import oshi.driver.windows.perfmon.SystemInformation.ContextSwitchProperty;
import oshi.driver.windows.wmi.Win32Processor;
import oshi.driver.windows.wmi.Win32Processor.ProcessorIdProperty;
import oshi.hardware.common.AbstractCentralProcessor;
import oshi.jna.platform.windows.PowrProf;
import oshi.jna.platform.windows.PowrProf.ProcessorPowerInformation;
import oshi.util.ParseUtil;
import oshi.util.platform.windows.WmiUtil;
import oshi.util.tuples.Pair;
/**
* A CPU, representing all of a system's processors. It may contain multiple
* individual Physical and Logical processors.
*/
@ThreadSafe
final class WindowsCentralProcessor extends AbstractCentralProcessor {
private static final Logger LOG = LoggerFactory.getLogger(WindowsCentralProcessor.class);
// populated by initProcessorCounts called by the parent constructor
private Map numaNodeProcToLogicalProcMap;
/**
* Initializes Class variables
*/
@Override
protected ProcessorIdentifier queryProcessorId() {
String cpuVendor = "";
String cpuName = "";
String cpuIdentifier = "";
String cpuFamily = "";
String cpuModel = "";
String cpuStepping = "";
String processorID;
boolean cpu64bit = false;
final String cpuRegistryRoot = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\";
String[] processorIds = Advapi32Util.registryGetKeys(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryRoot);
if (processorIds.length > 0) {
String cpuRegistryPath = cpuRegistryRoot + processorIds[0];
cpuVendor = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryPath,
"VendorIdentifier");
cpuName = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryPath,
"ProcessorNameString");
cpuIdentifier = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, cpuRegistryPath,
"Identifier");
}
if (!cpuIdentifier.isEmpty()) {
cpuFamily = parseIdentifier(cpuIdentifier, "Family");
cpuModel = parseIdentifier(cpuIdentifier, "Model");
cpuStepping = parseIdentifier(cpuIdentifier, "Stepping");
}
SYSTEM_INFO sysinfo = new SYSTEM_INFO();
Kernel32.INSTANCE.GetNativeSystemInfo(sysinfo);
int processorArchitecture = sysinfo.processorArchitecture.pi.wProcessorArchitecture.intValue();
if (processorArchitecture == 9 // PROCESSOR_ARCHITECTURE_AMD64
|| processorArchitecture == 12 // PROCESSOR_ARCHITECTURE_ARM64
|| processorArchitecture == 6) { // PROCESSOR_ARCHITECTURE_IA64
cpu64bit = true;
}
WmiResult processorId = Win32Processor.queryProcessorId();
if (processorId.getResultCount() > 0) {
processorID = WmiUtil.getString(processorId, ProcessorIdProperty.PROCESSORID, 0);
} else {
processorID = createProcessorID(cpuStepping, cpuModel, cpuFamily,
cpu64bit ? new String[] { "ia64" } : new String[0]);
}
return new ProcessorIdentifier(cpuVendor, cpuName, cpuFamily, cpuModel, cpuStepping, processorID, cpu64bit);
}
/**
* Parses identifier string
*
* @param identifier
* the full identifier string
* @param key
* the key to retrieve
* @return the string following id
*/
private static String parseIdentifier(String identifier, String key) {
String[] idSplit = ParseUtil.whitespaces.split(identifier);
boolean found = false;
for (String s : idSplit) {
// If key string found, return next value
if (found) {
return s;
}
found = s.equals(key);
}
// If key string not found, return empty string
return "";
}
@Override
protected List initProcessorCounts() {
if (VersionHelpers.IsWindows7OrGreater()) {
List logProcs = LogicalProcessorInformation.getLogicalProcessorInformationEx();
// Save numaNode,Processor lookup for future PerfCounter instance lookup
this.numaNodeProcToLogicalProcMap = new HashMap<>();
int lp = 0;
for (LogicalProcessor logProc : logProcs) {
numaNodeProcToLogicalProcMap
.put(String.format("%d,%d", logProc.getNumaNode(), logProc.getProcessorNumber()), lp++);
}
return logProcs;
} else {
return LogicalProcessorInformation.getLogicalProcessorInformation();
}
}
@Override
public long[] querySystemCpuLoadTicks() {
long[] ticks = new long[TickType.values().length];
WinBase.FILETIME lpIdleTime = new WinBase.FILETIME();
WinBase.FILETIME lpKernelTime = new WinBase.FILETIME();
WinBase.FILETIME lpUserTime = new WinBase.FILETIME();
if (!Kernel32.INSTANCE.GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime)) {
LOG.error("Failed to update system idle/kernel/user times. Error code: {}", Native.getLastError());
return ticks;
}
// IOwait:
// Windows does not measure IOWait.
// IRQ and ticks:
// Percent time raw value is cumulative 100NS-ticks
// Divide by 10_000 to get milliseconds
Map valueMap = ProcessorInformation.querySystemCounters();
ticks[TickType.IRQ.getIndex()] = valueMap.getOrDefault(SystemTickCountProperty.PERCENTINTERRUPTTIME, 0L)
/ 10_000L;
ticks[TickType.SOFTIRQ.getIndex()] = valueMap.getOrDefault(SystemTickCountProperty.PERCENTDPCTIME, 0L)
/ 10_000L;
ticks[TickType.IDLE.getIndex()] = lpIdleTime.toDWordLong().longValue() / 10_000L;
ticks[TickType.SYSTEM.getIndex()] = lpKernelTime.toDWordLong().longValue() / 10_000L
- ticks[TickType.IDLE.getIndex()];
ticks[TickType.USER.getIndex()] = lpUserTime.toDWordLong().longValue() / 10_000L;
// Additional decrement to avoid double counting in the total array
ticks[TickType.SYSTEM.getIndex()] -= ticks[TickType.IRQ.getIndex()] + ticks[TickType.SOFTIRQ.getIndex()];
return ticks;
}
@Override
public long[] queryCurrentFreq() {
if (VersionHelpers.IsWindows7OrGreater()) {
Pair, Map>> instanceValuePair = ProcessorInformation
.queryFrequencyCounters();
List instances = instanceValuePair.getA();
Map> valueMap = instanceValuePair.getB();
List percentMaxList = valueMap.get(ProcessorFrequencyProperty.PERCENTOFMAXIMUMFREQUENCY);
if (!instances.isEmpty()) {
long maxFreq = this.getMaxFreq();
long[] freqs = new long[getLogicalProcessorCount()];
for (int p = 0; p < instances.size(); p++) {
int cpu = instances.get(p).contains(",")
? numaNodeProcToLogicalProcMap.getOrDefault(instances.get(p), 0)
: ParseUtil.parseIntOrDefault(instances.get(p), 0);
if (cpu >= getLogicalProcessorCount()) {
continue;
}
freqs[cpu] = percentMaxList.get(cpu) * maxFreq / 100L;
}
return freqs;
}
}
// If 3) {
throw new IllegalArgumentException("Must include from one to three elements.");
}
double[] average = new double[nelem];
// Windows doesn't have load average
for (int i = 0; i < average.length; i++) {
average[i] = -1;
}
return average;
}
@Override
public long[][] queryProcessorCpuLoadTicks() {
Pair, Map>> instanceValuePair = ProcessorInformation
.queryProcessorCounters();
List instances = instanceValuePair.getA();
Map> valueMap = instanceValuePair.getB();
List systemList = valueMap.get(ProcessorTickCountProperty.PERCENTPRIVILEGEDTIME);
List userList = valueMap.get(ProcessorTickCountProperty.PERCENTUSERTIME);
List irqList = valueMap.get(ProcessorTickCountProperty.PERCENTINTERRUPTTIME);
List softIrqList = valueMap.get(ProcessorTickCountProperty.PERCENTDPCTIME);
// % Processor Time is actually Idle time
List idleList = valueMap.get(ProcessorTickCountProperty.PERCENTPROCESSORTIME);
long[][] ticks = new long[getLogicalProcessorCount()][TickType.values().length];
if (instances.isEmpty() || systemList == null || userList == null || irqList == null || softIrqList == null
|| idleList == null) {
return ticks;
}
for (int p = 0; p < instances.size(); p++) {
int cpu = instances.get(p).contains(",") ? numaNodeProcToLogicalProcMap.getOrDefault(instances.get(p), 0)
: ParseUtil.parseIntOrDefault(instances.get(p), 0);
if (cpu >= getLogicalProcessorCount()) {
continue;
}
ticks[cpu][TickType.SYSTEM.getIndex()] = systemList.get(cpu);
ticks[cpu][TickType.USER.getIndex()] = userList.get(cpu);
ticks[cpu][TickType.IRQ.getIndex()] = irqList.get(cpu);
ticks[cpu][TickType.SOFTIRQ.getIndex()] = softIrqList.get(cpu);
ticks[cpu][TickType.IDLE.getIndex()] = idleList.get(cpu);
// Additional decrement to avoid double counting in the
// total array
ticks[cpu][TickType.SYSTEM.getIndex()] -= ticks[cpu][TickType.IRQ.getIndex()]
+ ticks[cpu][TickType.SOFTIRQ.getIndex()];
// Raw value is cumulative 100NS-ticks
// Divide by 10_000 to get milliseconds
ticks[cpu][TickType.SYSTEM.getIndex()] /= 10_000L;
ticks[cpu][TickType.USER.getIndex()] /= 10_000L;
ticks[cpu][TickType.IRQ.getIndex()] /= 10_000L;
ticks[cpu][TickType.SOFTIRQ.getIndex()] /= 10_000L;
ticks[cpu][TickType.IDLE.getIndex()] /= 10_000L;
}
// Skipping nice and IOWait, they'll stay 0
return ticks;
}
@Override
public long queryContextSwitches() {
return SystemInformation.queryContextSwitchCounters().getOrDefault(ContextSwitchProperty.CONTEXTSWITCHESPERSEC,
0L);
}
@Override
public long queryInterrupts() {
return ProcessorInformation.queryInterruptCounters().getOrDefault(InterruptsProperty.INTERRUPTSPERSEC, 0L);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy