Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidation with SmallRye Common #100

Merged
merged 6 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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