Skip to content

Commit

Permalink
Merge pull request #100 from dmlloyd/smallrye
Browse files Browse the repository at this point in the history
Consolidation with SmallRye Common
  • Loading branch information
dmlloyd authored Jan 19, 2024
2 parents b174840 + e80f3d7 commit f67ce2b
Show file tree
Hide file tree
Showing 40 changed files with 516 additions and 3,414 deletions.
35 changes: 34 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<groupId>org.wildfly.common</groupId>
<artifactId>wildfly-common</artifactId>
<version>1.8.0.Final</version>
<version>2.0.0-SNAPSHOT</version>

<parent>
<groupId>org.jboss</groupId>
Expand All @@ -50,10 +50,23 @@
<properties>
<version.org.jboss.logging.jboss-logging>3.5.3.Final</version.org.jboss.logging.jboss-logging>
<version.org.jboss.logging.jboss-logging-tools>2.2.1.Final</version.org.jboss.logging.jboss-logging-tools>
<version.io.smallrye.common.smallrye-common>2.2.0</version.io.smallrye.common.smallrye-common>

<jdk.min.version>11</jdk.min.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-bom</artifactId>
<version>${version.io.smallrye.common.smallrye-common}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.graalvm.sdk</groupId>
Expand Down Expand Up @@ -88,6 +101,26 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-cpu</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-expression</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-net</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-os</artifactId>
</dependency>
<dependency>
<groupId>io.smallrye.common</groupId>
<artifactId>smallrye-common-ref</artifactId>
</dependency>
<dependency>
<!-- This dependency is just for javadoc -->
<groupId>javax.annotation</groupId>
Expand Down
226 changes: 15 additions & 211 deletions src/main/java/org/wildfly/common/cpu/CacheInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,27 @@

package org.wildfly.common.cpu;

import static java.security.AccessController.doPrivileged;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Locale;
import java.util.stream.IntStream;

/**
* A class which exposes any available cache line information for the current CPU.
*
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
* @deprecated Use {@link io.smallrye.common.cpu.CacheInfo} instead.
*/
@Deprecated(forRemoval = true)
public final class CacheInfo {
private static final CacheLevelInfo[] cacheLevels;

/**
* Get the number of CPU cache level entries. If no cache information could be gathered, 0 is returned.
*
* @return the number of CPU cache levels, or 0 if unknown
* @deprecated Use {@link io.smallrye.common.cpu.CacheInfo#getLevelEntryCount()} instead.
*/
@Deprecated(forRemoval = true)
public static int getLevelEntryCount() {
return cacheLevels.length;
return io.smallrye.common.cpu.CacheInfo.getLevelEntryCount();
}

/**
Expand All @@ -54,7 +47,9 @@ public static int getLevelEntryCount() {
*
* @param index the cache level index
* @return the CPU cache level information
* @deprecated Use {@link io.smallrye.common.cpu.CacheInfo#getCacheLevelInfo(int)} instead.
*/
@Deprecated(forRemoval = true)
public static CacheLevelInfo getCacheLevelInfo(int index) {
return cacheLevels[index];
}
Expand All @@ -64,218 +59,27 @@ public static CacheLevelInfo getCacheLevelInfo(int index) {
* cache lines may exist if one or more cache line sizes are unknown.
*
* @return the smallest cache line size, or 0 if unknown
* @deprecated Use {@link io.smallrye.common.cpu.CacheInfo#getSmallestDataCacheLineSize()} instead.
*/
@Deprecated(forRemoval = true)
public static int getSmallestDataCacheLineSize() {
int minSize = Integer.MAX_VALUE;
for (CacheLevelInfo cacheLevel : cacheLevels) {
if (cacheLevel.getCacheType().isData()) {
final int cacheLineSize = cacheLevel.getCacheLineSize();
if (cacheLineSize != 0 && cacheLineSize < minSize) {
minSize = cacheLineSize;
}
}
}
return minSize == Integer.MAX_VALUE ? 0 : minSize;
return io.smallrye.common.cpu.CacheInfo.getSmallestDataCacheLineSize();
}

/**
* Get the smallest known instruction cache line size. If no cache line sizes are known, 0 is returned. Note that smaller
* cache lines may exist if one or more cache line sizes are unknown.
*
* @return the smallest cache line size, or 0 if unknown
* @deprecated Use {@link io.smallrye.common.cpu.CacheInfo#getSmallestInstructionCacheLineSize()} instead.
*/
@Deprecated(forRemoval = true)
public static int getSmallestInstructionCacheLineSize() {
int minSize = Integer.MAX_VALUE;
for (CacheLevelInfo cacheLevel : cacheLevels) {
if (cacheLevel.getCacheType().isInstruction()) {
final int cacheLineSize = cacheLevel.getCacheLineSize();
if (cacheLineSize != 0 && cacheLineSize < minSize) {
minSize = cacheLineSize;
}
}
}
return minSize == Integer.MAX_VALUE ? 0 : minSize;
return io.smallrye.common.cpu.CacheInfo.getSmallestInstructionCacheLineSize();
}

static {
cacheLevels = doPrivileged((PrivilegedAction<CacheLevelInfo[]>) () -> {
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<File> indexes = new ArrayList<File>();
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;
}
}
} 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<CacheLevelInfo> list = new ArrayList<CacheLevelInfo>();
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
}
} catch (Throwable ignored) {}
// all has failed
return new CacheLevelInfo[0];
});
}

