diff --git a/src/main/java/com/sheepit/client/hardware/cpu/CPU.java b/src/main/java/com/sheepit/client/hardware/cpu/CPU.java index 02b00a8..7654ab7 100644 --- a/src/main/java/com/sheepit/client/hardware/cpu/CPU.java +++ b/src/main/java/com/sheepit/client/hardware/cpu/CPU.java @@ -19,12 +19,22 @@ package com.sheepit.client.hardware.cpu; +import com.sheepit.client.Log; +import com.sheepit.client.os.OS; +import com.sheepit.client.os.Windows; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + public class CPU { public static final int MIN_CORES = Runtime.getRuntime().availableProcessors() > 1 ? 2 : 1; private String name; private String model; private String family; private String arch; // 32 or 64 bits + private static final Log log = Log.getInstance(null); + private static Integer logicalCores = -1; // Store core count throughout instances public CPU() { this.name = null; @@ -50,7 +60,57 @@ public class CPU { } public int cores() { - return Runtime.getRuntime().availableProcessors(); + // If logicalCores is -1, then haven't run the core-checking script yet + // Only want to run it once since cores is called multiple times + if(logicalCores == -1) { + // Use normal method for systems other than windows, and in case script fails. + logicalCores = Runtime.getRuntime().availableProcessors(); + + if (OS.getOS() instanceof Windows) { + ProcessBuilder powershellProcess = new ProcessBuilder("powershell.exe", + "((Get-CimInstance -ClassName Win32_Processor).NumberOfLogicalProcessors | Measure-Object -Sum ).Sum"); + powershellProcess.redirectErrorStream(true); + Process process = null; + + // Initiate Process and catch any possible IO error + try { + process = powershellProcess.start(); + } catch(IOException ex) { + log.error("CPU::cores Error starting Powershell Process. Stacktrace:" + ex); + } + + if (process != null) { + + // Using try with resources. Will automatically close the BufferedReader stream + try (BufferedReader shellStdOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String shellLine; + + while ((shellLine = shellStdOut.readLine()) != null) { + // Verify output is a number, and if not print it out since it has errored + if (shellLine.matches("^[+-]?\\d+$")) { + logicalCores = Integer.parseInt(shellLine); + } + else { + log.error("CPU::cores Powershell error: " + shellLine); + } + } + + process.waitFor(); + } + catch (Exception ex) { + log.error("CPU::cores Error in Powershell Script. Stacktrace: " + ex); + } + finally { + // Destroy process to prevent memory leaks + process.destroy(); + } + } + else { + log.error("CPU::cores Error powershell process is NULL! Cannot run script."); + } + } + } + return logicalCores; } public void setName(String name_) {