diff --git a/src/one/nio/os/Cpus.java b/src/one/nio/os/Cpus.java index 19c9e726..6455a8dc 100644 --- a/src/one/nio/os/Cpus.java +++ b/src/one/nio/os/Cpus.java @@ -16,41 +16,43 @@ package one.nio.os; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; +import one.nio.util.Utf8; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import one.nio.util.Utf8; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.BitSet; public class Cpus { private static final Log log = LogFactory.getLog(Cpus.class); - public static final int ONLINE = cpus("/sys/devices/system/cpu/online"); - public static final int POSSIBLE = cpus("/sys/devices/system/cpu/possible"); - public static final int PRESENT = cpus("/sys/devices/system/cpu/present"); - - private static int cpus(String rangeFile) { + public static final BitSet ONLINE = cpus("/sys/devices/system/cpu/online"); + public static final BitSet PRESENT = cpus("/sys/devices/system/cpu/present"); + public static final BitSet POSSIBLE = cpus("/sys/devices/system/cpu/possible"); + public static final int COUNT = POSSIBLE.cardinality(); + + private static BitSet cpus(String rangeFile) { try { byte[] bytes = Files.readAllBytes(Paths.get(rangeFile)); String rangeStr = Utf8.read(bytes, 0, bytes.length).trim(); - int cpus = 0; + BitSet cpus = new BitSet(); for (String range : rangeStr.split(",")) { String[] s = range.split("-"); - if (s.length == 1) { - cpus++; - } else { - cpus += 1 + Integer.parseInt(s[1]) - Integer.parseInt(s[0]); - } + int from = Integer.parseInt(s[0]); + int to = s.length == 1 ? from : Integer.parseInt(s[1]); + cpus.set(from, to); } return cpus; } catch (IOException e) { if (log.isDebugEnabled()) { log.debug("Failed to read " + rangeFile, e); } - return Runtime.getRuntime().availableProcessors(); + BitSet cpus = new BitSet(); + cpus.set(0, Runtime.getRuntime().availableProcessors()); + return cpus; } } } diff --git a/src/one/nio/os/bpf/BpfMap.java b/src/one/nio/os/bpf/BpfMap.java index c29632fe..23c15c63 100644 --- a/src/one/nio/os/bpf/BpfMap.java +++ b/src/one/nio/os/bpf/BpfMap.java @@ -28,7 +28,7 @@ import java.util.NoSuchElementException; public class BpfMap extends BpfObj implements Closeable { - public static final int CPUS = Cpus.POSSIBLE; + public static final int CPUS = Cpus.COUNT; public static final int ARRAY_KEY_SIZE = 4; public final MapType type; diff --git a/src/one/nio/os/native/perf.c b/src/one/nio/os/native/perf.c index 9a18d8d9..2eda59c4 100644 --- a/src/one/nio/os/native/perf.c +++ b/src/one/nio/os/native/perf.c @@ -111,10 +111,6 @@ Java_one_nio_os_perf_Perf_openEvent(JNIEnv* env, jclass cls, jint pid, jint cpu, attr.config = config; } - if (type == PERF_TYPE_SOFTWARE) { - attr.precise_ip = 2; - } - unsigned long flags = parse_perf_options(env, options, &attr); int fd = syscall(__NR_perf_event_open, &attr, pid, cpu, group, flags); @@ -180,5 +176,7 @@ Java_one_nio_os_perf_Perf_getValue(JNIEnv* env, jclass cls, jint fd, jlongArray JNIEXPORT void JNICALL Java_one_nio_os_perf_Perf_ioctl(JNIEnv* env, jclass cls, jint fd, jint cmd, jint arg) { - ioctl(fd, ioctl_cmd[cmd], arg); + if (ioctl(fd, ioctl_cmd[cmd], arg) < 0) { + throw_io_exception(env); + } } diff --git a/src/one/nio/os/perf/LocalValue.java b/src/one/nio/os/perf/LocalValue.java index d250fbf1..6a93e081 100644 --- a/src/one/nio/os/perf/LocalValue.java +++ b/src/one/nio/os/perf/LocalValue.java @@ -17,6 +17,8 @@ package one.nio.os.perf; public class LocalValue implements CounterValue { + public static final LocalValue ZERO = new LocalValue(0, 0, 0); + public final long value; public final long running; public final long enabled; diff --git a/src/one/nio/os/perf/Perf.java b/src/one/nio/os/perf/Perf.java index 58236597..0bd2d719 100644 --- a/src/one/nio/os/perf/Perf.java +++ b/src/one/nio/os/perf/Perf.java @@ -58,13 +58,15 @@ public static PerfCounter open(PerfEvent event, String cgroup, int cpu, PerfOpti public static PerfCounterGlobal openGlobal(PerfEvent event, int pid, PerfOption... options) throws IOException { String optionString = optionString(options); - int[] fds = new int[Cpus.PRESENT]; + int[] fds = new int[Cpus.COUNT]; PerfOptionGlobalGroup group = (PerfOptionGlobalGroup) option(options, PerfOption.GROUP_GLOBAL); try { for (int cpu = 0; cpu < fds.length; cpu++) { - int groupFd = group == null ? -1 : group.fds[cpu]; - fds[cpu] = openEvent(pid, cpu, event.type, event.config, event.breakpoint, groupFd, optionString); + if (Cpus.ONLINE.get(cpu)) { + int groupFd = group == null ? -1 : group.fds[cpu]; + fds[cpu] = openEvent(pid, cpu, event.type, event.config, event.breakpoint, groupFd, optionString); + } } } catch (Throwable e) { for (int fd : fds) { diff --git a/src/one/nio/os/perf/PerfCounterGlobal.java b/src/one/nio/os/perf/PerfCounterGlobal.java index 70039fea..dec434d1 100644 --- a/src/one/nio/os/perf/PerfCounterGlobal.java +++ b/src/one/nio/os/perf/PerfCounterGlobal.java @@ -35,7 +35,9 @@ public void close() { for (int i = 0; i < fds.length; i++) { int fd = fds[i]; fds[i] = -1; - Perf.close(fd); + if (fd > 0) { + Perf.close(fd); + } } } } @@ -44,7 +46,9 @@ public void close() { public long get() throws IOException { long sum = 0; for (int fd : fds) { - sum += Perf.get(fd); + if (fd > 0) { + sum += Perf.get(fd); + } } return sum; } @@ -54,18 +58,25 @@ public CounterValue getValue() throws IOException { int vals = hasReadFormat(ReadFormat.TOTAL_TIME_RUNNING | ReadFormat.TOTAL_TIME_ENABLED) ? 3 : 1; long[] buf = new long[3 * fds.length]; for (int cpu = 0; cpu < fds.length; cpu++) { - Perf.getValue(fds[cpu], buf, cpu * 3, vals); + int fd = fds[cpu]; + if (fd > 0) { + Perf.getValue(fd, buf, cpu * 3, vals); + } } return new GlobalValue(buf); } public long getForCpu(int cpu) throws IOException { - return Perf.get(fds[cpu]); + int fd = fds[cpu]; + return fd > 0 ? Perf.get(fd) : 0; } public LocalValue getValueForCpu(int cpu) throws IOException { + int fd = fds[cpu]; + if (fd <= 0) return LocalValue.ZERO; + long[] buf = newBuffer(); - Perf.getValue(fds[cpu], buf, 0, buf.length); + Perf.getValue(fd, buf, 0, buf.length); return toValue(buf); } @@ -74,9 +85,11 @@ protected long[] getRawValue() throws IOException { long[] buf = newBuffer(); long[] total = newBuffer(); for (int fd : fds) { - Perf.getValue(fd, buf, 0, buf.length); - for (int i = 0; i < buf.length; i++) { - total[i] += buf[i]; + if (fd > 0) { + Perf.getValue(fd, buf, 0, buf.length); + for (int i = 0; i < buf.length; i++) { + total[i] += buf[i]; + } } } return total; @@ -85,7 +98,9 @@ protected long[] getRawValue() throws IOException { @Override void ioctl(int cmd, int arg) throws IOException { for (int fd : fds) { - Perf.ioctl(fd, cmd, arg); + if (fd > 0) { + Perf.ioctl(fd, cmd, arg); + } } } @@ -101,6 +116,9 @@ public void storeTo(BpfMap map, int cpu) throws IOException { throw new IllegalArgumentException(); } - map.put(BpfMap.bytes(cpu), BpfMap.bytes(fds[cpu])); + int fd = fds[cpu]; + if (fd > 0) { + map.put(BpfMap.bytes(cpu), BpfMap.bytes(fd)); + } } }