/**
* Oshi (https://github.com/oshi/oshi)
*
* Copyright (c) 2010 - 2017 The Oshi Project Team
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Maintainers:
* dblock[at]dblock[dot]org
* widdis[at]gmail[dot]com
* enrico.bianchi[at]gmail[dot]com
*
* Contributors:
* https://github.com/oshi/oshi/graphs/contributors
*/
package oshi.hardware.platform.unix.solaris;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.hardware.common.AbstractCentralProcessor;
import oshi.jna.platform.linux.Libc;
import oshi.jna.platform.unix.solaris.LibKstat.Kstat;
import oshi.util.ExecutingCommand;
import oshi.util.ParseUtil;
import oshi.util.platform.unix.solaris.KstatUtil;
/**
* A CPU
*
* @author widdis[at]gmail[dot]com
*/
public class SolarisCentralProcessor extends AbstractCentralProcessor {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(SolarisCentralProcessor.class);
private static final Pattern PSRINFO = Pattern.compile(".*physical processor has (\\d+) virtual processors.*");
/**
* Create a Processor
*/
public SolarisCentralProcessor() {
super();
// Initialize class variables
initVars();
// Initialize tick arrays
initTicks();
LOG.debug("Initialized Processor");
}
private void initVars() {
// Get first result
Kstat ksp = KstatUtil.kstatLookup("cpu_info", -1, null);
// Set values
if (ksp != null && KstatUtil.kstatRead(ksp)) {
setVendor(KstatUtil.kstatDataLookupString(ksp, "vendor_id"));
setName(KstatUtil.kstatDataLookupString(ksp, "brand"));
setStepping(KstatUtil.kstatDataLookupString(ksp, "stepping"));
setModel(KstatUtil.kstatDataLookupString(ksp, "model"));
setFamily(KstatUtil.kstatDataLookupString(ksp, "family"));
}
setCpu64("64".equals(ExecutingCommand.getFirstAnswer("isainfo -b").trim()));
setProcessorID(getProcessorID(getStepping(), getModel(), getFamily()));
}
/**
* Updates logical and physical processor counts from psrinfo
*/
@Override
protected void calculateProcessorCounts() {
this.logicalProcessorCount = 0;
this.physicalProcessorCount = 0;
// Get number of logical processors
for (String cpu : ExecutingCommand.runNative("psrinfo -pv")) {
Matcher m = PSRINFO.matcher(cpu.trim());
if (m.matches()) {
this.physicalProcessorCount++;
this.logicalProcessorCount += ParseUtil.parseIntOrDefault(m.group(1), 0);
}
}
if (this.logicalProcessorCount < 1) {
LOG.error("Couldn't find logical processor count. Assuming 1.");
this.logicalProcessorCount = 1;
}
if (this.physicalProcessorCount < 1) {
LOG.error("Couldn't find physical processor count. Assuming 1.");
this.physicalProcessorCount = 1;
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized long[] getSystemCpuLoadTicks() {
long[] ticks = new long[TickType.values().length];
// Average processor ticks
long[][] procTicks = getProcessorCpuLoadTicks();
for (int i = 0; i < ticks.length; i++) {
for (long[] procTick : procTicks) {
ticks[i] += procTick[i];
}
ticks[i] /= procTicks.length;
}
return ticks;
}
/**
* {@inheritDoc}
*/
@Override
public double[] getSystemLoadAverage(int nelem) {
if (nelem < 1 || nelem > 3) {
throw new IllegalArgumentException("Must include from one to three elements.");
}
double[] average = new double[nelem];
int retval = Libc.INSTANCE.getloadavg(average, nelem);
if (retval < nelem) {
for (int i = Math.max(retval, 0); i < average.length; i++) {
average[i] = -1d;
}
}
return average;
}
/**
* {@inheritDoc}
*/
@Override
public long[][] getProcessorCpuLoadTicks() {
long[][] ticks = new long[this.logicalProcessorCount][TickType.values().length];
int cpu = -1;
for (Kstat ksp : KstatUtil.kstatLookupAll("cpu", -1, "sys")) {
// This is a new CPU
if (++cpu >= ticks.length) {
// Shouldn't happen
break;
}
if (KstatUtil.kstatRead(ksp)) {
ticks[cpu][TickType.IDLE.getIndex()] = KstatUtil.kstatDataLookupLong(ksp, "cpu_ticks_idle");
ticks[cpu][TickType.SYSTEM.getIndex()] = KstatUtil.kstatDataLookupLong(ksp, "cpu_ticks_kernel");
ticks[cpu][TickType.USER.getIndex()] = KstatUtil.kstatDataLookupLong(ksp, "cpu_ticks_user");
}
}
return ticks;
}
/**
* {@inheritDoc}
*/
@Override
public long getSystemUptime() {
Kstat ksp = KstatUtil.kstatLookup("unix", 0, "system_misc");
if (ksp == null) {
return 0L;
}
// Snap Time is in nanoseconds; divide for seconds
return ksp.ks_snaptime / 1000000000L;
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public String getSystemSerialNumber() {
return new SolarisComputerSystem().getSerialNumber();
}
/**
* Fetches the ProcessorID by encoding the stepping, model, family, and
* feature flags.
*
* @param stepping
* @param model
* @param family
* @return The Processor ID string
*/
private String getProcessorID(String stepping, String model, String family) {
List<String> isainfo = ExecutingCommand.runNative("isainfo -v");
StringBuilder flags = new StringBuilder();
for (String line : isainfo) {
if (line.startsWith("64-bit")) {
continue;
} else if (line.startsWith("32-bit")) {
break;
}
flags.append(' ').append(line.trim());
}
return createProcessorID(stepping, model, family, flags.toString().toLowerCase().split("\\s+"));
}
}