static int parseIntFile(final File file) {
return safeParseInt(parseStringFile(file));
}

static int safeParseInt(final String string) {
try {
return Integer.parseInt(string);
} catch (Throwable ignored) {
return 0;
}
}

static int parseIntKBFile(final File file) {
try {
final String s = parseStringFile(file);
if (s.endsWith("K")) {
return Integer.parseInt(s.substring(0, s.length() - 1));
} else if (s.endsWith("M")) {
return Integer.parseInt(s.substring(0, s.length() - 1)) * 1024;
} else if (s.endsWith("G")) {
return Integer.parseInt(s.substring(0, s.length() - 1)) * 1024 * 1024;
} else {
return Integer.parseInt(s);
}
} catch (Throwable ignored) {
return 0;
}
}

static String parseStringFile(final File file) {
try (FileInputStream is = new FileInputStream(file)) {
return parseStringStream(is);
} catch (Throwable ignored) {
return "";
}
}

static String parseStringStream(final InputStream is) {
try (Reader r = new InputStreamReader(is, StandardCharsets.UTF_8)) {
StringBuilder b = new StringBuilder();
char[] cb = new char[64];
int res;
while ((res = r.read(cb)) != -1) {
b.append(cb, 0, res);
}
return b.toString().trim();
} catch (Throwable ignored) {
return "";
}
}

static String parseProcessOutput(final String... args) {
final ProcessBuilder processBuilder = new ProcessBuilder(args);
try {
final Process process = processBuilder.start();
process.getOutputStream().close();
final InputStream errorStream = process.getErrorStream();

final Thread errorThread = new Thread(null, new StreamConsumer(errorStream), "Process thread", 32768L);
errorThread.start();

final String result;
try (final InputStream inputStream = process.getInputStream()) {
result = parseStringStream(inputStream);
}

boolean intr = false;
try {
process.waitFor();
} catch (InterruptedException e) {
intr = true;
return null;
} finally {
try {
errorThread.join();
} catch (InterruptedException e) {
intr = true;
} finally {
if (intr) {
Thread.currentThread().interrupt();
}
}
}
return result;
} catch (IOException e) {
return "";
}
}

static class StreamConsumer implements Runnable {

private final InputStream stream;

StreamConsumer(final InputStream stream) {
this.stream = stream;
}

public void run() {
byte[] buffer = new byte[128];
try {
while (stream.read(buffer) != -1) ;
} catch (IOException ignored) {
} finally {
try {
stream.close();
} catch (IOException ignored) {
}
}
}
cacheLevels = IntStream.range(0, io.smallrye.common.cpu.CacheInfo.getLevelEntryCount()).mapToObj(io.smallrye.common.cpu.CacheInfo::getCacheLevelInfo).map(CacheLevelInfo::new).toArray(CacheLevelInfo[]::new);
}

public static void main(String[] args) {
Expand Down
23 changes: 10 additions & 13 deletions src/main/java/org/wildfly/common/cpu/CacheLevelInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,15 @@

/**
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*
* @deprecated Use {@link io.smallrye.common.cpu.CacheLevelInfo} instead.
*/
@Deprecated(forRemoval = true)
public final class CacheLevelInfo {
private final int cacheLevel;
private final CacheType cacheType;
private final int cacheLevelSizeKB;
private final int cacheLineSize;
private final io.smallrye.common.cpu.CacheLevelInfo info;

CacheLevelInfo(final int cacheLevel, final CacheType cacheType, final int cacheLevelSizeKB, final int cacheLineSize) {
this.cacheLevel = cacheLevel;
this.cacheType = cacheType;
this.cacheLevelSizeKB = cacheLevelSizeKB;
this.cacheLineSize = cacheLineSize;
CacheLevelInfo(final io.smallrye.common.cpu.CacheLevelInfo info) {
this.info = info;
}

/**
Expand All @@ -41,7 +38,7 @@ public final class CacheLevelInfo {
* @return the level index, or 0 if unknown
*/
public int getCacheLevel() {
return cacheLevel;
return info.getCacheLevel();
}

/**
Expand All @@ -50,7 +47,7 @@ public int getCacheLevel() {
* @return the type of cache (not {@code null})
*/
public CacheType getCacheType() {
return cacheType;
return CacheType.of(info.getCacheType());
}

/**
Expand All @@ -59,7 +56,7 @@ public CacheType getCacheType() {
* @return the size of this cache level in kilobytes, or 0 if unknown
*/
public int getCacheLevelSizeKB() {
return cacheLevelSizeKB;
return info.getCacheLevelSizeKB();
}

/**
Expand All @@ -68,6 +65,6 @@ public int getCacheLevelSizeKB() {
* @return the cache line size in bytes, or 0 if unknown
*/
public int getCacheLineSize() {
return cacheLineSize;
return info.getCacheLineSize();
}
}
Loading

0 comments on commit f67ce2b

Please sign in to comment.