diff --git a/cpu/src/main/java/io/smallrye/common/cpu/CacheInfo.java b/cpu/src/main/java/io/smallrye/common/cpu/CacheInfo.java index a6e1760..a5da8ac 100644 --- a/cpu/src/main/java/io/smallrye/common/cpu/CacheInfo.java +++ b/cpu/src/main/java/io/smallrye/common/cpu/CacheInfo.java @@ -78,84 +78,95 @@ public static int getSmallestInstructionCacheLineSize() { } static { - cacheLevels = doPrivileged((PrivilegedAction) () -> { - try { - String osArch = System.getProperty("os.name", "unknown").toLowerCase(Locale.US); - if (osArch.contains("linux")) { - // try to read /sys fs - final File cpu0 = new File("/sys/devices/system/cpu/cpu0/cache"); - if (cpu0.exists()) { - // great! - final File[] files = cpu0.listFiles(); - if (files != null) { - ArrayList indexes = new ArrayList(); - for (File file : files) { - if (file.getName().startsWith("index")) { - indexes.add(file); + cacheLevels = doPrivileged(new PrivilegedAction<>() { + @Override + public CacheLevelInfo[] run() { + if (determineCacheLevel()) { + try { + String osArch = System.getProperty("os.name", "unknown").toLowerCase(Locale.US); + if (osArch.contains("linux")) { + // try to read /sys fs + final File cpu0 = new File("/sys/devices/system/cpu/cpu0/cache"); + if (cpu0.exists()) { + // great! + final File[] files = cpu0.listFiles(); + if (files != null) { + ArrayList indexes = new ArrayList(); + for (File file : files) { + if (file.getName().startsWith("index")) { + indexes.add(file); + } + } + final CacheLevelInfo[] levelInfoArray = new CacheLevelInfo[indexes.size()]; + for (int i = 0; i < indexes.size(); i++) { + File file = indexes.get(i); + int index = parseIntFile(new File(file, "level")); + final CacheType type; + switch (parseStringFile(new File(file, "type"))) { + case "Data": + type = CacheType.DATA; + break; + case "Instruction": + type = CacheType.INSTRUCTION; + break; + case "Unified": + type = CacheType.UNIFIED; + break; + default: + type = CacheType.UNKNOWN; + break; + } + int size = parseIntKBFile(new File(file, "size")); + int lineSize = parseIntFile(new File(file, "coherency_line_size")); + levelInfoArray[i] = new CacheLevelInfo(index, type, size, lineSize); + } + return levelInfoArray; } } - final CacheLevelInfo[] levelInfoArray = new CacheLevelInfo[indexes.size()]; - for (int i = 0; i < indexes.size(); i++) { - File file = indexes.get(i); - int index = parseIntFile(new File(file, "level")); - final CacheType type; - switch (parseStringFile(new File(file, "type"))) { - case "Data": - type = CacheType.DATA; - break; - case "Instruction": - type = CacheType.INSTRUCTION; - break; - case "Unified": - type = CacheType.UNIFIED; - break; - default: - type = CacheType.UNKNOWN; - break; + } else if (osArch.contains("mac os x")) { + // cache line size + final int lineSize = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.cachelinesize")); + if (lineSize != 0) { + // cache sizes + final int l1d = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l1dcachesize")); + final int l1i = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l1icachesize")); + final int l2 = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l2cachesize")); + final int l3 = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l3cachesize")); + ArrayList list = new ArrayList(); + if (l1d != 0) { + list.add(new CacheLevelInfo(1, CacheType.DATA, l1d / 1024, lineSize)); + } + if (l1i != 0) { + list.add(new CacheLevelInfo(1, CacheType.INSTRUCTION, l1i / 1024, lineSize)); + } + if (l2 != 0) { + list.add(new CacheLevelInfo(2, CacheType.UNIFIED, l2 / 1024, lineSize)); + } + if (l3 != 0) { + list.add(new CacheLevelInfo(3, CacheType.UNIFIED, l3 / 1024, lineSize)); + } + if (list.size() > 0) { + return list.toArray(new CacheLevelInfo[list.size()]); } - int size = parseIntKBFile(new File(file, "size")); - int lineSize = parseIntFile(new File(file, "coherency_line_size")); - levelInfoArray[i] = new CacheLevelInfo(index, type, size, lineSize); } - return levelInfoArray; + } else if (osArch.contains("windows")) { + // TODO: use the wmic utility to get cache line info } + } catch (Throwable ignored) { } - } else if (osArch.contains("mac os x")) { - // cache line size - final int lineSize = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.cachelinesize")); - if (lineSize != 0) { - // cache sizes - final int l1d = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l1dcachesize")); - final int l1i = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l1icachesize")); - final int l2 = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l2cachesize")); - final int l3 = safeParseInt(parseProcessOutput("/usr/sbin/sysctl", "-n", "hw.l3cachesize")); - ArrayList list = new ArrayList(); - if (l1d != 0) { - list.add(new CacheLevelInfo(1, CacheType.DATA, l1d / 1024, lineSize)); - } - if (l1i != 0) { - list.add(new CacheLevelInfo(1, CacheType.INSTRUCTION, l1i / 1024, lineSize)); - } - if (l2 != 0) { - list.add(new CacheLevelInfo(2, CacheType.UNIFIED, l2 / 1024, lineSize)); - } - if (l3 != 0) { - list.add(new CacheLevelInfo(3, CacheType.UNIFIED, l3 / 1024, lineSize)); - } - if (list.size() > 0) { - return list.toArray(new CacheLevelInfo[list.size()]); - } - } - } else if (osArch.contains("windows")) { - // TODO: use the wmic utility to get cache line info + // all has failed + return new CacheLevelInfo[0]; + } else { + return new CacheLevelInfo[] { new CacheLevelInfo(0, CacheType.UNKNOWN, 0, 64) }; } - } catch (Throwable ignored) { } - // all has failed - return new CacheLevelInfo[0]; }); } + private static boolean determineCacheLevel() { + return Boolean.parseBoolean(System.getProperty("smallrye.cpu.determine-cache-level", "false")); + } + static int parseIntFile(final File file) { return safeParseInt(parseStringFile(file)); } @@ -278,4 +289,4 @@ public static void main(String[] args) { Integer.valueOf(levelInfo.getCacheLineSize())); } } -} \ No newline at end of file +}