From afed6998b341adf2f94fae723fe767c98c786ae2 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 10 Jan 2024 14:31:52 +0000 Subject: [PATCH 001/110] Remove class that was moved --- .../net/openhft/affinity/AffinitySupport.java | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 affinity/src/main/java/net/openhft/affinity/AffinitySupport.java diff --git a/affinity/src/main/java/net/openhft/affinity/AffinitySupport.java b/affinity/src/main/java/net/openhft/affinity/AffinitySupport.java deleted file mode 100644 index d4cc6e249..000000000 --- a/affinity/src/main/java/net/openhft/affinity/AffinitySupport.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2016-2020 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package net.openhft.affinity; - -/** - * For backward compatibility with Affinity 2.x - */ -@Deprecated(/* to be removed in x.22 */) -public class AffinitySupport { - - public static int getThreadId() { - return Affinity.getThreadId(); - } - - public static void setThreadId() { - Affinity.setThreadId(); - } -} From 2a31656397765343879de8d00319c9daf0aed379 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 25 Jan 2024 15:11:43 +0000 Subject: [PATCH 002/110] Fix AffinityLockTest on Java 21 (#113) Was broken because Thread#toString includes thread ID on Java 21. Ignore this in the test cases. --- .../openhft/affinity/AffinityLockTest.java | 38 ++++++------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index b3ff7def5..a2decf585 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -20,24 +20,21 @@ import net.openhft.affinity.impl.Utilities; import net.openhft.affinity.impl.VanillaCpuLayout; import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import static java.lang.Runtime.getRuntime; import static net.openhft.affinity.AffinityLock.PROCESSORS; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; -import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; /** @@ -45,13 +42,11 @@ */ public class AffinityLockTest extends BaseAffinityTest { private static final Logger logger = LoggerFactory.getLogger(AffinityLockTest.class); - private static final int JDK_VERSION = getMajorVersion(); private final TestFileLockBasedLockChecker lockChecker = new TestFileLockBasedLockChecker(); @Test public void dumpLocksI7() throws IOException { - assumeFalse(JDK_VERSION > 20); LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("i7.cpuinfo")); AffinityLock[] locks = { new AffinityLock(0, true, false, lockInventory), @@ -70,7 +65,7 @@ public void dumpLocksI7() throws IOException { locks[6].assignedThread = new Thread(new InterrupedThread(), "main"); locks[7].assignedThread = new Thread(new InterrupedThread(), "tcp"); locks[7].assignedThread.start(); - final String actual = LockInventory.dumpLocks(locks); + final String actual = dumpLocks(locks); assertEquals("0: General use CPU\n" + "1: CPU not available\n" + "2: Thread[logger,5,main] alive=true\n" + @@ -89,7 +84,6 @@ public void dumpLocksI7() throws IOException { @Test public void dumpLocksI3() throws IOException { - assumeFalse(JDK_VERSION > 20); LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("i3.cpuinfo")); AffinityLock[] locks = { new AffinityLock(0, true, false, lockInventory), @@ -101,7 +95,7 @@ public void dumpLocksI3() throws IOException { locks[1].assignedThread.start(); locks[3].assignedThread = new Thread(new InterrupedThread(), "main"); - final String actual = LockInventory.dumpLocks(locks); + final String actual = dumpLocks(locks); assertEquals("0: General use CPU\n" + "1: Thread[engine,5,main] alive=true\n" + "2: General use CPU\n" + @@ -113,7 +107,6 @@ public void dumpLocksI3() throws IOException { @Test public void dumpLocksCoreDuo() throws IOException { - assumeFalse(JDK_VERSION > 20); LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("core.duo.cpuinfo")); AffinityLock[] locks = { new AffinityLock(0, true, false, lockInventory), @@ -122,7 +115,7 @@ public void dumpLocksCoreDuo() throws IOException { locks[1].assignedThread = new Thread(new InterrupedThread(), "engine"); locks[1].assignedThread.start(); - final String actual = LockInventory.dumpLocks(locks); + final String actual = dumpLocks(locks); assertEquals("0: General use CPU\n" + "1: Thread[engine,5,main] alive=true\n", actual); System.out.println(actual); @@ -317,21 +310,12 @@ public void testTooHighCpuId2() { } } - private static int getMajorVersion() { - try { - final Method method = Runtime.class.getDeclaredMethod("version"); - final Object version = method.invoke(getRuntime()); - final Class clz = Class.forName("java.lang.Runtime$Version"); - return (Integer) clz.getDeclaredMethod("major").invoke(version); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException | - IllegalArgumentException e) { - // ignore and fall back to pre-jdk9 - } - try { - return Integer.parseInt(Runtime.class.getPackage().getSpecificationVersion().split("\\.")[1]); - } catch (Exception e) { - System.err.println("Unable to get the major version, defaulting to 8 " + e); - return 8; - } + /** + * In Java 21 the toString contents of Thread changed to include an ID. This breaks the tests here in Java 21. + * Strip out the thread ID here so that existing tests continue to pass. + */ + private static String dumpLocks(AffinityLock[] locks) { + String value = LockInventory.dumpLocks(locks); + return value.replaceAll("#[0-9]+(,)?", ""); } } From f83ea94d2af56bcc3f2c767beca94e2b09a2bf04 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 9 Feb 2024 00:54:51 +0000 Subject: [PATCH 003/110] Updating parent POM (automated) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index a603a8b62..0c06e6569 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.24.0 + 1.25.3 diff --git a/affinity/pom.xml b/affinity/pom.xml index bc65cfe05..465215613 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.24.0 + 1.25.3 diff --git a/pom.xml b/pom.xml index 0dc355831..f96e7e5e3 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.24.0 + 1.25.3 From 3cebc6f6ccf41671a3752128f990f667612b359c Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Mon, 4 Mar 2024 21:03:07 +0000 Subject: [PATCH 004/110] Updating parent POM (automated) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 0c06e6569..694444f84 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.25.3 + 1.25.4 diff --git a/affinity/pom.xml b/affinity/pom.xml index 465215613..d63ec73fa 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.25.3 + 1.25.4 diff --git a/pom.xml b/pom.xml index f96e7e5e3..0416056c1 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.25.3 + 1.25.4 From 959768b27877f57560c81b87d45165652d3275a3 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Mon, 25 Mar 2024 11:45:32 +0000 Subject: [PATCH 005/110] Initial branch of x.26 --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 694444f84..5cfe6cc26 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.24ea0-SNAPSHOT + 3.26ea0-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -42,7 +42,7 @@ net.openhft third-party-bom pom - 3.24.0 + 3.25.2 import diff --git a/affinity/pom.xml b/affinity/pom.xml index d63ec73fa..7387a7601 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.24ea0-SNAPSHOT + 3.26ea0-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -43,13 +43,13 @@ net.openhft third-party-bom pom - 3.24.0 + 3.25.2 import net.openhft chronicle-bom - 2.24ea-SNAPSHOT + 2.26ea-SNAPSHOT pom import diff --git a/pom.xml b/pom.xml index 0416056c1..a4b88a58f 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.24ea0-SNAPSHOT + 3.64ea0-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From c05061f567317cc41a386da8e22a35deadc0277b Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 28 Mar 2024 10:48:52 +0000 Subject: [PATCH 006/110] fix deprecated usage --- .../src/test/java/net/openhft/affinity/AffinityLockTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index a2decf585..96c19f341 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -20,6 +20,7 @@ import net.openhft.affinity.impl.Utilities; import net.openhft.affinity.impl.VanillaCpuLayout; import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; +import org.hamcrest.MatcherAssert; import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.slf4j.Logger; @@ -244,7 +245,7 @@ public void shouldReturnLockForSpecifiedCpu() { assumeTrue(Runtime.getRuntime().availableProcessors() > 3); try (final AffinityLock affinityLock = AffinityLock.acquireLock(3)) { - assertThat(affinityLock.cpuId(), is(3)); + MatcherAssert.assertThat(affinityLock.cpuId(), is(3)); } assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); } From f4c5df52f8e00f7371fd4af8579e7dad8320dddc Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 3 Apr 2024 11:39:43 +0100 Subject: [PATCH 007/110] Tidy up compiler setting and some warnings --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 5cfe6cc26..dc06e7229 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -42,7 +42,7 @@ net.openhft third-party-bom pom - 3.25.2 + 3.26.0-SNAPSHOT import diff --git a/affinity/pom.xml b/affinity/pom.xml index 7387a7601..8655b4567 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -43,7 +43,7 @@ net.openhft third-party-bom pom - 3.25.2 + 3.26.0-SNAPSHOT import From cfdc2f6e4760019fc272736c70871cb3cf51764f Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 10 Apr 2024 10:53:28 +0100 Subject: [PATCH 008/110] tidy SuppressWarnings --- .../java/net/openhft/affinity/impl/LinuxHelper.java | 12 ++++++------ .../net/openhft/affinity/impl/VersionHelper.java | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java index 3b4d301de..f2e456286 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java @@ -239,7 +239,7 @@ public String getSysname() { return new String(sysname, 0, length(sysname)); } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("unused") public String getNodename() { return new String(nodename, 0, length(nodename)); } @@ -270,7 +270,7 @@ public String getMachine() { return new String(machine, 0, length(machine)); } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("UnusedDeclaration") public String getDomainname() { return new String(domainname, 0, length(domainname)); } @@ -295,7 +295,7 @@ public cpu_set_t() { } } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("UnusedDeclaration") public static void __CPU_ZERO(cpu_set_t cpuset) { for (NativeLong bits : cpuset.__bits) { bits.setValue(0L); @@ -310,19 +310,19 @@ public static long __CPUMASK(int cpu) { return 1L << (cpu % __NCPUBITS); } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("UnusedDeclaration") public static void __CPU_SET(int cpu, cpu_set_t cpuset) { cpuset.__bits[__CPUELT(cpu)].setValue( cpuset.__bits[__CPUELT(cpu)].longValue() | __CPUMASK(cpu)); } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("UnusedDeclaration") public static void __CPU_CLR(int cpu, cpu_set_t cpuset) { cpuset.__bits[__CPUELT(cpu)].setValue( cpuset.__bits[__CPUELT(cpu)].longValue() & ~__CPUMASK(cpu)); } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("UnusedDeclaration") public static boolean __CPU_ISSET(int cpu, cpu_set_t cpuset) { return (cpuset.__bits[__CPUELT(cpu)].longValue() & __CPUMASK(cpu)) != 0; } diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java index b54d75081..9729c2980 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java @@ -61,7 +61,7 @@ public int hashCode() { return (major << 16) | (minor << 8) | release; } - @SuppressWarnings({"UnusedDeclaration"}) + @SuppressWarnings("unused") public boolean majorMinorEquals(final VersionHelper ver) { return ver != null && this.major == ver.major From 9a9148f9f5073cb4c8ff4a59804d3f7c74d84ce2 Mon Sep 17 00:00:00 2001 From: rogersimmons Date: Wed, 17 Apr 2024 09:33:05 +0100 Subject: [PATCH 009/110] Remove old comment (long since addressed) --- .../main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java index 1a4463319..5f93ca361 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java @@ -72,7 +72,6 @@ public BitSet getAffinity() { return ret; } - // TODO: FIXME!!! CHANGE IAffinity TO SUPPORT PLATFORMS WITH 64+ CORES FIXME!!! @Override public void setAffinity(final BitSet affinity) { LinuxHelper.sched_setaffinity(affinity); From 25b21069372bb0feee5d3e3cf266f29fb65fec12 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 7 May 2024 18:48:15 +0100 Subject: [PATCH 010/110] Fix newlines --- .../src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java | 1 - affinity/src/main/java/net/openhft/affinity/LockCheck.java | 2 +- affinity/src/main/java/net/openhft/affinity/LockInventory.java | 2 -- .../src/main/java/net/openhft/affinity/MicroJitterSampler.java | 2 -- .../src/main/java/net/openhft/affinity/impl/LinuxHelper.java | 2 +- .../src/main/java/net/openhft/affinity/impl/VersionHelper.java | 1 - affinity/src/main/java/net/openhft/ticker/Ticker.java | 2 +- affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java | 2 +- affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java | 2 +- .../src/test/java/net/openhft/affinity/BootClassPathTest.java | 2 +- .../test/java/net/openhft/affinity/FileLockLockCheckTest.java | 2 +- affinity/src/test/java/net/openhft/affinity/LockCheckTest.java | 2 +- .../src/test/java/net/openhft/ticker/impl/JNIClockTest.java | 2 +- 13 files changed, 9 insertions(+), 15 deletions(-) diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java index deb9d9d5f..3dc8d2652 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java @@ -61,4 +61,3 @@ public static Bundle findBundle(BundleContext context, String symbolicName) { return null; } } - diff --git a/affinity/src/main/java/net/openhft/affinity/LockCheck.java b/affinity/src/main/java/net/openhft/affinity/LockCheck.java index 8acaf4e23..29b962f07 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockCheck.java +++ b/affinity/src/main/java/net/openhft/affinity/LockCheck.java @@ -100,4 +100,4 @@ static boolean updateCpu(int cpu) throws IOException { public static void releaseLock(int cpu) { lockChecker.releaseLock(cpu); } -} \ No newline at end of file +} diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index ce15aebed..2ca7eb39e 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -159,7 +159,6 @@ && updateLockForCurrentThread(bind, al, false)) { return noLock(); } - LOGGER.warn("No reservable CPU for {}", Thread.currentThread()); return noLock(); @@ -181,7 +180,6 @@ && updateLockForCurrentThread(bind, required, false)) { return noLock(); } - LOGGER.warn("Unable to acquire lock on CPU {} for thread {}, trying to find another CPU", cpuId, Thread.currentThread()); diff --git a/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java b/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java index c2a8ef3aa..d0a971806 100644 --- a/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java +++ b/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java @@ -46,7 +46,6 @@ private static void pause() throws InterruptedException { } else { Thread.sleep(1); } - } public static void main(String... ignored) throws InterruptedException { @@ -133,7 +132,6 @@ void print(PrintStream ps) { ps.println(); } } - /* e.g. Ubuntu 20.04, Ryzen 5950X with an isolated CPU. (init 3) sudo cpupower -c {cpu} -g performance, run from command line After 3600 seconds, the average per hour was diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java index f2e456286..da85e247f 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java @@ -69,7 +69,7 @@ cpu_set_t sched_getaffinity() { public static void sched_setaffinity(final BitSet affinity) { sched_setaffinity(0, affinity); } - + public static void sched_setaffinity(final int pid, final BitSet affinity) { final CLibrary lib = CLibrary.INSTANCE; final cpu_set_t cpuset = new cpu_set_t(); diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java index 9729c2980..98e1c19f0 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java @@ -77,4 +77,3 @@ public boolean isSameOrNewer(final VersionHelper ver) { && this.release >= ver.release)); } } - diff --git a/affinity/src/main/java/net/openhft/ticker/Ticker.java b/affinity/src/main/java/net/openhft/ticker/Ticker.java index d8ac5a1e6..6e17c653c 100644 --- a/affinity/src/main/java/net/openhft/ticker/Ticker.java +++ b/affinity/src/main/java/net/openhft/ticker/Ticker.java @@ -58,4 +58,4 @@ public static long toNanos(long ticks) { public static double toMicros(long ticks) { return INSTANCE.toMicros(ticks); } -} \ No newline at end of file +} diff --git a/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java b/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java index 0115c19cd..1808af9a7 100644 --- a/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java +++ b/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java @@ -103,4 +103,4 @@ public long toNanos(long ticks) { public double toMicros(double ticks) { return ticks * RDTSC_MICRO_FACTOR; } -} \ No newline at end of file +} diff --git a/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java b/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java index 8844ab460..2c3402433 100644 --- a/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java +++ b/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java @@ -47,4 +47,4 @@ public long toNanos(long ticks) { public double toMicros(double ticks) { return ticks / 1e3; } -} \ No newline at end of file +} diff --git a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java index d4c555938..3c0c29df8 100644 --- a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java @@ -30,4 +30,4 @@ public void shouldDetectClassesOnClassPath() { assertTrue(BootClassPath.INSTANCE.has("java.lang.Thread")); assertTrue(BootClassPath.INSTANCE.has("java.lang.Runtime")); } -} \ No newline at end of file +} diff --git a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java index 5f39b87ce..1576851f4 100644 --- a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java @@ -71,4 +71,4 @@ public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { LockCheck.isCpuFree(cpu); } -} \ No newline at end of file +} diff --git a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java index c6ab5e042..11ec9463f 100644 --- a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java @@ -84,4 +84,4 @@ public void shouldNotBlowUpIfPidFileIsCorrupt() throws Exception { LockCheck.isCpuFree(cpu); } -} \ No newline at end of file +} diff --git a/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java b/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java index 8af7760de..b87b793fe 100644 --- a/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java +++ b/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java @@ -78,4 +78,4 @@ public void testJitter() { System.out.println(((long) (clock.toMicros(time[i]) * 10)) / 10.0 + ", " + ((long) (clock.toMicros(length[i]) * 10) / 10.0)); } } -} \ No newline at end of file +} From 4b8f50d83ee7dd2411e13a4d034306cb78d4df4e Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Mon, 20 May 2024 13:31:13 +0100 Subject: [PATCH 011/110] type:pom order --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index dc06e7229..9722d19fc 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -41,8 +41,8 @@ net.openhft third-party-bom - pom 3.26.0-SNAPSHOT + pom import diff --git a/affinity/pom.xml b/affinity/pom.xml index 8655b4567..ca116fbe0 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -42,8 +42,8 @@ net.openhft third-party-bom - pom 3.26.0-SNAPSHOT + pom import From 8386232d9a0848dec9e7946401d27f279cbe9ecd Mon Sep 17 00:00:00 2001 From: rogersimmons Date: Wed, 17 Apr 2024 09:33:05 +0100 Subject: [PATCH 012/110] Remove old comment (long since addressed) --- .../main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java index 1a4463319..5f93ca361 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java @@ -72,7 +72,6 @@ public BitSet getAffinity() { return ret; } - // TODO: FIXME!!! CHANGE IAffinity TO SUPPORT PLATFORMS WITH 64+ CORES FIXME!!! @Override public void setAffinity(final BitSet affinity) { LinuxHelper.sched_setaffinity(affinity); From eb3ec15b9c881fafbc358fef2f5bae5e8c95f089 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 22 May 2024 19:16:40 +0100 Subject: [PATCH 013/110] parent poms -> x.26.0 --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 9722d19fc..c894212c9 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -41,7 +41,7 @@ net.openhft third-party-bom - 3.26.0-SNAPSHOT + 3.26.0 pom import diff --git a/affinity/pom.xml b/affinity/pom.xml index ca116fbe0..fd303d10a 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -42,7 +42,7 @@ net.openhft third-party-bom - 3.26.0-SNAPSHOT + 3.26.0 pom import From b21836e42701e6db0ef3cfbc5b41a1110b55c799 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 23 May 2024 13:06:41 +0100 Subject: [PATCH 014/110] correct version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4b88a58f..2e42b312a 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.64ea0-SNAPSHOT + 3.26ea0-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From bec873c5e1ff97fa7178ab5c5f21d8549ae27e16 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 23 May 2024 13:31:12 +0100 Subject: [PATCH 015/110] Bump the snapshot version for affinity --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fd303d10a..9a4a91acd 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea0-SNAPSHOT + 3.26ea1-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity From 4a33d97715d77acf6102a8eb117b71cb9cb8a630 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 23 May 2024 13:32:01 +0100 Subject: [PATCH 016/110] Bump the snapshot version for affinity --- affinity-test/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index c894212c9..7cf2554a9 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea0-SNAPSHOT + 3.26ea1-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test diff --git a/pom.xml b/pom.xml index 2e42b312a..48714d4dc 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea0-SNAPSHOT + 3.26ea1-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From 91e88fd51b6af8b082191b34a827767cc02f46fd Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 23 May 2024 13:54:35 +0100 Subject: [PATCH 017/110] java-parent-pom -> 1.26.0 --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 4 ++-- .../src/main/java/net/openhft/affinity/AffinityLock.java | 1 + .../java/net/openhft/affinity/AffinityThreadFactory.java | 1 + .../main/java/net/openhft/affinity/MicroJitterSampler.java | 1 + .../main/java/net/openhft/affinity/impl/LinuxHelper.java | 4 ++-- .../affinity/lockchecker/FileLockBasedLockChecker.java | 1 + .../test/java/net/openhft/affinity/AffinityLockTest.java | 7 +++++++ .../net/openhft/affinity/impl/NativeAffinityImpTest.java | 4 +++- .../net/openhft/affinity/impl/PosixJNAAffinityTest.java | 4 +++- pom.xml | 2 +- 11 files changed, 23 insertions(+), 8 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 7cf2554a9..c4f20dd60 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.25.4 + 1.26.0 diff --git a/affinity/pom.xml b/affinity/pom.xml index 9a4a91acd..833855bf1 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.25.4 + 1.26.0 @@ -178,7 +178,7 @@ -h ${project.build.directory}/jni - -Xlint:deprecation + -Xlint:all,-options 1.8 1.8 diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 67642daf5..2fba8ce46 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -446,6 +446,7 @@ public void close() { release(); } + @SuppressWarnings("removal") @Override protected void finalize() throws Throwable { if (bound) { diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java b/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java index a70bfbe3d..5962f4b62 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java @@ -57,6 +57,7 @@ public synchronized Thread newThread(@NotNull final Runnable r) { @Override public void run() { try (AffinityLock ignored = acquireLockBasedOnLast()) { + assert ignored != null; r.run(); } } diff --git a/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java b/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java index d0a971806..f9e34715d 100644 --- a/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java +++ b/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java @@ -71,6 +71,7 @@ private void once() throws InterruptedException { public void run() { try (final AffinityLock lock = AffinityLock.acquireLock(CPU)) { + assert lock != null; boolean first = true; System.out.println("Warming up..."); while (!Thread.currentThread().isInterrupted()) { diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java index da85e247f..448d37bd7 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java @@ -231,7 +231,7 @@ static int length(final byte[] data) { } @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return FIELD_ORDER; } @@ -328,7 +328,7 @@ public static boolean __CPU_ISSET(int cpu, cpu_set_t cpuset) { } @Override - protected List getFieldOrder() { + protected List getFieldOrder() { return FIELD_ORDER; } } diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java index 77095375c..6b596a49f 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java @@ -241,5 +241,6 @@ private File tmpDir() { * Thrown when another process deleted the lock file between us opening the file and acquiring the lock */ class ConcurrentLockFileDeletionException extends Exception { + private static final long serialVersionUID = 0L; } } diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index 96c19f341..dd286686f 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -162,6 +162,7 @@ public void resetAffinity() { } assertEquals(1, Affinity.getAffinity().cardinality()); try (AffinityLock lock = AffinityLock.acquireLock()) { + assertNotNull(lock); } assertTrue(Affinity.getAffinity().cardinality() > 1); } @@ -274,15 +275,19 @@ public void testAffinityLockDescriptions() { return; } try (AffinityLock lock = AffinityLock.acquireLock("last")) { + assertNotNull(lock); assertEquals(PROCESSORS - 1, Affinity.getCpu()); } try (AffinityLock lock = AffinityLock.acquireLock("last")) { + assertNotNull(lock); assertEquals(PROCESSORS - 1, Affinity.getCpu()); } try (AffinityLock lock = AffinityLock.acquireLock("last-1")) { + assertNotNull(lock); assertEquals(PROCESSORS - 2, Affinity.getCpu()); } try (AffinityLock lock = AffinityLock.acquireLock("1")) { + assertNotNull(lock); assertEquals(1, Affinity.getCpu()); } try (AffinityLock lock = AffinityLock.acquireLock("any")) { @@ -302,12 +307,14 @@ public void testAffinityLockDescriptions() { @Test public void testTooHighCpuId() { try (AffinityLock ignored = AffinityLock.acquireLock(123456)) { + assertNotNull(ignored); } } @Test public void testTooHighCpuId2() { try (AffinityLock ignored = AffinityLock.acquireLock(new int[] {123456})) { + assertNotNull(ignored); } } diff --git a/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java b/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java index 3c98d9683..04c200e3f 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java @@ -53,7 +53,9 @@ public void testGettid() { long time = 0; for (int i = 0; i < runs; i++) { long start = System.nanoTime(); - tid = Thread.currentThread().getId(); + @SuppressWarnings("deprecation") + long tid0 = Thread.currentThread().getId(); + tid = tid0; time += System.nanoTime() - start; assertTrue(tid > 0); assertTrue(tid < 1 << 16); diff --git a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java index a763cef05..d25aa89ae 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java @@ -51,7 +51,9 @@ public void testGettid() { long time = 0; for (int i = 0; i < runs; i++) { long start = System.nanoTime(); - tid = Thread.currentThread().getId(); + @SuppressWarnings("deprecation") + long tid0 = Thread.currentThread().getId(); + tid = tid0; time += System.nanoTime() - start; assertTrue(tid > 0); assertTrue(tid < 1 << 24); diff --git a/pom.xml b/pom.xml index 48714d4dc..79ab1d2c7 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.25.4 + 1.26.0 From 5dcf176422ec646922127458a43a0dc6adcb3727 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 23 May 2024 15:47:36 +0100 Subject: [PATCH 018/110] java-parent-pom -> 1.26.0 (finalize) --- affinity/src/main/java/net/openhft/affinity/AffinityLock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 2fba8ce46..f7a01619d 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -446,7 +446,7 @@ public void close() { release(); } - @SuppressWarnings("removal") + @SuppressWarnings({"deprecation", "removal"}) @Override protected void finalize() throws Throwable { if (bound) { From 461408b2b9a3ccc2e59a60178fee5c15b72d8e21 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 29 May 2024 16:27:53 +0100 Subject: [PATCH 019/110] Updating to bom version 2.26ea0 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 833855bf1..fc8b062b0 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea0 pom import From 730f7f688c89b2a9db4914312c37945c8235d207 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 29 May 2024 16:28:11 +0100 Subject: [PATCH 020/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fc8b062b0..43f964c8d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea1-SNAPSHOT + 3.26ea1 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea0 + 2.26ea-SNAPSHOT pom import @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea1 From dd79316f2b37cc562d7069ba267177038ddc9821 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 29 May 2024 16:35:19 +0100 Subject: [PATCH 021/110] Updating to bom version 2.26ea1 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 43f964c8d..143ff8dc2 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea1 pom import From a0a58fb320320bc3267732691669db27169f79ec Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 29 May 2024 16:35:33 +0100 Subject: [PATCH 022/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 143ff8dc2..43f964c8d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea1 + 2.26ea-SNAPSHOT pom import From bfcfd600d765db61a768076b651ac9d7f7b7af3e Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 29 May 2024 17:13:50 +0100 Subject: [PATCH 023/110] Re-release affinity --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index c4f20dd60..ae07c3ea9 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea1-SNAPSHOT + 3.26ea2-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test diff --git a/affinity/pom.xml b/affinity/pom.xml index 43f964c8d..56851c13d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea1 + 3.26ea2-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity diff --git a/pom.xml b/pom.xml index 79ab1d2c7..b871d1851 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea1-SNAPSHOT + 3.26ea2-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From db1264b730358131e853aa9f20f45c22b4a67da2 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 29 May 2024 18:56:31 +0100 Subject: [PATCH 024/110] Updating to bom version 2.26ea1 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 56851c13d..3cb0a0047 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea1 pom import From 7e25a795341deb2c8c974b57f1e3396a2bb55c57 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 29 May 2024 18:56:47 +0100 Subject: [PATCH 025/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 3cb0a0047..6736c3564 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea2-SNAPSHOT + 3.26ea2 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea1 + 2.26ea-SNAPSHOT pom import @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea1 + Java-Thread-Affinity-3.26ea2 From ea37beb018cc4759ebcc23fd9ac1e3ff7b5a5935 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 30 May 2024 08:01:44 +0100 Subject: [PATCH 026/110] Re-release affinity --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index ae07c3ea9..93e457d06 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea2-SNAPSHOT + 3.26ea3-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test diff --git a/affinity/pom.xml b/affinity/pom.xml index 6736c3564..d1fe17ab9 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea2 + 3.26ea3-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity diff --git a/pom.xml b/pom.xml index b871d1851..1e11e7cb4 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea2-SNAPSHOT + 3.26ea3-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From 0122ee6e4a6a91d54d821b7fcade97fa5d397921 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Tue, 11 Jun 2024 10:34:22 +0100 Subject: [PATCH 027/110] Updating to bom version 2.26ea8 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index d1fe17ab9..fbe386bcb 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea8 pom import From 2897de818ef4b41e160a57a70a1ccde957ded6b6 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Tue, 11 Jun 2024 10:34:38 +0100 Subject: [PATCH 028/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fbe386bcb..45be8631c 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea3-SNAPSHOT + 3.26ea3 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea8 + 2.26ea-SNAPSHOT pom import @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea2 + Java-Thread-Affinity-3.26ea3 From 041a62c492c96b13893d7c1637358dd1e120ff48 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 11 Jun 2024 11:02:40 +0100 Subject: [PATCH 029/110] Release affinity --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 45be8631c..5c493be2c 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea3 + 3.26ea3-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity From 3258abc52130de6c39a032044c696e8f2a4a5392 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Thu, 13 Jun 2024 09:10:23 +0100 Subject: [PATCH 030/110] Updating to bom version 2.26ea9 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 5c493be2c..60c1276d1 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea9 pom import From ae4ee4ebdbfc2c8d14631b1cdf3d7e8759aff43b Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Thu, 13 Jun 2024 09:10:38 +0100 Subject: [PATCH 031/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 60c1276d1..45be8631c 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea3-SNAPSHOT + 3.26ea3 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea9 + 2.26ea-SNAPSHOT pom import From d0c0cb130a1aed71f09b7b324f9b7b2088ce50dd Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 14 Jun 2024 14:36:45 +0100 Subject: [PATCH 032/110] revert affinity to 3.23.3 (#124) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 93e457d06..d324ab26d 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea3-SNAPSHOT + 3.26ea4-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test diff --git a/affinity/pom.xml b/affinity/pom.xml index 45be8631c..410f53d28 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea3 + 3.26ea4-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity diff --git a/pom.xml b/pom.xml index 1e11e7cb4..3271c1b61 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea3-SNAPSHOT + 3.26ea4-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From a6be0bc146afa42756896abdfd44a9cf6c46b43e Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Jun 2024 21:47:10 +0100 Subject: [PATCH 033/110] Updating to bom version 2.26ea11 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 410f53d28..45523d0a3 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea11 pom import From af618862835862cc8856fcc98bd4ce3a2c8bf824 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Jun 2024 21:47:25 +0100 Subject: [PATCH 034/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 45523d0a3..fadcb8df6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea4-SNAPSHOT + 3.26ea4 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea11 + 2.26ea-SNAPSHOT pom import @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea3 + Java-Thread-Affinity-3.26ea4 From a881052293ddb83191db4788ad9028d9ce9252d9 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Jun 2024 22:30:41 +0100 Subject: [PATCH 035/110] Updating to bom version 2.26ea12 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fadcb8df6..2d0fb3c6b 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea12 pom import From 999da9e5ec3179564e56970d80c22161734e1010 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Jun 2024 22:30:53 +0100 Subject: [PATCH 036/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 2d0fb3c6b..fadcb8df6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea12 + 2.26ea-SNAPSHOT pom import From 60033e4d9625ad6b284548f86abbddb294e9035f Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Jun 2024 22:55:51 +0100 Subject: [PATCH 037/110] Updating to bom version 2.26ea13 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fadcb8df6..ba2a60708 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea13 pom import From e41a026b61c211f32378abe55c8f0797a9fdbf98 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Jun 2024 22:56:03 +0100 Subject: [PATCH 038/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index ba2a60708..fadcb8df6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea13 + 2.26ea-SNAPSHOT pom import From 60fc755bab401f51b4d120aa1c83d30ddfa352a4 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 15 Jun 2024 13:17:41 +0100 Subject: [PATCH 039/110] Align snapshot versions 3.26ea4-SNAPSHOT (#125) --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fadcb8df6..ca2a401d6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea4 + 3.26ea4-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity From f28cdb37f0108f914eb4db5d5c9700b4486c94f5 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 16:29:43 +0100 Subject: [PATCH 040/110] Updating to bom version 2.26ea14 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index ca2a401d6..cbe50eab6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea14 pom import From c099d7106e2be55896c99cc3f7eaf30f830bb171 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 16:29:58 +0100 Subject: [PATCH 041/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index cbe50eab6..fadcb8df6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea4-SNAPSHOT + 3.26ea4 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea14 + 2.26ea-SNAPSHOT pom import From 3e66fe1c35b9260516facfa00bd86cebe141d7ba Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 18:10:32 +0100 Subject: [PATCH 042/110] Updating to bom version 2.26ea15 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fadcb8df6..cdd631c61 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea15 pom import From 680d0b2e1c2480156c1927db15a8bab6d07f5a8a Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 18:10:46 +0100 Subject: [PATCH 043/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index cdd631c61..fadcb8df6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea15 + 2.26ea-SNAPSHOT pom import From c744a7b7282becd561edaf0071d237917411ea9e Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 18:15:29 +0100 Subject: [PATCH 044/110] Updating to bom version 2.26ea16 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fadcb8df6..0b6183d08 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea16 pom import From 3cd3d15b388704ec8794318978ca41f8dd9604e2 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 18:15:42 +0100 Subject: [PATCH 045/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 0b6183d08..fadcb8df6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea16 + 2.26ea-SNAPSHOT pom import From 3bc506762a4a1680218929f69d8a510fb8d6b700 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 19:05:26 +0100 Subject: [PATCH 046/110] Set snapshot version --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index fadcb8df6..ca2a401d6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea4 + 3.26ea4-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity From 4f7c73c9f73c460e7b3daf0ce1ac18d27c468913 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 19:54:01 +0100 Subject: [PATCH 047/110] Updating to bom version 2.26ea17 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index ca2a401d6..2aa138538 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea17 pom import From 065f5b028845ab5aeafdf82d52a982ebab4cfcda Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 19:54:20 +0100 Subject: [PATCH 048/110] [maven-release-plugin] prepare release Java-Thread-Affinity-3.26ea4 --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index d324ab26d..df7887064 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea4-SNAPSHOT + 3.26ea4 bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea4 scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index 2aa138538..1f1213a2d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea4-SNAPSHOT + 3.26ea4 bundle OpenHFT/Java-Thread-Affinity/affinity diff --git a/pom.xml b/pom.xml index 3271c1b61..f21e294b4 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea4-SNAPSHOT + 3.26ea4 pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea4 From 562f22f6bda298a309c28ccb43d3b2ed0a412c13 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 19:54:23 +0100 Subject: [PATCH 049/110] [maven-release-plugin] prepare for next development iteration --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 2 +- pom.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index df7887064..6ab139997 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea4 + 3.26ea5-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea4 + ea scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index 1f1213a2d..03c1f2733 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea4 + 3.26ea5-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity diff --git a/pom.xml b/pom.xml index f21e294b4..4c0fee020 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea4 + 3.26ea5-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea4 + ea From f44ec43781aede29ae8d43b221de5d23b6c1587f Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Sat, 15 Jun 2024 19:54:38 +0100 Subject: [PATCH 050/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 03c1f2733..caec040d6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea17 + 2.26ea-SNAPSHOT pom import From 73cc564b0e7beb666b0d201e40a458340e6abdd5 Mon Sep 17 00:00:00 2001 From: rogersimmons <42873823+rogersimmons@users.noreply.github.com> Date: Sat, 29 Jun 2024 18:39:30 +0100 Subject: [PATCH 051/110] Add rdtsc for ARM 64 and 32 bit (#129) * Add rdtsc for ARM 64 and 32 bit * Remove link lib which isn't needed * Add macOS and Widows support for rdtsc() * Add OS detect to Makefile mac build * Add windows support Tweak macOS support * More macOS tweaks --------- Co-authored-by: rogersimmons --- affinity/pom.xml | 2 +- affinity/src/main/c/Makefile | 17 +++++++-- .../c/net_openhft_ticker_impl_JNIClock.cpp | 24 ++++++++++++ ...terprise_internals_impl_NativeAffinity.cpp | 37 ++++++++++++++++--- 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index caec040d6..ef717e9d5 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -129,7 +129,7 @@ exec - ${project.basedir}/${native.source.dir}/Makefile + make ${project.basedir}/${native.source.dir} diff --git a/affinity/src/main/c/Makefile b/affinity/src/main/c/Makefile index 0138fe1af..ac448e568 100755 --- a/affinity/src/main/c/Makefile +++ b/affinity/src/main/c/Makefile @@ -1,4 +1,3 @@ -#!/usr/bin/make -f # # Makefile for C code # @@ -10,6 +9,16 @@ TARGET := $(TARGET_DIR)/libCEInternals.so WORKING_DIR := $(TARGET_DIR)/../jni +JNI_OS := win32 +UNAME_S:= $(shell uname -s) +ifeq ($(UNAME_S), Linux) + JNI_OS := linux + LRT := -lrt +endif +ifeq ($(UNAME_S), Darwin) + JNI_OS := darwin +endif + JAVA_CLASSES = software.chronicle.enterprise.internals.impl.NativeAffinity net.openhft.ticker.impl.JNIClock JNI_STUBS := $(subst .,_,$(JAVA_CLASSES)) @@ -19,10 +28,10 @@ JAVA_BUILD_DIR := $(TARGET_DIR) JAVA_HOME ?= /usr/java/default JAVA_LIB := $(JAVA_HOME)/jre/lib -JVM_SHARED_LIBS := -L$(JAVA_LIB)/amd64/server -L$(JAVA_LIB)/i386/server -L$(JAVA_LIB)/amd64/jrockit/ -L$(JAVA_LIB)/i386/jrockit/ -L$(JAVA_LIB)/ppc64le/server -L$(JAVA_LIB)/ppc64le/jrockit/ -L$(JAVA_HOME)/lib/server +JVM_SHARED_LIBS := -L"$(JAVA_LIB)/amd64/server" -L"$(JAVA_LIB)/i386/server" -L"$(JAVA_LIB)/amd64/jrockit" -L"$(JAVA_LIB)/i386/jrockit" -L"$(JAVA_LIB)/ppc64le/server" -L"$(JAVA_LIB)/ppc64le/jrockit" -L"$(JAVA_HOME)/lib/server" CXX=g++ -INCLUDES := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux -I $(WORKING_DIR) +INCLUDES := -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/$(JNI_OS)" -I"$(WORKING_DIR)" # classpath for javah ifdef CLASSPATH @@ -36,7 +45,7 @@ endif all: $(TARGET) $(TARGET): $(JNI_SOURCES) - $(CXX) -O3 -Wall -shared -fPIC $(JVM_SHARED_LIBS) -ljvm -lrt $(INCLUDES) $(JNI_SOURCES) -o $(TARGET) + $(CXX) -O3 -Wall -shared -fPIC $(JVM_SHARED_LIBS) $(LRT) $(INCLUDES) $(JNI_SOURCES) -o $(TARGET) clean: rm $(TARGET) diff --git a/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp b/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp index e269308a5..d5534c073 100644 --- a/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp +++ b/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp @@ -53,6 +53,30 @@ unsigned long long rdtsc(){ __asm__ __volatile__("mfspr %%r3, 268": "=r" (rval)); return rval; } +#elif defined(__aarch64__) // ARMv8-A (AArch64) +#include +inline uint64_t rdtsc() { + uint64_t virtual_timer_value; + asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); + return virtual_timer_value; +} +#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 7) // ARMv7-A (32-bit) +#include +inline uint64_t rdtsc() { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec; +} +#elif defined(__APPLE__) +#include +inline uint64_t rdtsc() { + return mach_absolute_time(); +} +#elif defined(_MSC_VER) +#include +inline uint64_t rdtsc() { + return __rdtsc(); +} #endif /* diff --git a/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp b/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp index 0a2384022..013b85433 100644 --- a/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp +++ b/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp @@ -19,12 +19,14 @@ #endif #include -#include -#include -#include -#include -#include - +#ifdef __linux__ + #include + #include + #include + #include + #include +#endif +#include #include "software_chronicle_enterprise_internals_impl_NativeAffinity.h" /* @@ -35,6 +37,7 @@ JNIEXPORT jbyteArray JNICALL Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getAffinity0 (JNIEnv *env, jclass c) { +#ifdef __linux__ // The default size of the structure supports 1024 CPUs, should be enough // for now In the future we can use dynamic sets, which can support more // CPUs, given OS can handle them as well @@ -53,6 +56,9 @@ JNIEXPORT jbyteArray JNICALL Java_software_chronicle_enterprise_internals_impl_N env->SetByteArrayRegion(ret, 0, size, bytes); return ret; +#else + throw std::runtime_error("Not supported"); +#endif } /* @@ -63,6 +69,7 @@ JNIEXPORT jbyteArray JNICALL Java_software_chronicle_enterprise_internals_impl_N JNIEXPORT void JNICALL Java_software_chronicle_enterprise_internals_impl_NativeAffinity_setAffinity0 (JNIEnv *env, jclass c, jbyteArray affinity) { +#ifdef __linux__ cpu_set_t mask; const size_t size = sizeof(mask); CPU_ZERO(&mask); @@ -71,6 +78,9 @@ JNIEXPORT void JNICALL Java_software_chronicle_enterprise_internals_impl_NativeA memcpy(&mask, bytes, size); sched_setaffinity(0, size, &mask); +#else + throw std::runtime_error("Not supported"); +#endif } /* @@ -80,7 +90,12 @@ JNIEXPORT void JNICALL Java_software_chronicle_enterprise_internals_impl_NativeA */ JNIEXPORT jint JNICALL Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getProcessId0 (JNIEnv *env, jclass c) { +#ifndef __linux__ + throw std::runtime_error("Not supported"); +#else + return (jint) getpid(); +#endif } /* @@ -90,7 +105,12 @@ JNIEXPORT jint JNICALL Java_software_chronicle_enterprise_internals_impl_NativeA */ JNIEXPORT jint JNICALL Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getThreadId0 (JNIEnv *env, jclass c) { +#ifndef __linux__ + throw std::runtime_error("Not supported"); +#else + return (jint) (pid_t) syscall (SYS_gettid); +#endif } /* @@ -100,6 +120,11 @@ JNIEXPORT jint JNICALL Java_software_chronicle_enterprise_internals_impl_NativeA */ JNIEXPORT jint JNICALL Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getCpu0 (JNIEnv *env, jclass c) { +#ifndef __linux__ + throw std::runtime_error("Not supported"); +#else + return (jint) sched_getcpu(); +#endif } From 830b24f0716104d44e3ac65172746914290c90e1 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 11 Jul 2024 18:06:12 +0100 Subject: [PATCH 052/110] Retrying acquiring a lock after failure to obtain lock file should be an info message, Fixes #130 --- affinity/src/main/java/net/openhft/affinity/LockInventory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index 2ca7eb39e..f1b9b1a6d 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -89,7 +89,7 @@ private static boolean updateLockForCurrentThread(final boolean bind, final Affi throw e; } catch (IOException e) { - LOGGER.warn("Error occurred acquiring lock", e); + LOGGER.info("Error occurred acquiring lock, trying another " + e); } return false; } From ef4c9d0bfc4517a7c8a2afcbdf272bf67653cd64 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 19 Jul 2024 17:54:28 +0100 Subject: [PATCH 053/110] Updating to bom version 2.26ea26 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index ef717e9d5..ec8c8e166 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea26 pom import From 7a51a6bc2440d5eca4eaaf9c38a0d913bb205087 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 19 Jul 2024 17:54:50 +0100 Subject: [PATCH 054/110] [maven-release-plugin] prepare release Java-Thread-Affinity-3.26ea5 --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 6ab139997..75fd793e9 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea5-SNAPSHOT + 3.26ea5 bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea5 scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index ec8c8e166..51dd91634 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea5-SNAPSHOT + 3.26ea5 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea4 + Java-Thread-Affinity-3.26ea5 diff --git a/pom.xml b/pom.xml index 4c0fee020..b5c9c6806 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea5-SNAPSHOT + 3.26ea5 pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea5 From 439e7be8180dcd982fc82a070e56f9683a4ea7cb Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 19 Jul 2024 17:54:54 +0100 Subject: [PATCH 055/110] [maven-release-plugin] prepare for next development iteration --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 75fd793e9..3edb7f160 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea5 + 3.26ea6-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea5 + ea scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index 51dd91634..f27fb9f6d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea5 + 3.26ea6-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea5 + Java-Thread-Affinity-3.26ea4 diff --git a/pom.xml b/pom.xml index b5c9c6806..0d24f5c1e 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea5 + 3.26ea6-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea5 + ea From 9d92e04c421a491a2389b49fc473f79229bdec05 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 19 Jul 2024 17:55:09 +0100 Subject: [PATCH 056/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index f27fb9f6d..65f0dd99d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea26 + 2.26ea-SNAPSHOT pom import From 7f2e43e8d18a9cb0a5425aeffa9935a49093a682 Mon Sep 17 00:00:00 2001 From: Jerry Shea Date: Mon, 7 Oct 2024 11:20:24 +1100 Subject: [PATCH 057/110] fix NPE --- .../net/openhft/affinity/LockInventory.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index f1b9b1a6d..25714b1d1 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.nio.channels.ClosedByInterruptException; +import java.util.Map; import java.util.NavigableMap; import java.util.TreeMap; @@ -117,6 +118,24 @@ public final synchronized void set(CpuLayout cpuLayout) { } locks[cpuLayout.threadId(layoutId)] = lock; } + shrink(physicalCoreLocks); + } + + /** + * If some CPUs are hyper-threaded, but not others, fix up the HT CPUs + */ + private void shrink(NavigableMap physicalCoreLocks) { + for (Map.Entry e : physicalCoreLocks.entrySet()) { + final AffinityLock[] locks = e.getValue(); + for (int i=0; i Date: Mon, 14 Oct 2024 12:11:48 +0100 Subject: [PATCH 058/110] Updating to bom version 2.26ea50 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 65f0dd99d..28b0d7136 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.26ea50 pom import From 14153ba8f339f13e54015bbc7aaa3e816f580e0e Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Mon, 14 Oct 2024 12:12:07 +0100 Subject: [PATCH 059/110] [maven-release-plugin] prepare release Java-Thread-Affinity-3.26ea6 --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 3edb7f160..64931363a 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea6-SNAPSHOT + 3.26ea6 bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea6 scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index 28b0d7136..6235f5a5f 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea6-SNAPSHOT + 3.26ea6 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea4 + Java-Thread-Affinity-3.26ea6 diff --git a/pom.xml b/pom.xml index 0d24f5c1e..cf2b41a59 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea6-SNAPSHOT + 3.26ea6 pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.26ea6 From 3969334cfdebcf8dde596ee26baede100bb0470f Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Mon, 14 Oct 2024 12:12:11 +0100 Subject: [PATCH 060/110] [maven-release-plugin] prepare for next development iteration --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 64931363a..6219ae0cd 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.26ea6 + 3.26ea7-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea6 + ea scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index 6235f5a5f..af2486979 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.26ea6 + 3.26ea7-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea6 + Java-Thread-Affinity-3.26ea4 diff --git a/pom.xml b/pom.xml index cf2b41a59..95460b583 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.26ea6 + 3.26ea7-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea6 + ea From 59952c6f297cf837288b2c9466c0c7bc216be7ad Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Mon, 14 Oct 2024 12:12:25 +0100 Subject: [PATCH 061/110] Reverting back to bom version 2.26ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index af2486979..aeb2f4a2f 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.26ea50 + 2.26ea-SNAPSHOT pom import From 8ba321ce658b3aa498e3785818e34ef19571d0ae Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 11 Nov 2024 16:21:23 +0000 Subject: [PATCH 062/110] x27ea release roll * Roll version to 2.27ea0-SNAPSHOT * Update pom versions to x.27 snapshot versions --- affinity-test/pom.xml | 6 +++--- affinity/pom.xml | 8 ++++---- pom.xml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 6219ae0cd..10a19d819 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -21,12 +21,12 @@ net.openhft java-parent-pom - 1.26.0 + 1.27ea0-SNAPSHOT affinity-test - 3.26ea7-SNAPSHOT + 3.27ea0-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -41,7 +41,7 @@ net.openhft third-party-bom - 3.26.0 + 3.27ea0-SNAPSHOT pom import diff --git a/affinity/pom.xml b/affinity/pom.xml index aeb2f4a2f..d5cbfa12b 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -21,12 +21,12 @@ net.openhft java-parent-pom - 1.26.0 + 1.27ea0-SNAPSHOT affinity - 3.26ea7-SNAPSHOT + 3.27ea0-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -42,14 +42,14 @@ net.openhft third-party-bom - 3.26.0 + 3.27ea0-SNAPSHOT pom import net.openhft chronicle-bom - 2.26ea-SNAPSHOT + 2.27ea-SNAPSHOT pom import diff --git a/pom.xml b/pom.xml index 95460b583..5eb4759bf 100644 --- a/pom.xml +++ b/pom.xml @@ -21,12 +21,12 @@ net.openhft java-parent-pom - 1.26.0 + 1.27ea0-SNAPSHOT Java-Thread-Affinity - 3.26ea7-SNAPSHOT + 3.27ea0-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From 79dfb0475aad8dcf2aa558c3c2d41dc78fe04cb7 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 13 Nov 2024 14:51:15 +0000 Subject: [PATCH 063/110] Bump parent pom and third party bom to release versions (#136) --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 10a19d819..232e47006 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.27ea0-SNAPSHOT + 1.27ea0 @@ -41,7 +41,7 @@ net.openhft third-party-bom - 3.27ea0-SNAPSHOT + 3.27ea0 pom import diff --git a/affinity/pom.xml b/affinity/pom.xml index d5cbfa12b..9e8839580 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.27ea0-SNAPSHOT + 1.27ea0 @@ -42,7 +42,7 @@ net.openhft third-party-bom - 3.27ea0-SNAPSHOT + 3.27ea0 pom import diff --git a/pom.xml b/pom.xml index 5eb4759bf..3f4a19ddc 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.27ea0-SNAPSHOT + 1.27ea0 From 39b85e398acf76c1c7aab9ccdbbea61e999f4891 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 15 Nov 2024 17:37:21 +0000 Subject: [PATCH 064/110] Updating to bom version 2.27ea0 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 9e8839580..74fe31427 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.27ea-SNAPSHOT + 2.27ea0 pom import From a4890dab52e0afe3b89217df6a9c2707a8734c11 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 15 Nov 2024 17:37:41 +0000 Subject: [PATCH 065/110] [maven-release-plugin] prepare release Java-Thread-Affinity-3.27ea0 --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 232e47006..eba35edf0 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.27ea0-SNAPSHOT + 3.27ea0 bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.27ea0 scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index 74fe31427..f41c60851 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.27ea0-SNAPSHOT + 3.27ea0 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea4 + Java-Thread-Affinity-3.27ea0 diff --git a/pom.xml b/pom.xml index 3f4a19ddc..9982c35aa 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.27ea0-SNAPSHOT + 3.27ea0 pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.27ea0 From 880125221b17a20e9a44c3d50809c6495d45ac72 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 15 Nov 2024 17:37:44 +0000 Subject: [PATCH 066/110] [maven-release-plugin] prepare for next development iteration --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index eba35edf0..97b6857dc 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.27ea0 + 3.27ea1-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.27ea0 + ea scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index f41c60851..a308d774f 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.27ea0 + 3.27ea1-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -269,7 +269,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.27ea0 + Java-Thread-Affinity-3.26ea4 diff --git a/pom.xml b/pom.xml index 9982c35aa..d6bd9c4a0 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.27ea0 + 3.27ea1-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.27ea0 + ea From 28d8ca876d57ceb3b40ca6e09bd10d8f883ad63d Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 15 Nov 2024 17:37:59 +0000 Subject: [PATCH 067/110] Reverting back to bom version 2.27ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index a308d774f..6e84f2418 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.27ea0 + 2.27ea-SNAPSHOT pom import From 36c1cec731014df49e16f55419d45f7919178a56 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 22 May 2025 15:16:29 +0100 Subject: [PATCH 068/110] Update copyright year to 2025 in multiple files --- LICENSE | 2 +- affinity-test/pom.xml | 2 +- .../main/java/net/openhft/affinity/osgi/OSGiPlaceholder.java | 2 +- .../test/java/net/openhft/affinity/osgi/OSGiBundleTest.java | 2 +- .../src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java | 2 +- affinity/pom.xml | 2 +- affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp | 2 +- ...are_chronicle_enterprise_internals_impl_NativeAffinity.cpp | 2 +- ...hronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c | 2 +- affinity/src/main/java/net/openhft/affinity/Affinity.java | 2 +- affinity/src/main/java/net/openhft/affinity/AffinityLock.java | 2 +- .../main/java/net/openhft/affinity/AffinityStrategies.java | 2 +- .../src/main/java/net/openhft/affinity/AffinityStrategy.java | 2 +- .../main/java/net/openhft/affinity/AffinityThreadFactory.java | 2 +- .../src/main/java/net/openhft/affinity/BootClassPath.java | 2 +- affinity/src/main/java/net/openhft/affinity/CpuLayout.java | 2 +- affinity/src/main/java/net/openhft/affinity/IAffinity.java | 2 +- affinity/src/main/java/net/openhft/affinity/LockCheck.java | 2 +- .../src/main/java/net/openhft/affinity/LockInventory.java | 2 +- .../main/java/net/openhft/affinity/MicroJitterSampler.java | 4 +--- .../src/main/java/net/openhft/affinity/impl/LinuxHelper.java | 2 +- .../main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java | 2 +- .../src/main/java/net/openhft/affinity/impl/NoCpuLayout.java | 2 +- .../src/main/java/net/openhft/affinity/impl/NullAffinity.java | 2 +- .../main/java/net/openhft/affinity/impl/OSXJNAAffinity.java | 2 +- .../main/java/net/openhft/affinity/impl/PosixJNAAffinity.java | 2 +- .../java/net/openhft/affinity/impl/SolarisJNAAffinity.java | 2 +- .../src/main/java/net/openhft/affinity/impl/Utilities.java | 2 +- .../main/java/net/openhft/affinity/impl/VanillaCpuLayout.java | 2 +- .../main/java/net/openhft/affinity/impl/VersionHelper.java | 2 +- .../java/net/openhft/affinity/impl/WindowsJNAAffinity.java | 2 +- .../affinity/lockchecker/FileLockBasedLockChecker.java | 4 +--- .../java/net/openhft/affinity/lockchecker/LockChecker.java | 4 +--- .../java/net/openhft/affinity/lockchecker/LockReference.java | 4 +--- .../main/java/net/openhft/affinity/main/AffinityTestMain.java | 4 +--- affinity/src/main/java/net/openhft/ticker/ITicker.java | 2 +- affinity/src/main/java/net/openhft/ticker/Ticker.java | 2 +- affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java | 2 +- .../src/main/java/net/openhft/ticker/impl/SystemClock.java | 2 +- .../chronicle/enterprise/internals/impl/NativeAffinity.java | 2 +- .../test/java/net/openhft/affinity/AffinityLockBindMain.java | 2 +- .../src/test/java/net/openhft/affinity/AffinityLockMain.java | 2 +- .../src/test/java/net/openhft/affinity/AffinityLockTest.java | 2 +- .../test/java/net/openhft/affinity/AffinitySupportMain.java | 2 +- .../java/net/openhft/affinity/AffinityThreadFactoryMain.java | 2 +- .../src/test/java/net/openhft/affinity/BaseAffinityTest.java | 4 +--- .../src/test/java/net/openhft/affinity/BootClassPathTest.java | 4 +--- .../test/java/net/openhft/affinity/FileLockLockCheckTest.java | 2 +- .../src/test/java/net/openhft/affinity/InterrupedThread.java | 2 +- .../src/test/java/net/openhft/affinity/LockCheckTest.java | 2 +- .../java/net/openhft/affinity/MultiProcessAffinityTest.java | 4 +--- .../net/openhft/affinity/impl/AbstractAffinityImplTest.java | 2 +- .../java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java | 2 +- .../java/net/openhft/affinity/impl/NativeAffinityImpTest.java | 2 +- .../java/net/openhft/affinity/impl/PosixJNAAffinityTest.java | 2 +- .../java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java | 2 +- .../java/net/openhft/affinity/impl/VersionHelperTest.java | 2 +- .../affinity/testimpl/TestFileLockBasedLockChecker.java | 4 +--- .../src/test/java/net/openhft/ticker/impl/JNIClockTest.java | 2 +- .../chronicle/enterprise/internals/JnaAffinityTest.java | 2 +- .../chronicle/enterprise/internals/NativeAffinityTest.java | 2 +- affinity/src/test/resources/i7.properties | 2 +- pom.xml | 2 +- 63 files changed, 63 insertions(+), 81 deletions(-) diff --git a/LICENSE b/LICENSE index a1993e4de..f7f8b7f7d 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2014-2018 Chronicle Software Ltd + Copyright 2014-2025 chronicle.software Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 97b6857dc..e90b2d811 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -1,6 +1,6 @@ - sonatype-nexus-staging - https://oss.sonatype.org/content/repositories/staging + + true + + chronicle-enterprise-snapshots + Snapshot Repository + https://nexus.chronicle.software/content/repositories/snapshots + + true + chronicle-enterprise-release + https://nexus.chronicle.software/content/repositories/releases @@ -269,7 +276,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.26ea4 + ea From c7e60bb74ca99a5cc2eea78a0a3f1630a4921dd5 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 11:29:12 +0100 Subject: [PATCH 070/110] Add requirements document for Java Thread Affinity library and update README with OS support details --- README.adoc | 129 +++++++- affinity/src/main/adoc/requirements.adoc | 297 ++++++++++++++++++ .../openhft/affinity/impl/LinuxHelper.java | 6 +- 3 files changed, 425 insertions(+), 7 deletions(-) create mode 100644 affinity/src/main/adoc/requirements.adoc diff --git a/README.adoc b/README.adoc index 773c4ffa7..91b0eeb06 100644 --- a/README.adoc +++ b/README.adoc @@ -17,6 +17,20 @@ OpenHFT Java Thread Affinity library See https://github.com/OpenHFT/Java-Thread-Affinity/tree/master/affinity/src/test/java[affinity/src/test/java] for working examples of how to use this library. +=== Supported operating systems + +The library detects the running platform in `Affinity.java` and selects an +implementation for that OS. Features differ between systems: + +* *Linux* - full affinity control via JNA. The implementation can get and set + thread affinity, query the current CPU, and obtain process and thread IDs. +* *Windows* - thread affinity is managed through the kernel API. Process and + thread IDs are available, while `getCpu()` returns `-1`. +* *macOS* - provides process and thread IDs but does not modify affinity and + reports the CPU id as `-1`. +* *Solaris* - mirrors the macOS implementation: only process and thread IDs are + returned with no affinity or CPU querying support. + === Changes * V3.2.0 - Add support for text configuration @@ -47,6 +61,12 @@ for the artifacts `jna` and `jna-platform` in the project's `pom` file. sudo yum install jna +=== Installing JNA on Windows + + choco install jna + +Or download jna.jar and jna-platform.jar from the JNA project and add them to your classpath. + === How does CPU allocation work? The library will read your `/proc/cpuinfo` if you have one or provide one and it will determine your CPU layout. If you don't have one it will assume every CPU is on one CPU socket. @@ -54,7 +74,20 @@ The library looks for isolated CPUs determined by looking at the CPUs you are no i.e. if you have 16 CPUs but 8 of them are not available for general use (as determined by the affinity of the process on startup) it will start assigning to those CPUs. Note: if you have more than one process using this library you need to specify which CPUs the process can use otherwise it will assign the same CPUs to both processes. -To control which CPUs a process can use, add -Daffinity.reserved={cpu-mask-in-hex} to the command line of the process. + +To control which CPUs a process can use, add `-Daffinity.reserved={cpu-mask-in-hex}` +to the command line of the process. The mask is a hexadecimal bit mask without +the `0x` prefix where bit `0` represents CPU `0`, bit `1` represents CPU `1` and +so on. Multiple CPUs can be specified by setting more than one bit. + +For example: + +* `-Daffinity.reserved=2` reserves only CPU `1`. +* `-Daffinity.reserved=6` reserves CPUs `1` and `2`. +* `-Daffinity.reserved=10` reserves CPUs `1` and `3` (hexadecimal `a`). + +Use an appropriate mask when starting each process to avoid reserving the same +cores for multiple JVMs. Note: the CPU 0 is reserved for the Operating System, it has to run somewhere. @@ -76,6 +109,21 @@ To isolate the 1st and 3rd CPU cores (CPU numbers start from 0) on your system, isolcpus=1,3 +Using GRUB +[source] +---- +sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=1,3 /' /etc/default/grub +sudo update-grub +sudo reboot +---- + +Using systemd-boot +[source] +---- +sudo sed -i 's/^options \(.*\)/options \1 isolcpus=1,3/' /boot/loader/entries/*.conf +sudo reboot +---- + == Using AffinityLock === Acquiring a CPU lock for a thread @@ -127,7 +175,21 @@ try (final AffinityLock al = AffinityLock.acquireLock()) { t.start(); } ---- -In this example, the library will prefer a free CPU on the same Socket as the first thread, otherwise it will pick any free CPU. +In this example, the library will prefer a free CPU on the same Socket as the first thread, otherwise it will pick any free CPU. + +=== Affinity strategies +The `AffinityStrategies` enum defines hints for selecting a CPU relative to an existing lock. + +[options="header",cols="1,3"] +|=== +| Strategy | Meaning + +|`ANY`|Use any available CPU. +|`SAME_CORE`|Select a CPU on the same core. +|`SAME_SOCKET`|Select a CPU on the same socket but a different core. +|`DIFFERENT_CORE`|Select a CPU on another core (possibly another socket). +|`DIFFERENT_SOCKET`|Select a CPU on a different socket. +|=== === Getting the thread id You can get the current thread id using @@ -157,10 +219,50 @@ long reservedAffinity = AffinityLock.RESERVED_AFFINITY; ---- If you want to get/set the affinity directly you can do [source, java] ----- +---- long currentAffinity = AffinitySupport.getAffinity(); AffinitySupport.setAffinity(1L << 5); // lock to CPU 5. ----- +---- + +=== Understanding dumpLocks() output + +Several examples print the current CPU assignments using `AffinityLock.dumpLocks()`. +Each line of the output begins with the zero based CPU id followed by the status +of that CPU. Example output might look like: + +[source] +---- +0: Reserved for this application +1: Thread[reader,5,main] alive=true +2: General use CPU +3: CPU not available +---- + +The number on each line is the logical CPU index as recognised by the library. +The text after the colon describes whether that CPU is free, reserved or already +bound to a thread. Use these indices when calling `AffinityLock.acquireLock(n)` +or when constructing explicit affinity masks. + +=== Lock file directory + +AffinityLock stores a small lock file for each CPU. These files are placed in +the directory specified by the `java.io.tmpdir` system property, which by +default points to your system's temporary directory (usually `/tmp` on Linux). + +If you want to keep the lock files elsewhere, set this property before using any +affinity APIs: + +[source, bash] +---- +java -Djava.io.tmpdir=/path/to/dir ... +---- + +or in code + +[source, java] +---- +System.setProperty("java.io.tmpdir", "/path/to/dir"); +---- === Debugging affinity state @@ -185,6 +287,25 @@ $ for i in "$(ls cpu-*)"; ---- +== Using AffinityThreadFactory + +`AffinityThreadFactory` binds each thread it creates according to a set of +`AffinityStrategy` rules. This allows executors to automatically run tasks on +cores selected by the library. + +[source, java] +---- +ExecutorService es = Executors.newFixedThreadPool(4, + new AffinityThreadFactory("worker", + AffinityStrategies.SAME_CORE, + AffinityStrategies.DIFFERENT_SOCKET, + AffinityStrategies.ANY)); +es.submit(() -> { + // your task here +}); +System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks()); +---- + == Support Material https://groups.google.com/forum/?hl=en-GB#!forum/java-thread-affinity[Java Thread Affinity support group] diff --git a/affinity/src/main/adoc/requirements.adoc b/affinity/src/main/adoc/requirements.adoc new file mode 100644 index 000000000..f15cf0ed4 --- /dev/null +++ b/affinity/src/main/adoc/requirements.adoc @@ -0,0 +1,297 @@ += Requirements Document: Java Thread Affinity +Author: Gemini AI +Date: 23 May 2025 +Version: 1.0 +:toc: left +:toclevels: 3 +:sectnums: + +== 1. Introduction + +This document outlines the requirements for the *Java Thread Affinity* library. The primary purpose of this library is to provide Java applications with the capability to control Central Processing Unit (CPU) affinity for their threads. This allows developers to bind specific threads to designated CPU cores, which can lead to performance improvements, especially in latency-sensitive applications, by reducing context switching and improving cache utilisation. + +The library aims to offer a cross-platform API, with the most comprehensive support for Linux systems, leveraging Java Native Access (JNA) and, where applicable, Java Native Interface (JNI) for low-level system interactions. + +== 2. Scope + +The scope of the Java Thread Affinity project includes: + +* Providing mechanisms to get and set thread affinity on supported operating systems. +* Offering a CPU locking mechanism (`AffinityLock`) to manage core reservations for threads or entire cores. +* Detecting or allowing specification of the CPU layout (sockets, cores, threads per core). +* Providing a high-resolution timer. +* Supporting inter-process lock checking for CPU core reservations. +* Delivering a thread factory that assigns affinity to newly created threads. +* Packaging the core library and an OSGi-compatible test bundle. + +== 3. Definitions, Acronyms, and Abbreviations + +* *CPU*: Central Processing Unit +* *JNA*: Java Native Access +* *JNI*: Java Native Interface +* *OS*: Operating System +* *PID*: Process Identifier +* *OSGi*: Open Service Gateway initiative +* *POM*: Project Object Model (Maven) +* *API*: Application Programming Interface + +== 4. References + +* Project Repository: https://github.com/OpenHFT/Java-Thread-Affinity +* JNA: https://github.com/java-native-access/jna + +== 5. Project Overview + +The *Java Thread Affinity* library enables fine-grained control over which CPU cores Java threads execute on. This is particularly beneficial for high-performance computing and low-latency applications where minimising jitter and maximising cache efficiency is critical. The library abstracts OS-specific details, providing a unified Java API. + +=== 5.1. Purpose + +* To allow Java threads to be bound to specific CPU cores. +* To provide tools for understanding and managing CPU topology from within a Java application. +* To offer a high-resolution timing mechanism. + +=== 5.2. Benefits + +* _Performance Improvement_: Reduced thread migration and context switching. +* _Cache Efficiency_: Better utilisation of CPU caches (L1, L2, L3). +* _Jitter Reduction_: More predictable thread execution times. + +== 6. Functional Requirements + +=== 6.1. Core Affinity Control (net.openhft.affinity.Affinity) + +* *FR1*: The system _shall_ allow setting the affinity of the current thread to a specific CPU core or a set of cores (BitSet). +** `Affinity.setAffinity(BitSet affinity)` +** `Affinity.setAffinity(int cpu)` +* *FR2*: The system _shall_ allow retrieving the current affinity mask of the current thread. +** `Affinity.getAffinity()` +* *FR3*: The system _shall_ allow querying the logical CPU ID the current thread is running on. +** `Affinity.getCpu()` +* *FR4*: The system _shall_ allow retrieving the native process ID of the current Java process. +** `IAffinity.getProcessId()` +* *FR5*: The system _shall_ allow retrieving the native thread ID of the current Java thread. +** `IAffinity.getThreadId()` +** `Affinity.setThreadId()` (to update `Thread.tid` via reflection if available) + +=== 6.2. CPU Lock Management (net.openhft.affinity.AffinityLock) + +* *FR6.1*: The system _shall_ provide a mechanism to acquire an exclusive lock on an available CPU core for the current thread. +** `AffinityLock.acquireLock()` +** `AffinityLock.acquireLock(boolean bind)` +** `AffinityLock.acquireLock(int cpuId)` +** `AffinityLock.acquireLock(String desc)` (e.g., "last", "last-N", "N", "any", "none", "csv:1,2,3") +* *FR6.2*: The system _shall_ provide a mechanism to acquire an exclusive lock on an entire physical core (including all its logical CPUs/hyper-threads). +** `AffinityLock.acquireCore()` +** `AffinityLock.acquireCore(boolean bind)` +* *FR6.3*: Acquired locks _shall_ be releasable, restoring the thread's affinity to a base state or a defined default. +** `AffinityLock.release()` +** `AffinityLock.close()` (for try-with-resources) +* *FR6.4*: The system _shall_ support affinity strategies for acquiring new locks relative to existing locks (e.g., same core, same socket, different core, different socket). +** `AffinityLock.acquireLock(AffinityStrategy... strategies)` +** `AffinityStrategies` enum: `ANY`, `SAME_CORE`, `SAME_SOCKET`, `DIFFERENT_CORE`, `DIFFERENT_SOCKET`. +* *FR6.5*: The system _shall_ provide a method to dump the current status of all CPU locks managed by the library. +** `AffinityLock.dumpLocks()` +* *FR6.6*: The system _shall_ allow querying if a lock is allocated and bound. +** `AffinityLock.isAllocated()` +** `AffinityLock.isBound()` + +=== 6.3. CPU Layout Detection (net.openhft.affinity.CpuLayout) + +* *FR7.1*: On Linux, the system _shall_ attempt to automatically detect the CPU layout (sockets, cores per socket, threads per core) by parsing `/proc/cpuinfo`. +** `VanillaCpuLayout.fromCpuInfo()` +* *FR7.2*: The system _shall_ allow applications to programmatically define the CPU layout. +** `AffinityLock.cpuLayout(CpuLayout cpuLayout)` +* *FR7.3*: The CPU layout _shall_ provide information about: +** Total number of logical CPUs: `CpuLayout.cpus()` +** Number of sockets: `CpuLayout.sockets()` +** Cores per socket: `CpuLayout.coresPerSocket()` +** Threads per core: `CpuLayout.threadsPerCore()` +** Mapping a logical CPU ID to its socket, core, and thread ID: `socketId(int)`, `coreId(int)`, `threadId(int)`. +** Hyper-threaded pair for a CPU: `pair(int)`. + +=== 6.4. High-Resolution Timer (net.openhft.ticker.Ticker) + +* *FR8.1*: The system _shall_ provide a high-resolution time source. +** `Ticker.ticks()` (raw timer ticks) +** `Ticker.nanoTime()` (ticks converted to nanoseconds) +* *FR8.2*: If native JNI components are available and loaded (specifically `libCEInternals.so`), the timer _shall_ attempt to use `rdtsc` (Read Time-Stamp Counter). +** `JNIClock.rdtsc0()` +* *FR8.3*: If JNI-based `rdtsc` is not available, the timer _shall_ fall back to `System.nanoTime()`. +** `SystemClock.INSTANCE` +* *FR8.4*: The timer _shall_ provide methods to convert ticks to nanoseconds and microseconds. +** `ITicker.toNanos(long ticks)` +** `ITicker.toMicros(double ticks)` + +=== 6.5. OS-Specific Implementations (net.openhft.affinity.impl) + +* *FR9.1*: The system _shall_ provide tailored implementations of `IAffinity` for different operating systems: +** *Linux*: Full affinity control, CPU ID, Process ID, Thread ID via JNA (`LinuxJNAAffinity`, `PosixJNAAffinity`) or JNI (`NativeAffinity`). +** *Windows*: Thread affinity control, Process ID, Thread ID via JNA (`WindowsJNAAffinity`). `getCpu()` returns -1. +** *macOS*: Process ID, Thread ID via JNA (`OSXJNAAffinity`). No affinity modification; `getCpu()` returns -1. +** *Solaris*: Process ID, Thread ID via JNA (`SolarisJNAAffinity`). No affinity modification; `getCpu()` returns -1. +* *FR9.2*: A `NullAffinity` implementation _shall_ be used as a fallback if no suitable native implementation can be loaded or for unsupported OS. + +=== 6.6. Affinity Thread Factory (net.openhft.affinity.AffinityThreadFactory) + +* *FR10.1*: The system _shall_ provide a `ThreadFactory` that assigns affinity to newly created threads based on specified `AffinityStrategy` rules. +** `new AffinityThreadFactory(String name, AffinityStrategy... strategies)` +* *FR10.2*: If no strategies are provided, `AffinityStrategies.ANY` _shall_ be used by default. + +=== 6.7. Inter-Process Lock Checking (net.openhft.affinity.lockchecker) + +* *FR11.1*: On Linux, the system _shall_ provide a mechanism to check if a specific CPU core is free or already locked by another process. +** `LockCheck.isCpuFree(int cpu)` +* *FR11.2*: This mechanism _shall_ use file-based locks located in the directory specified by the `java.io.tmpdir` system property. +** `FileLockBasedLockChecker` +* *FR11.3*: The system _shall_ allow obtaining and releasing these inter-process locks for specified CPU IDs. +** `LockChecker.obtainLock(int id, int id2, String metaInfo)` +** `LockChecker.releaseLock(int id)` +* *FR11.4*: The system _shall_ store meta-information (e.g., PID of the locking process) within the lock file and allow its retrieval. +** `LockChecker.getMetaInfo(int id)` + +=== 6.8. Native Code Compilation (C/C++) + +* *FR12.1*: The system _shall_ include C/C++ source code for native functions required for affinity and timer operations on Linux and macOS. + ** `software_chronicle_enterprise_internals_impl_NativeAffinity.cpp` (Linux) + ** `software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c` (macOS) + ** `net_openhft_ticker_impl_JNIClock.cpp` (for `rdtsc`) +* *FR12.2*: A Makefile _shall_ be provided to compile the native C/C++ code into a shared library (`libCEInternals.so`). +* *FR12.3*: The Java code _shall_ load this native library if available. +** `software.chronicle.enterprise.internals.impl.NativeAffinity.loadAffinityNativeLibrary()` + +== 7. Non-Functional Requirements + +* *NFR1. Platform Support*: +** *Primary Support*: Linux (full functionality). +** *Partial Support*: Windows (affinity setting, PID/TID, no `getCpu()`). +** *Limited Support*: macOS, Solaris (PID/TID only, no affinity setting or `getCpu()`). +* *NFR2. Dependencies*: +** *JNA*: `net.java.dev.jna:jna`, `net.java.dev.jna:jna-platform`. Version 5.x or higher is recommended for full functionality. The project currently uses version 4.4.0 (as per README, though POMs might show updates). +** *SLF4J API*: `org.slf4j:slf4j-api` for logging. +** *JetBrains Annotations*: `org.jetbrains:annotations` for code quality. +* *NFR3. Performance*: The library _should_ introduce minimal overhead. Native calls _should_ be efficient. The primary goal is to enable performance improvements in the client application. +* *NFR4. Licensing*: The project _shall_ be licensed under the Apache License, Version 2.0. +* *NFR5. Build System*: The project _shall_ use Apache Maven for building and dependency management. +* *NFR6. Language*: +** Core library _shall_ be implemented in Java (1.8+ as per POM). +** Native components _shall_ be implemented in C/C++. +* *NFR7. Usability*: +** The API _should_ be clear and relatively simple to use. +** Javadoc _shall_ be provided for public APIs. +** Example usage _shall_ be available (e.g., in test sources and README). +* *NFR8. Error Handling and Resilience*: +** The library _shall_ degrade gracefully if JNA or native libraries are not available or if an OS does not support certain features (e.g., falling back to `NullAffinity`). +** Errors during native calls _should_ be appropriately logged and/or propagated as exceptions. +* *NFR9. Configuration*: +** Reserved CPUs for the application _shall_ be configurable via the system property `affinity.reserved={hex-mask}`. +** The lock file directory _shall_ default to `java.io.tmpdir` and be overridable by setting this system property. +* *NFR10. OSGi Support*: The `affinity-test` module _shall_ be packaged as an OSGi bundle, demonstrating OSGi compatibility. +* *NFR11. Language Style*: Code and documentation _shall_ use British English, except for established technical US spellings (e.g., `synchronized`). + +== 8. System Architecture + +=== 8.1. High-Level Architecture + +The Java Thread Affinity library is a Java-based system that interfaces with the underlying operating system through JNA (primarily) and JNI (for specific `libCEInternals.so` functionalities). It abstracts OS-specific system calls related to thread affinity, CPU information, and timing. + +=== 8.2. Key Components + +* *`net.openhft.affinity.Affinity`*: Main public API facade for basic affinity operations. +* *`net.openhft.affinity.IAffinity`*: Interface defining the contract for OS-specific implementations. +** Concrete Implementations: `LinuxJNAAffinity`, `WindowsJNAAffinity`, `OSXJNAAffinity`, `SolarisJNAAffinity`, `PosixJNAAffinity`, `NativeAffinity` (JNI), `NullAffinity`. +* *`net.openhft.affinity.AffinityLock`*: Manages CPU reservations and bindings. +* *`net.openhft.affinity.LockInventory`*: Tracks the state of CPU locks based on `CpuLayout`. +* *`net.openhft.affinity.CpuLayout`*: Interface for CPU topology information. +** `VanillaCpuLayout`: Parses `/proc/cpuinfo` or properties files. +** `NoCpuLayout`: Default layout if detection fails. +* *`net.openhft.affinity.AffinityStrategies`*: Enum defining strategies for selecting CPUs. +* *`net.openhft.affinity.AffinityThreadFactory`*: A `java.util.concurrent.ThreadFactory` that sets affinity for new threads. +* *`net.openhft.ticker.Ticker`*: Provides high-resolution time. +** `JNIClock`: Uses `rdtsc` via JNI. +** `SystemClock`: Uses `System.nanoTime()`. +* *`net.openhft.affinity.lockchecker.LockChecker`*: Interface for inter-process lock management. +** `FileLockBasedLockChecker`: Implementation using file system locks. +* *Native Code (`src/main/c`)*: C/C++ sources for `libCEInternals.so` providing functions like `getAffinity0`, `setAffinity0` (Linux JNI), `rdtsc0`. + +=== 8.3. Maven Modules + +* *`Java-Thread-Affinity` (Parent POM)*: Aggregates sub-modules. +** Group ID: `net.openhft` +** Artifact ID: `Java-Thread-Affinity` +* *`affinity` (Core Library)*: Contains the main library code, JNA/JNI integrations, and native sources. +** Artifact ID: `affinity` +** Packaging: `bundle` (OSGi compatible) +* *`affinity-test` (Test Module)*: Contains OSGi integration tests and example usage. +** Artifact ID: `affinity-test` +** Packaging: `bundle` + +== 9. Native Components (libCEInternals.so) + +The library can utilise an optional native shared library, `libCEInternals.so`, for certain operations, primarily on Linux. + +* *Purpose*: Provides direct JNI implementations for thread affinity and the `rdtsc` timer. +* *Source Location*: `Java-Thread-Affinity/affinity/src/main/c/` +* *Build*: Compiled using the `Makefile` in the source directory (typically invoked by Maven's `exec-maven-plugin`). +* *Key Native Functions Implemented*: +** `Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getAffinity0` +** `Java_software_chronicle_enterprise_internals_impl_NativeAffinity_setAffinity0` +** `Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getCpu0` +** `Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getProcessId0` +** `Java_software_chronicle_enterprise_internals_impl_NativeAffinity_getThreadId0` +** `Java_net_openhft_ticker_impl_JNIClock_rdtsc0` +* *Platform Specifics*: +** *Linux*: Uses `sched_getaffinity`, `sched_setaffinity`, `sched_getcpu`, `getpid`, `syscall(SYS_gettid)`. +** *macOS*: (Separate C file `software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c`) Uses `pthread_mach_thread_np`, `thread_policy_get`, `thread_policy_set`. Note: JNA implementations are generally preferred on macOS. +* *Loading*: The `NativeAffinity.java` class attempts to load `System.loadLibrary("CEInternals")`. + +== 10. API Overview + +A brief overview of the primary public classes and interfaces: + +* *`net.openhft.affinity.Affinity`*: +** Static utility methods for basic affinity operations: `getAffinity()`, `setAffinity(BitSet)`, `setAffinity(int cpu)`, `getCpu()`, `getThreadId()`. +** Manages selection of the appropriate `IAffinity` implementation. +* *`net.openhft.affinity.AffinityLock`*: +** Manages acquisition and release of CPU locks: `acquireLock()`, `acquireCore()`, `release()`, `close()`. +** Configures CPU layout: `cpuLayout(CpuLayout)`. +** Provides information about reserved CPUs: `BASE_AFFINITY`, `RESERVED_AFFINITY`. +* *`net.openhft.affinity.AffinityStrategies`*: +** Enum defining CPU selection strategies for `AffinityLock`. +* *`net.openhft.affinity.CpuLayout`*: +** Interface to describe the machine's CPU topology. +* *`net.openhft.affinity.IAffinity`*: +** Core interface implemented by OS-specific providers. +* *`net.openhft.ticker.Ticker`*: +** Static utility for accessing high-resolution time: `ticks()`, `nanoTime()`. +* *`net.openhft.affinity.AffinityThreadFactory`*: +** Implements `java.util.concurrent.ThreadFactory` to create threads with specific affinity settings. + +== 11. Build and Deployment + +* The project is built using Apache Maven. +* The main artifact `net.openhft:affinity` is an OSGi bundle. +* Dependencies are managed via `pom.xml` files, including a `third-party-bom` and `chronicle-bom`. +* The `make-c` profile in `affinity/pom.xml` triggers the compilation of native C code using `make`. +* The `maven-bundle-plugin` is used to generate OSGi manifest information. +* The `maven-scm-publish-plugin` is configured for publishing Javadoc to `gh-pages`. + +== 12. Testing + +The project includes a comprehensive suite of tests: + +* *Unit Tests*: Located in `affinity/src/test/java/`. +** `NativeAffinityTest`, `JnaAffinityTest`: Test core JNI/JNA functionalities. +** `AffinityLockTest`: Tests `AffinityLock` logic, including descriptions and inter-thread lock acquisition. +** `VanillaCpuLayoutTest`, `VanillaCpuLayoutPropertiesParseTest`: Test parsing of `cpuinfo` files and properties files for CPU layout. +** `TickerTest`, `JNIClockTest`: Test timer implementations. +** `LockCheckTest`, `FileLockLockCheckTest`: Test inter-process lock checking. +** `MultiProcessAffinityTest`: Tests affinity locking behavior across multiple Java processes. +* *OSGi Bundle Tests*: Located in `affinity-test/src/test/java/net/openhft/affinity/osgi/`. +** `OSGiBundleTest`: Verifies bundle activation and package exports in an OSGi environment using Pax Exam. +* *Test Resources*: Includes sample `cpuinfo` files for various architectures and corresponding properties files to test layout parsing. +** `affinity/src/test/resources/` +* *Test Infrastructure*: +** `BaseAffinityTest`: Provides common setup for tests, including temporary folder management for lock files. +** `chronicle-test-framework`: Used for some test utilities, like `JavaProcessBuilder` for multi-process tests. + +The tests cover various aspects including basic affinity setting, CPU layout parsing, lock management, multi-threading scenarios, multi-process contention, and OSGi integration. diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java index efde99972..df5cbbc3d 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java @@ -66,9 +66,9 @@ cpu_set_t sched_getaffinity() { return cpuset; } - public static void sched_setaffinity(final BitSet affinity) { - sched_setaffinity(0, affinity); - } + public static void sched_setaffinity(final BitSet affinity) { + sched_setaffinity(0, affinity); + } public static void sched_setaffinity(final int pid, final BitSet affinity) { final CLibrary lib = CLibrary.INSTANCE; From e6f2812ba24d880ca0afdc538d8162b907ba02bb Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 11:35:11 +0100 Subject: [PATCH 071/110] Enhance documentation for ITicker interface with detailed description of high resolution time source and utility methods --- .../main/java/net/openhft/ticker/ITicker.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/affinity/src/main/java/net/openhft/ticker/ITicker.java b/affinity/src/main/java/net/openhft/ticker/ITicker.java index 5438e51d8..0763f0871 100644 --- a/affinity/src/main/java/net/openhft/ticker/ITicker.java +++ b/affinity/src/main/java/net/openhft/ticker/ITicker.java @@ -17,8 +17,23 @@ package net.openhft.ticker; -/* - * Created by Peter Lawrey on 13/07/15. +/** + * Abstraction of a high resolution time source used throughout the library. + *

+ * Implementations may be based on {@link System#nanoTime()} or platform + * specific timers such as the processor's time stamp counter accessed via + * JNI. The {@linkplain #ticks() tick values} returned are therefore + * implementation dependent. They always increase monotonically but the unit + * they represent can vary from nanoseconds to CPU cycles. + *

+ * Utility methods are provided to convert these raw ticks into conventional + * time units. For example {@link #toNanos(long)} converts the supplied number + * of ticks to nanoseconds and {@link #toMicros(double)} converts them to + * microseconds. + *

+ * This interface is typically accessed via the {@link net.openhft.ticker.Ticker} + * helper class which selects the best available implementation for the + * running platform. */ public interface ITicker { long nanoTime(); From 32f317ae3a8ae1df8278056adb189f3bf64ceb59 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:01:03 +0100 Subject: [PATCH 072/110] Code analysis fixes: Refactor code for consistency and readability, including assertion simplifications and formatting improvements --- .../openhft/affinity/osgi/OSGiBundleTest.java | 2 +- .../openhft/affinity/osgi/OSGiTestBase.java | 2 +- .../java/net/openhft/affinity/Affinity.java | 5 ++-- .../net/openhft/affinity/AffinityLock.java | 26 ++++++++++++------- .../affinity/AffinityThreadFactory.java | 12 ++++----- .../net/openhft/affinity/BootClassPath.java | 5 ++-- .../net/openhft/affinity/LockInventory.java | 12 ++++----- .../openhft/affinity/MicroJitterSampler.java | 1 + .../affinity/impl/LinuxJNAAffinity.java | 2 +- .../openhft/affinity/impl/NullAffinity.java | 2 +- .../openhft/affinity/impl/OSXJNAAffinity.java | 2 +- .../affinity/impl/PosixJNAAffinity.java | 2 +- .../affinity/impl/SolarisJNAAffinity.java | 2 +- .../affinity/impl/VanillaCpuLayout.java | 3 ++- .../openhft/affinity/impl/VersionHelper.java | 4 +-- .../lockchecker/FileLockBasedLockChecker.java | 10 +++---- .../affinity/main/AffinityTestMain.java | 7 ++--- .../net/openhft/ticker/impl/JNIClock.java | 5 ++-- .../openhft/affinity/AffinityLockTest.java | 15 ++++------- .../affinity/AffinityThreadFactoryMain.java | 10 +++---- .../affinity/MultiProcessAffinityTest.java | 19 ++++++++------ .../impl/AbstractAffinityImplTest.java | 8 ++---- .../enterprise/internals/JnaAffinityTest.java | 11 +++----- .../internals/NativeAffinityTest.java | 11 +++----- 24 files changed, 84 insertions(+), 94 deletions(-) diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java index 9d1cfee02..80949898f 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java @@ -64,7 +64,7 @@ public void checkInject() { public void checkBundleState() { final Bundle bundle = findBundle(context, "net.openhft.affinity"); assertNotNull(bundle); - assertEquals(bundle.getState(), Bundle.ACTIVE); + assertEquals(Bundle.ACTIVE, bundle.getState()); } @Test diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java index b50b0a8ce..a1e9fcc96 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java @@ -29,7 +29,7 @@ public class OSGiTestBase { public static Option workspaceBundle(String projectName) { String baseDir = System.getProperty("main.basedir"); - String bundleDir = null; + String bundleDir; bundleDir = String.format("%s/%s/target/classes", baseDir, projectName); if (new File(bundleDir).exists()) { diff --git a/affinity/src/main/java/net/openhft/affinity/Affinity.java b/affinity/src/main/java/net/openhft/affinity/Affinity.java index 034602821..d4654749a 100644 --- a/affinity/src/main/java/net/openhft/affinity/Affinity.java +++ b/affinity/src/main/java/net/openhft/affinity/Affinity.java @@ -190,11 +190,10 @@ public static void setThreadId() { public static boolean isJNAAvailable() { if (JNAAvailable == null) { int majorVersion = Integer.parseInt(Native.VERSION.split("\\.")[0]); - if(majorVersion < 5) { + if (majorVersion < 5) { LOGGER.warn("Affinity library requires JNA version >= 5"); JNAAvailable = false; - } - else { + } else { try { Class.forName("com.sun.jna.Platform"); JNAAvailable = true; diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 5954efcb4..2fcdb4d95 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -131,7 +131,7 @@ private static BitSet getReservedAffinity0() { reservedAffinity = reservedAffinity.trim(); long[] longs = new long[1 + (reservedAffinity.length() - 1) / 16]; int end = reservedAffinity.length(); - for(int i = 0; i < longs.length ; i++) { + for (int i = 0; i < longs.length; i++) { int begin = Math.max(0, end - 16); longs[i] = Long.parseLong(reservedAffinity.substring(begin, end), 16); end = begin; @@ -186,6 +186,9 @@ public static AffinityLock acquireLock(boolean bind) { * @return A handle for an affinity lock. */ public static AffinityLock acquireLock(int cpuId) { + if (cpuId < 0 || cpuId >= PROCESSORS) { + throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpuId); + } return acquireLock(true, cpuId, AffinityStrategies.ANY); } @@ -199,17 +202,18 @@ public static AffinityLock acquireLock(int cpuId) { * @return A handle for an affinity lock, or nolock if no available CPU in the array */ public static AffinityLock acquireLock(int[] cpus) { - for( int cpu : cpus ) - { + for (int cpu : cpus) { + if (cpu < 0 || cpu >= PROCESSORS) { + throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpu); + } AffinityLock lock = tryAcquireLock(true, cpu); - if(lock != null) - { + if (lock != null) { LOGGER.info("Acquired lock on CPU {}", cpu); return lock; } } - LOGGER.warn("Failed to lock any CPU in explicit list " + Arrays.toString(cpus)); + LOGGER.warn("Failed to lock any CPU in explicit list {}", Arrays.toString(cpus)); return LOCK_INVENTORY.noLock(); } @@ -228,7 +232,7 @@ public static AffinityLock acquireLockLastMinus(int n) { *

    *
  • "N" being a positive integer means allocate this CPU,
  • *
  • "last" or "last-N" means allocate from the end,
  • - *
  • "csv:1,2,5,6 eg means allocate first free core from the provided
  • + *
  • "csv:1,2,5,6" eg means allocate first free core from the provided
  • *
  • "any" means allow any
  • *
  • "none" or null means
  • *
  • "0" is not allowed
  • @@ -281,7 +285,7 @@ public static AffinityLock acquireLock(String desc) { } } if (cpuId <= 0) { - System.err.println("Cannot allocate 0 or negative cpuIds '" + desc + "'"); + LOGGER.warn("Cannot allocate 0 or negative cpuIds '{}'", desc); return LOCK_INVENTORY.noLock(); } return acquireLock(cpuId); @@ -309,7 +313,7 @@ private static AffinityLock acquireLock(boolean bind, int cpuId, @NotNull Affini * Try to acquire a lock on the specified core * Returns lock if successful, or null if cpu cannot be acquired * - * @param bind - if true, bind the current thread; if false, reserve a cpu which can be bound later + * @param bind - if true, bind the current thread; if false, reserve a cpu which can be bound later * @param cpuId - the cpu to lock * @return - A handle to an affinity lock on success; null if failed to lock */ @@ -332,7 +336,9 @@ public static String dumpLocks() { private static boolean areAssertionsEnabled() { boolean debug = false; + //noinspection AssertWithSideEffects assert debug = true; + //noinspection ConstantValue return debug; } @@ -450,7 +456,7 @@ public void close() { @Override protected void finalize() throws Throwable { if (bound) { - LOGGER.warn("Affinity lock for " + assignedThread + " was discarded rather than release()d in a controlled manner.", boundHere); + LOGGER.warn("Affinity lock for {} was discarded rather than release()d in a controlled manner.", assignedThread, boundHere); release(); } super.finalize(); diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java b/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java index 91bd4d29b..7f789a4e5 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java @@ -53,13 +53,11 @@ public AffinityThreadFactory(String name, boolean daemon, @NotNull AffinityStrat public synchronized Thread newThread(@NotNull final Runnable r) { String name2 = id <= 1 ? name : (name + '-' + id); id++; - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try (AffinityLock ignored = acquireLockBasedOnLast()) { - assert ignored != null; - r.run(); - } + Thread t = new Thread(() -> { + try (AffinityLock ignored = acquireLockBasedOnLast()) { + //noinspection ConstantValue + assert ignored != null; + r.run(); } }, name2); t.setDaemon(daemon); diff --git a/affinity/src/main/java/net/openhft/affinity/BootClassPath.java b/affinity/src/main/java/net/openhft/affinity/BootClassPath.java index 9dfa07f9d..5ae3ca125 100644 --- a/affinity/src/main/java/net/openhft/affinity/BootClassPath.java +++ b/affinity/src/main/java/net/openhft/affinity/BootClassPath.java @@ -17,6 +17,7 @@ package net.openhft.affinity; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,7 +88,7 @@ private static Set findResourcesInDirectory(final Path path, final Logge try { Files.walkFileTree(path, new SimpleFileVisitor() { @Override - public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + public @NotNull FileVisitResult visitFile(final @NotNull Path file, final @NotNull BasicFileAttributes attrs) throws IOException { if (file.getFileName().toString().endsWith(".class")) { dirResources.add(path.relativize(file).toString()); } @@ -95,7 +96,7 @@ public FileVisitResult visitFile(final Path file, final BasicFileAttributes attr } }); } catch (IOException e) { - logger.warn("Error walking dir: " + path, e); + logger.warn("Error walking dir: {}", path, e); } return dirResources; diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index 4b96edeec..b3743d3b6 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -53,7 +53,7 @@ public static String dumpLocks(@NotNull AffinityLock[] locks) { for (int i = 0; i < locks.length; i++) { AffinityLock al = locks[i]; sb.append(i).append(": "); - sb.append(al.toString()); + sb.append(al); sb.append('\n'); } return sb.toString(); @@ -90,7 +90,7 @@ private static boolean updateLockForCurrentThread(final boolean bind, final Affi throw e; } catch (IOException e) { - LOGGER.info("Error occurred acquiring lock, trying another " + e); + LOGGER.info("Error occurred acquiring lock, trying another {}", String.valueOf(e)); } return false; } @@ -127,7 +127,7 @@ public final synchronized void set(CpuLayout cpuLayout) { private void shrink(NavigableMap physicalCoreLocks) { for (Map.Entry e : physicalCoreLocks.entrySet()) { final AffinityLock[] locks = e.getValue(); - for (int i=0; i cpuDetails = new ArrayList<>(); CpuInfo details = new CpuInfo(); diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java index 5ad224302..616f49232 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java @@ -30,7 +30,7 @@ public VersionHelper(int major_, int minor_, int release_) { } public VersionHelper(String ver) { - if (ver != null && (ver = ver.trim()).length() > 0) { + if (ver != null && !(ver = ver.trim()).isEmpty()) { final String[] parts = ver.split("\\."); major = parts.length > 0 ? Integer.parseInt(parts[0]) : 0; minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; @@ -46,7 +46,7 @@ public String toString() { } public boolean equals(Object o) { - if (o != null && (o instanceof VersionHelper)) { + if (o instanceof VersionHelper) { VersionHelper ver = (VersionHelper) o; return this.major == ver.major && this.minor == ver.minor diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java index c13040e1d..a720efb67 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java @@ -72,7 +72,7 @@ public synchronized boolean isLockFree(int id) { try (final FileLock fileLock = channel.tryLock(0, Long.MAX_VALUE, true)) { if (fileLock != null && fileLock.isValid()) { if (!lockFile.delete()) { // try and clean up the orphaned lock file - LOGGER.debug("Couldn't delete orphaned lock file " + lockFile); + LOGGER.debug("Couldn't delete orphaned lock file {}", lockFile); } return true; } else { @@ -112,7 +112,7 @@ public synchronized boolean obtainLock(int id, String metaInfo) throws IOExcepti attempt++; } } - LOGGER.warn("Exceeded maximum retries for locking CPU " + id + ", failing acquire"); + LOGGER.warn("Exceeded maximum retries for locking CPU {}, failing acquire", id); return false; } @@ -172,7 +172,7 @@ public synchronized boolean releaseLock(int id) { if (locks[id] != null) { final File lockFile = toFile(id); if (!lockFile.delete()) { - LOGGER.warn("Couldn't delete lock file on release: " + lockFile); + LOGGER.warn("Couldn't delete lock file on release: {}", lockFile); } closeQuietly(locks[id].lock, locks[id].channel); locks[id] = null; @@ -188,7 +188,7 @@ private void closeQuietly(AutoCloseable... closeables) { closeable.close(); } } catch (Exception e) { - LOGGER.warn("Error closing " + closeable.getClass().getName(), e); + LOGGER.warn("Error closing {}", closeable.getClass().getName(), e); } } } @@ -238,7 +238,7 @@ private File tmpDir() { /** * Thrown when another process deleted the lock file between us opening the file and acquiring the lock */ - class ConcurrentLockFileDeletionException extends Exception { + static class ConcurrentLockFileDeletionException extends Exception { private static final long serialVersionUID = 0L; } } diff --git a/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java b/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java index 01ec845b3..78ca56302 100644 --- a/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java +++ b/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java @@ -29,11 +29,11 @@ public class AffinityTestMain { public static void main(String[] args) { - int cpus = 1; + int cpus; if (args.length == 0) { cpus = AffinityLock.cpuLayout().cpus() / 12; } else { - cpus = Integer.valueOf(args[0]); + cpus = Integer.parseInt(args[0]); } for (int i = 0; i < cpus; i++) { @@ -50,9 +50,10 @@ private static void acquireAndDoWork() { System.out.println("Thread (" + threadName + ") locked onto cpu " + al.cpuId()); while (true) { - System.out.println(df.format(new Date()) + " - Thread (" + threadName + ") doing work on cpu " + al.cpuId() + ". IsAllocated = " + al.isAllocated() + ", isBound = " + al.isBound() + ". " + al.toString()); + System.out.println(df.format(new Date()) + " - Thread (" + threadName + ") doing work on cpu " + al.cpuId() + ". IsAllocated = " + al.isAllocated() + ", isBound = " + al.isBound() + ". " + al); try { + //noinspection BusyWait Thread.sleep(10000L); } catch (InterruptedException e) { //nothing diff --git a/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java b/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java index b493d6020..58cb01ab6 100644 --- a/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java +++ b/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java @@ -65,13 +65,14 @@ static long tscToNano(final long tsc) { return (tsc * RDTSC_FACTOR) >> FACTOR_BITS; } + @SuppressWarnings("StatementWithEmptyBody") private static void estimateFrequency(int factor) { final long start = System.nanoTime(); long now; - while ((now = System.nanoTime()) == start) { + while (System.nanoTime() == start) { } - long end = start + factor * 1000000; + long end = start + factor * 1000000L; final long start0 = rdtsc0(); while ((now = System.nanoTime()) < end) { } diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index f4d8bf76e..b8a14dd77 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -21,7 +21,6 @@ import net.openhft.affinity.impl.VanillaCpuLayout; import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; import org.hamcrest.MatcherAssert; -import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -217,20 +216,16 @@ public void testGettid() { @Test public void testAffinity() throws InterruptedException { - // System.out.println("Started"); logger.info("Started"); displayStatus(); try (AffinityLock al = AffinityLock.acquireLock()) { System.out.println("Main locked"); displayStatus(); - Thread t = new Thread(new Runnable() { - @Override - public void run() { - AffinityLock al2 = al.acquireLock(AffinityStrategies.SAME_SOCKET, AffinityStrategies.ANY); - System.out.println("Thread-0 locked"); - displayStatus(); - al2.release(); - } + Thread t = new Thread(() -> { + AffinityLock al2 = al.acquireLock(AffinityStrategies.SAME_SOCKET, AffinityStrategies.ANY); + System.out.println("Thread-0 locked"); + displayStatus(); + al2.release(); }); t.start(); t.join(); diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java index 9b7960e01..9052239b3 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java @@ -37,16 +37,14 @@ private AffinityThreadFactoryMain() { public static void main(String... args) throws InterruptedException { for (int i = 0; i < 12; i++) - ES.submit(new Callable() { - @Override - public Void call() throws InterruptedException { - Thread.sleep(100); - return null; - } + ES.submit((Callable) () -> { + Thread.sleep(100); + return null; }); Thread.sleep(200); System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks()); ES.shutdown(); + //noinspection ResultOfMethodCallIgnored ES.awaitTermination(1, TimeUnit.SECONDS); } } diff --git a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java index ed96007fb..6aa948297 100644 --- a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java @@ -53,7 +53,7 @@ public void setUp() { } @Test - public void shouldNotAcquireLockOnCoresLockedByOtherProcesses() throws IOException, InterruptedException { + public void shouldNotAcquireLockOnCoresLockedByOtherProcesses() throws InterruptedException { // run the separate affinity locker final Process affinityLockerProcess = JavaProcessBuilder.create(AffinityLockerProcess.class) .withJvmArguments("-Djava.io.tmpdir=" + folder.getRoot().getAbsolutePath()) @@ -64,6 +64,7 @@ public void shouldNotAcquireLockOnCoresLockedByOtherProcesses() throws IOExcepti // wait for the CPU to be locked long endTime = System.currentTimeMillis() + 5_000; while (LockCheck.isCpuFree(lastCpuId)) { + //noinspection BusyWait Thread.sleep(100); if (System.currentTimeMillis() > endTime) { LOGGER.info("Timed out waiting for the lock to be acquired: isAlive={}, exitCode={}", @@ -83,7 +84,7 @@ public void shouldNotAcquireLockOnCoresLockedByOtherProcesses() throws IOExcepti } @Test - public void shouldAllocateCoresCorrectlyUnderContention() throws IOException, InterruptedException { + public void shouldAllocateCoresCorrectlyUnderContention() throws InterruptedException { final int numberOfLockers = Math.max(2, Math.min(12, Runtime.getRuntime().availableProcessors())) / 2; List lockers = new ArrayList<>(); LOGGER.info("Running test with {} locker processes", numberOfLockers); @@ -99,7 +100,7 @@ public void shouldAllocateCoresCorrectlyUnderContention() throws IOException, In } @Test - public void shouldAllocateCoresCorrectlyUnderContentionWithFailures() throws IOException, InterruptedException { + public void shouldAllocateCoresCorrectlyUnderContentionWithFailures() throws InterruptedException { final int numberOfLockers = Math.max(2, Math.min(12, Runtime.getRuntime().availableProcessors())) / 2; List lockers = new ArrayList<>(); LOGGER.info("Running test with {} locker processes", numberOfLockers); @@ -118,7 +119,7 @@ public void shouldAllocateCoresCorrectlyUnderContentionWithFailures() throws IOE } @Test - public void shouldBeAbleToAcquireLockLeftByOtherProcess() throws IOException, InterruptedException { + public void shouldBeAbleToAcquireLockLeftByOtherProcess() throws InterruptedException { final Process process = JavaProcessBuilder.create(AffinityLockerThatDoesNotReleaseProcess.class) .withJvmArguments("-Djava.io.tmpdir=" + folder.getRoot().getAbsolutePath()) .withProgramArguments("last").start(); @@ -214,12 +215,12 @@ public static void main(String[] args) { String cpuIdToLock = args[0]; try (final AffinityLock affinityLock = AffinityLock.acquireLock(cpuIdToLock)) { - LOGGER.info("Got affinity lock " + affinityLock + " at " + LocalDateTime.now() + ", CPU=" + affinityLock.cpuId()); + LOGGER.info("Got affinity lock {} at {}, CPU={}", affinityLock, LocalDateTime.now(), affinityLock.cpuId()); Thread.sleep(Integer.MAX_VALUE); LOGGER.error("Woke from sleep? this should never happen"); } catch (InterruptedException e) { // expected, just end - LOGGER.info("Interrupted at " + LocalDateTime.now() + " lock is released"); + LOGGER.info("Interrupted at {} lock is released", LocalDateTime.now()); } } } @@ -228,13 +229,13 @@ public static void main(String[] args) { * Acquires a lock then ends */ static class AffinityLockerThatDoesNotReleaseProcess { - private static final Logger LOGGER = LoggerFactory.getLogger(AffinityLockerProcess.class); + private static final Logger LOGGER = LoggerFactory.getLogger(AffinityLockerThatDoesNotReleaseProcess.class); public static void main(String[] args) { String cpuIdToLock = args[0]; final AffinityLock affinityLock = AffinityLock.acquireLock(cpuIdToLock); - LOGGER.info("Got affinity lock " + affinityLock + " at " + LocalDateTime.now() + ", CPU=" + affinityLock.cpuId()); + LOGGER.info("Got affinity lock {} at {}, CPU={}", affinityLock, LocalDateTime.now(), affinityLock.cpuId()); } } @@ -253,12 +254,14 @@ public static void main(String[] args) throws InterruptedException, IOException final long maxValue = Long.MAX_VALUE; // a PID that never exists ByteBuffer buffer = ByteBuffer.wrap((maxValue + "\n").getBytes(StandardCharsets.UTF_8)); while (buffer.hasRemaining()) { + //noinspection ResultOfMethodCallIgnored fc.write(buffer); } } } catch (FileAlreadyExistsException e) { LOGGER.info("Failed, trying again"); } + //noinspection BusyWait Thread.sleep(ThreadLocalRandom.current().nextInt(50)); } } diff --git a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java index 02ed43383..5757e32ba 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java @@ -23,8 +23,7 @@ import java.util.BitSet; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author cheremin @@ -49,10 +48,7 @@ public void getAffinityCompletesGracefully() { @Test public void getAffinityReturnsValidValue() { final BitSet affinity = getImpl().getAffinity(); - assertTrue( - "Affinity mask " + Utilities.toBinaryString(affinity) + " must be non-empty", - !affinity.isEmpty() - ); + assertFalse("Affinity mask " + Utilities.toBinaryString(affinity) + " must be non-empty", affinity.isEmpty()); final long allCoresMask = (1L << CORES) - 1; assertTrue( "Affinity mask " + Utilities.toBinaryString(affinity) + " must be <=(2^" + CORES + "-1 = " + allCoresMask + ")", diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java index db6fa69f4..85f0d7372 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java @@ -27,8 +27,7 @@ import java.util.BitSet; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author peter.lawrey @@ -54,10 +53,7 @@ public void getAffinityCompletesGracefully() { @Test public void getAffinityReturnsValidValue() { final BitSet affinity = getImpl().getAffinity(); - assertTrue( - "Affinity mask " + Utilities.toBinaryString(affinity) + " must be non-empty", - !affinity.isEmpty() - ); + assertFalse("Affinity mask " + Utilities.toBinaryString(affinity) + " must be non-empty", affinity.isEmpty()); final int allCoresMask = (1 << CORES) - 1; assertTrue( "Affinity mask " + Utilities.toBinaryString(affinity) + " must be <=(2^" + CORES + "-1 = " + allCoresMask + ")", @@ -80,8 +76,7 @@ public void getAffinityReturnsValuePreviouslySet() { return; } final IAffinity impl = LinuxJNAAffinity.INSTANCE; - final int cores = CORES; - for (int core = 0; core < cores; core++) { + for (int core = 0; core < CORES; core++) { final BitSet mask = new BitSet(); mask.set(core, true); getAffinityReturnsValuePreviouslySet(impl, mask); diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java index 33de98652..6534082b6 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java @@ -25,8 +25,7 @@ import java.util.BitSet; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * @author peter.lawrey @@ -52,10 +51,7 @@ public void getAffinityCompletesGracefully() { @Test public void getAffinityReturnsValidValue() { final BitSet affinity = getImpl().getAffinity(); - assertTrue( - "Affinity mask " + Utilities.toBinaryString(affinity) + " must be non-empty", - !affinity.isEmpty() - ); + assertFalse("Affinity mask " + Utilities.toBinaryString(affinity) + " must be non-empty", affinity.isEmpty()); final int allCoresMask = (1 << CORES) - 1; assertTrue( "Affinity mask " + Utilities.toBinaryString(affinity) + " must be <=(2^" + CORES + "-1 = " + allCoresMask + ")", @@ -79,8 +75,7 @@ public void getAffinityReturnsValuePreviouslySet() { return; } final IAffinity impl = NativeAffinity.INSTANCE; - final int cores = CORES; - for (int core = 0; core < cores; core++) { + for (int core = 0; core < CORES; core++) { final BitSet mask = new BitSet(); mask.set(core, true); getAffinityReturnsValuePreviouslySet(impl, mask); From 04268d4b8b478628ec8b0f2d4f37e940777da663 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 11:43:04 +0100 Subject: [PATCH 073/110] Added tests for edge cases --- .../affinity/AffinityLockDumpLocksTest.java | 58 +++++++++++++++++ .../affinity/AffinityLockReleaseTest.java | 48 ++++++++++++++ .../AffinityResetToBaseAffinityTest.java | 33 ++++++++++ .../affinity/AffinityThreadFactoryTest.java | 55 ++++++++++++++++ .../impl/CpuInfoLayoutMappingTest.java | 44 +++++++++++++ .../openhft/affinity/impl/UtilitiesTest.java | 64 +++++++++++++++++++ .../VanillaCpuLayoutPropertiesParseTest.java | 50 +++++++++++++++ .../src/test/resources/dual.E5405.properties | 24 +++++++ .../src/test/resources/dual.xeon.properties | 20 ++++++ affinity/src/test/resources/i3.properties | 20 ++++++ 10 files changed, 416 insertions(+) create mode 100644 affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java create mode 100644 affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java create mode 100644 affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java create mode 100644 affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java create mode 100644 affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java create mode 100644 affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java create mode 100644 affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java create mode 100644 affinity/src/test/resources/dual.E5405.properties create mode 100644 affinity/src/test/resources/dual.xeon.properties create mode 100644 affinity/src/test/resources/i3.properties diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java new file mode 100644 index 000000000..e981e4e12 --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java @@ -0,0 +1,58 @@ +package net.openhft.affinity; + +import net.openhft.affinity.impl.VanillaCpuLayout; +import org.junit.Assume; +import org.junit.Test; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertTrue; + +public class AffinityLockDumpLocksTest extends BaseAffinityTest { + + @Test + public void dumpLocksListsThreadsHoldingLocks() throws Exception { + Assume.assumeTrue(new File("/proc/cpuinfo").exists()); + + AffinityLock.cpuLayout(VanillaCpuLayout.fromCpuInfo()); + int nThreads = Math.min(3, Math.max(1, AffinityLock.PROCESSORS - 1)); + CountDownLatch acquired = new CountDownLatch(nThreads); + CountDownLatch release = new CountDownLatch(1); + List threads = new ArrayList<>(); + + for (int i = 0; i < nThreads; i++) { + String name = "worker-" + i; + Thread t = new Thread(() -> { + try (AffinityLock lock = AffinityLock.acquireLock()) { + supressUnusedWarning(lock); + acquired.countDown(); + release.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }, name); + threads.add(t); + t.start(); + } + + assertTrue("threads failed to acquire locks", acquired.await(5, TimeUnit.SECONDS)); + + String dump = AffinityLock.dumpLocks(); + for (Thread t : threads) { + assertTrue("Missing entry for " + t.getName(), dump.contains(t.getName())); + } + + release.countDown(); + for (Thread t : threads) { + t.join(); + } + } + + static void supressUnusedWarning(AutoCloseable c) { + // do nothing + } +} diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java new file mode 100644 index 000000000..4cbc15f4d --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2025 chronicle.software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.affinity; + +import net.openhft.affinity.impl.VanillaCpuLayout; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; + +/** + * Unit test to verify that releasing an {@link AffinityLock} restores the + * affinity mask back to {@link AffinityLock#BASE_AFFINITY}. + */ +public class AffinityLockReleaseTest extends BaseAffinityTest { + + @Test + public void acquireAndReleaseShouldRestoreBaseAffinity() throws Exception { + if (!new File("/proc/cpuinfo").exists()) { + System.out.println("Cannot run affinity test as this system doesn't have a /proc/cpuinfo file"); + return; + } + + // initialise CPU layout from the running machine so acquireLock works + AffinityLock.cpuLayout(VanillaCpuLayout.fromCpuInfo()); + + assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); + AffinityLock lock = AffinityLock.acquireLock(); + assertEquals(1, Affinity.getAffinity().cardinality()); + lock.release(); + assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); + } +} diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java new file mode 100644 index 000000000..502cb0e0b --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java @@ -0,0 +1,33 @@ +package net.openhft.affinity; + +import net.openhft.affinity.impl.VanillaCpuLayout; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; + +public class AffinityResetToBaseAffinityTest extends BaseAffinityTest { + + @Test + public void resettingShouldRestoreBaseAffinity() throws Exception { + if (!new File("/proc/cpuinfo").exists()) { + System.out.println("Cannot run affinity test as this system doesn't have a /proc/cpuinfo file"); + return; + } + + // initialise CPU layout from the running machine so acquireLock works + AffinityLock.cpuLayout(VanillaCpuLayout.fromCpuInfo()); + + assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); + AffinityLock lock = AffinityLock.acquireLock(); + try { + assertEquals(1, Affinity.getAffinity().cardinality()); + + Affinity.resetToBaseAffinity(); + assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); + } finally { + lock.release(); + } + } +} diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java new file mode 100644 index 000000000..7377cc7ea --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java @@ -0,0 +1,55 @@ +package net.openhft.affinity; + +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.*; + +public class AffinityThreadFactoryTest extends BaseAffinityTest { + + @Before + public void checkLinux() { + Assume.assumeTrue(LockCheck.IS_LINUX); + } + + @Test + public void threadsReceiveDistinctCpus() throws InterruptedException { + int available = Math.max(1, AffinityLock.PROCESSORS - 1); + int nThreads = Math.min(4, available); + + ExecutorService es = Executors.newFixedThreadPool(nThreads, + new AffinityThreadFactory("test")); + + Set cpus = ConcurrentHashMap.newKeySet(); + CountDownLatch ready = new CountDownLatch(nThreads); + CountDownLatch finished = new CountDownLatch(nThreads); + + for (int i = 0; i < nThreads; i++) { + es.submit(() -> { + cpus.add(Affinity.getCpu()); + ready.countDown(); + try { + ready.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + finished.countDown(); + }); + } + + assertTrue(finished.await(5, TimeUnit.SECONDS)); + es.shutdown(); + es.awaitTermination(5, TimeUnit.SECONDS); + + assertFalse(cpus.contains(-1)); + assertEquals(nThreads, cpus.size()); + } +} diff --git a/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java b/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java new file mode 100644 index 000000000..3cee5d4bc --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2016-2025 chronicle.software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.affinity.impl; + +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.Assert.assertEquals; + +public class CpuInfoLayoutMappingTest { + + @Test + public void verifyI7CpuInfoMapping() throws IOException { + final InputStream i7 = getClass().getClassLoader().getResourceAsStream("i7.cpuinfo"); + VanillaCpuLayout vcl = VanillaCpuLayout.fromCpuInfo(i7); + assertEquals( + "0: CpuInfo{socketId=0, coreId=0, threadId=0}\n" + + "1: CpuInfo{socketId=0, coreId=1, threadId=0}\n" + + "2: CpuInfo{socketId=0, coreId=2, threadId=0}\n" + + "3: CpuInfo{socketId=0, coreId=3, threadId=0}\n" + + "4: CpuInfo{socketId=0, coreId=0, threadId=1}\n" + + "5: CpuInfo{socketId=0, coreId=1, threadId=1}\n" + + "6: CpuInfo{socketId=0, coreId=2, threadId=1}\n" + + "7: CpuInfo{socketId=0, coreId=3, threadId=1}\n", + vcl.toString()); + } +} + diff --git a/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java b/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java new file mode 100644 index 000000000..45d05dbfd --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016-2025 chronicle.software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.affinity.impl; + +import org.junit.Test; + +import java.util.BitSet; + +import static org.junit.Assert.assertEquals; + +public class UtilitiesTest { + + private static String hex(BitSet set, int... bits) { + set.clear(); + for (int b : bits) { + set.set(b); + } + return Utilities.toHexString(set); + } + + private static String bin(BitSet set, int... bits) { + set.clear(); + for (int b : bits) { + set.set(b); + } + return Utilities.toBinaryString(set); + } + + @Test + public void testToHexString() { + BitSet set = new BitSet(); + assertEquals("", hex(set)); + assertEquals("1", hex(set, 0)); + assertEquals("10", hex(set, 4)); + assertEquals(Long.toHexString(1L << 63), hex(set, 63)); + assertEquals("01", hex(set, 64)); + assertEquals("101", hex(set, 0, 128)); + } + + @Test + public void testToBinaryString() { + BitSet set = new BitSet(); + assertEquals("", bin(set)); + assertEquals("1", bin(set, 0)); + assertEquals("10000", bin(set, 4)); + assertEquals(Long.toBinaryString(1L << 63), bin(set, 63)); + assertEquals("01", bin(set, 64)); + assertEquals("101", bin(set, 0, 128)); + } +} diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java new file mode 100644 index 000000000..b539ccf98 --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java @@ -0,0 +1,50 @@ +package net.openhft.affinity.impl; + +import org.junit.Test; + +import java.io.InputStream; + +import static org.junit.Assert.assertEquals; + +public class VanillaCpuLayoutPropertiesParseTest { + + @Test + public void testCountsI7() throws Exception { + InputStream is = getClass().getClassLoader().getResourceAsStream("i7.properties"); + VanillaCpuLayout vcl = VanillaCpuLayout.fromProperties(is); + assertEquals(8, vcl.cpus()); + assertEquals(1, vcl.sockets()); + assertEquals(4, vcl.coresPerSocket()); + assertEquals(2, vcl.threadsPerCore()); + } + + @Test + public void testCountsDualXeon() throws Exception { + InputStream is = getClass().getClassLoader().getResourceAsStream("dual.xeon.properties"); + VanillaCpuLayout vcl = VanillaCpuLayout.fromProperties(is); + assertEquals(4, vcl.cpus()); + assertEquals(2, vcl.sockets()); + assertEquals(1, vcl.coresPerSocket()); + assertEquals(2, vcl.threadsPerCore()); + } + + @Test + public void testCountsDualE5405() throws Exception { + InputStream is = getClass().getClassLoader().getResourceAsStream("dual.E5405.properties"); + VanillaCpuLayout vcl = VanillaCpuLayout.fromProperties(is); + assertEquals(8, vcl.cpus()); + assertEquals(2, vcl.sockets()); + assertEquals(4, vcl.coresPerSocket()); + assertEquals(1, vcl.threadsPerCore()); + } + + @Test + public void testCountsI3() throws Exception { + InputStream is = getClass().getClassLoader().getResourceAsStream("i3.properties"); + VanillaCpuLayout vcl = VanillaCpuLayout.fromProperties(is); + assertEquals(4, vcl.cpus()); + assertEquals(1, vcl.sockets()); + assertEquals(2, vcl.coresPerSocket()); + assertEquals(2, vcl.threadsPerCore()); + } +} diff --git a/affinity/src/test/resources/dual.E5405.properties b/affinity/src/test/resources/dual.E5405.properties new file mode 100644 index 000000000..d656b7376 --- /dev/null +++ b/affinity/src/test/resources/dual.E5405.properties @@ -0,0 +1,24 @@ +# +# Copyright 2016-2025 chronicle.software +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +0=0,0,0 +1=0,1,0 +2=0,2,0 +3=0,3,0 +4=1,4,0 +5=1,5,0 +6=1,6,0 +7=1,7,0 diff --git a/affinity/src/test/resources/dual.xeon.properties b/affinity/src/test/resources/dual.xeon.properties new file mode 100644 index 000000000..36fc4ef90 --- /dev/null +++ b/affinity/src/test/resources/dual.xeon.properties @@ -0,0 +1,20 @@ +# +# Copyright 2016-2025 chronicle.software +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +0=0,0,0 +1=0,0,1 +2=3,3,0 +3=3,3,1 diff --git a/affinity/src/test/resources/i3.properties b/affinity/src/test/resources/i3.properties new file mode 100644 index 000000000..ab4e83876 --- /dev/null +++ b/affinity/src/test/resources/i3.properties @@ -0,0 +1,20 @@ +# +# Copyright 2016-2025 chronicle.software +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +0=0,0,0 +1=0,2,0 +2=0,0,1 +3=0,2,1 From e70ae8d05a78b2733d34953db05490ed5ee0b1eb Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:17:03 +0100 Subject: [PATCH 074/110] AffinityLock.acquireCore should lock/unlock all cpus ie 2 when hyperthreaded --- .../net/openhft/affinity/AffinityLock.java | 19 ++++-- .../java/net/openhft/affinity/CpuLayout.java | 6 ++ .../java/net/openhft/affinity/LockCheck.java | 12 ++-- .../net/openhft/affinity/LockInventory.java | 12 ++-- .../openhft/affinity/impl/NoCpuLayout.java | 5 ++ .../affinity/impl/VanillaCpuLayout.java | 13 ++++ .../lockchecker/FileLockBasedLockChecker.java | 18 +++++- .../affinity/lockchecker/LockChecker.java | 2 +- .../openhft/affinity/AffinityLockTest.java | 60 +++++++++++++------ .../affinity/FileLockLockCheckTest.java | 6 +- .../net/openhft/affinity/LockCheckTest.java | 8 +-- .../impl/VanillaCpuLayoutPairTest.java | 56 +++++++++++++++++ 12 files changed, 170 insertions(+), 47 deletions(-) create mode 100644 affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 2fcdb4d95..79d576ac9 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -69,6 +69,7 @@ public class AffinityLock implements Closeable { * Logical ID of the CPU to which this lock belongs to. */ private final int cpuId; + private final int cpuId2; /** * CPU to which this lock belongs to is of general use. */ @@ -88,9 +89,10 @@ public class AffinityLock implements Closeable { Throwable boundHere; private boolean resetAffinity = true; - AffinityLock(int cpuId, boolean base, boolean reservable, LockInventory lockInventory) { + AffinityLock(int cpuId, int cpuId2, boolean base, boolean reservable, LockInventory lockInventory) { this.lockInventory = lockInventory; this.cpuId = cpuId; + this.cpuId2 = cpuId2; this.base = base; this.reservable = reservable; } @@ -133,7 +135,7 @@ private static BitSet getReservedAffinity0() { int end = reservedAffinity.length(); for (int i = 0; i < longs.length; i++) { int begin = Math.max(0, end - 16); - longs[i] = Long.parseLong(reservedAffinity.substring(begin, end), 16); + longs[i] = Long.parseUnsignedLong(reservedAffinity.substring(begin, end), 16); end = begin; } return BitSet.valueOf(longs); @@ -183,11 +185,11 @@ public static AffinityLock acquireLock(boolean bind) { * for defining your thread layout centrally and passing the handle via dependency injection. * * @param cpuId the CPU id to bind to - * @return A handle for an affinity lock. + * @return A handle for an affinity lock, or no lock if no available CPU in the array */ public static AffinityLock acquireLock(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpuId); + return LOCK_INVENTORY.noLock(); } return acquireLock(true, cpuId, AffinityStrategies.ANY); } @@ -204,7 +206,8 @@ public static AffinityLock acquireLock(int cpuId) { public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { if (cpu < 0 || cpu >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpu); + LOGGER.warn("cpuId {} is out of range", cpu); + continue; } AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { @@ -265,7 +268,7 @@ public static AffinityLock acquireLock(String desc) { } else if (desc.startsWith("csv:")) { String content = desc.substring(4); - int[] cpus = Arrays.asList(content.split(",")).stream() + int[] cpus = Arrays.stream(content.split(",")) .map(String::trim) .mapToInt(Integer::parseInt).toArray(); @@ -469,6 +472,10 @@ public int cpuId() { return cpuId; } + public int cpuId2() { + return cpuId2; + } + /** * @return Was a cpu found to bind this lock to. */ diff --git a/affinity/src/main/java/net/openhft/affinity/CpuLayout.java b/affinity/src/main/java/net/openhft/affinity/CpuLayout.java index 7221d7dfb..12cbce61e 100644 --- a/affinity/src/main/java/net/openhft/affinity/CpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/CpuLayout.java @@ -49,4 +49,10 @@ public interface CpuLayout { * @return which thread on a core this cpu is on. */ int threadId(int cpuId); + + /** + * @param cpuId the logical processor number + * @return the hyperthreaded pair number or 0 if not hyperthreaded. + */ + int pair(int cpuId); } diff --git a/affinity/src/main/java/net/openhft/affinity/LockCheck.java b/affinity/src/main/java/net/openhft/affinity/LockCheck.java index 259aaf40b..ac9ca6cc1 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockCheck.java +++ b/affinity/src/main/java/net/openhft/affinity/LockCheck.java @@ -55,8 +55,8 @@ public static boolean isCpuFree(int cpu) { return isLockFree(cpu); } - static boolean replacePid(int cpu, long processID) throws IOException { - return storePid(processID, cpu); + static boolean replacePid(int cpu, int cpu2, long processID) throws IOException { + return storePid(processID, cpu, cpu2); } public static boolean isProcessRunning(long pid) { @@ -70,8 +70,8 @@ public static boolean isProcessRunning(long pid) { * stores the pid in a file, named by the core, the pid is written to the file with the date * below */ - private synchronized static boolean storePid(long processID, int cpu) throws IOException { - return lockChecker.obtainLock(cpu, Long.toString(processID)); + private synchronized static boolean storePid(long processID, int cpu, int cpu2) throws IOException { + return lockChecker.obtainLock(cpu, cpu2, Long.toString(processID)); } private synchronized static boolean isLockFree(int id) { @@ -91,10 +91,10 @@ public static int getProcessForCpu(int core) throws IOException { return EMPTY_PID; } - static boolean updateCpu(int cpu) throws IOException { + static boolean updateCpu(int cpu, int cpu2) throws IOException { if (!canOSSupportOperation()) return true; - return replacePid(cpu, getPID()); + return replacePid(cpu, cpu2, getPID()); } public static void releaseLock(int cpu) { diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index b3743d3b6..0fa41b114 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -82,7 +82,7 @@ private static boolean isAnyCpu(final int cpuId) { */ private static boolean updateLockForCurrentThread(final boolean bind, final AffinityLock al, final boolean wholeCore) throws ClosedByInterruptException { try { - if (LockCheck.updateCpu(al.cpuId())) { + if (LockCheck.updateCpu(al.cpuId(), wholeCore ? al.cpuId2() : 0)) { al.assignCurrentThread(bind, wholeCore); return true; } @@ -108,7 +108,9 @@ public final synchronized void set(CpuLayout cpuLayout) { final boolean base = AffinityLock.BASE_AFFINITY.get(i); final boolean reservable = AffinityLock.RESERVED_AFFINITY.get(i); LOGGER.trace("cpu {} base={} reservable= {}", i, base, reservable); - AffinityLock lock = logicalCoreLocks[i] = newLock(i, base, reservable); + assert logicalCoreLocks != null; + @SuppressWarnings("resource") + AffinityLock lock = logicalCoreLocks[i] = newLock(i, cpuLayout.pair(i), base, reservable); int layoutId = lock.cpuId(); int physicalCore = toPhysicalCore(layoutId); @@ -277,8 +279,8 @@ public final synchronized String dumpLocks() { return dumpLocks(logicalCoreLocks); } - protected AffinityLock newLock(int cpuId, boolean base, boolean reservable) { - return new AffinityLock(cpuId, base, reservable, this); + protected AffinityLock newLock(int cpuId, int cpuId2, boolean base, boolean reservable) { + return new AffinityLock(cpuId, cpuId2, base, reservable, this); } private void reset(CpuLayout cpuLayout) { @@ -301,6 +303,6 @@ private void releaseAffinityLock(final Thread t, final AffinityLock al, final St } public AffinityLock noLock() { - return newLock(AffinityLock.ANY_CPU, false, false); + return newLock(AffinityLock.ANY_CPU, 0, false, false); } } diff --git a/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java b/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java index b22c36cf7..2996bdf0d 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java @@ -64,4 +64,9 @@ public int coreId(int cpuId) { public int threadId(int cpuId) { return 0; } + + @Override + public int pair(int cpuId) { + return 0; + } } diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java b/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java index 7c17d1788..74ff2d580 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java @@ -177,6 +177,19 @@ public int threadId(int cpuId) { return cpuDetails.get(cpuId).threadId; } + @Override + public int pair(int cpuId) { + for (int i = 0; i < cpuDetails.size(); i++) { + CpuInfo info = cpuDetails.get(i); + if (info.socketId == cpuDetails.get(cpuId).socketId && + info.coreId == cpuDetails.get(cpuId).coreId && + info.threadId != cpuDetails.get(cpuId).threadId) { + return i; + } + } + return 0; + } + @NotNull @Override public String toString() { diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java index a720efb67..265d8923f 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java @@ -98,14 +98,25 @@ public synchronized boolean isLockFree(int id) { } @Override - public synchronized boolean obtainLock(int id, String metaInfo) throws IOException { + public synchronized boolean obtainLock(int id, int id2, String metaInfo) throws IOException { int attempt = 0; while (attempt < MAX_LOCK_RETRIES) { try { LockReference lockReference = tryAcquireLockOnFile(id, metaInfo); if (lockReference != null) { - locks[id] = lockReference; - return true; + if (id2 <= 0) { + // no second lock to acquire, return success + locks[id] = lockReference; + return true; + } + LockReference lockReference2 = tryAcquireLockOnFile(id2, metaInfo); + if (lockReference2 != null) { + locks[id] = lockReference; + locks[id2] = lockReference2; + return true; + } else { + releaseLock(id); + } } return false; } catch (ConcurrentLockFileDeletionException e) { @@ -163,6 +174,7 @@ private void writeMetaInfoToFile(FileChannel fc, String metaInfo) throws IOExcep byte[] content = String.format("%s%n%s", metaInfo, dfTL.get().format(new Date())).getBytes(); ByteBuffer buffer = ByteBuffer.wrap(content); while (buffer.hasRemaining()) { + //noinspection ResultOfMethodCallIgnored fc.write(buffer); } } diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java index 8df4eafa1..62a6c2f52 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java @@ -26,7 +26,7 @@ public interface LockChecker { boolean isLockFree(int id); - boolean obtainLock(int id, String metaInfo) throws IOException; + boolean obtainLock(int id, int id2, String metaInfo) throws IOException; boolean releaseLock(int id); diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index b8a14dd77..943ebdad4 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -19,7 +19,6 @@ import net.openhft.affinity.impl.Utilities; import net.openhft.affinity.impl.VanillaCpuLayout; -import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; import org.hamcrest.MatcherAssert; import org.junit.Test; import org.slf4j.Logger; @@ -28,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -43,20 +43,19 @@ public class AffinityLockTest extends BaseAffinityTest { private static final Logger logger = LoggerFactory.getLogger(AffinityLockTest.class); - private final TestFileLockBasedLockChecker lockChecker = new TestFileLockBasedLockChecker(); @Test public void dumpLocksI7() throws IOException { LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("i7.cpuinfo")); AffinityLock[] locks = { - new AffinityLock(0, true, false, lockInventory), - new AffinityLock(1, false, false, lockInventory), - new AffinityLock(2, false, true, lockInventory), - new AffinityLock(3, false, true, lockInventory), - new AffinityLock(4, true, false, lockInventory), - new AffinityLock(5, false, false, lockInventory), - new AffinityLock(6, false, true, lockInventory), - new AffinityLock(7, false, true, lockInventory), + new AffinityLock(0, 0, true, false, lockInventory), + new AffinityLock(1, 5, false, false, lockInventory), + new AffinityLock(2, 6, false, true, lockInventory), + new AffinityLock(3, 7, false, true, lockInventory), + new AffinityLock(4, 0, true, false, lockInventory), + new AffinityLock(5, 1, false, false, lockInventory), + new AffinityLock(6, 2, false, true, lockInventory), + new AffinityLock(7, 3, false, true, lockInventory), }; locks[2].assignedThread = new Thread(new InterrupedThread(), "logger"); locks[2].assignedThread.start(); @@ -86,10 +85,10 @@ public void dumpLocksI7() throws IOException { public void dumpLocksI3() throws IOException { LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("i3.cpuinfo")); AffinityLock[] locks = { - new AffinityLock(0, true, false, lockInventory), - new AffinityLock(1, false, true, lockInventory), - new AffinityLock(2, true, false, lockInventory), - new AffinityLock(3, false, true, lockInventory), + new AffinityLock(0, 0, true, false, lockInventory), + new AffinityLock(1, 3, false, true, lockInventory), + new AffinityLock(2, 0, true, false, lockInventory), + new AffinityLock(3, 1, false, true, lockInventory), }; locks[1].assignedThread = new Thread(new InterrupedThread(), "engine"); locks[1].assignedThread.start(); @@ -109,8 +108,8 @@ public void dumpLocksI3() throws IOException { public void dumpLocksCoreDuo() throws IOException { LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("core.duo.cpuinfo")); AffinityLock[] locks = { - new AffinityLock(0, true, false, lockInventory), - new AffinityLock(1, false, true, lockInventory), + new AffinityLock(0, 0, true, false, lockInventory), + new AffinityLock(1, 0, false, true, lockInventory), }; locks[1].assignedThread = new Thread(new InterrupedThread(), "engine"); locks[1].assignedThread.start(); @@ -253,11 +252,34 @@ public void lockFilesShouldBeRemovedOnRelease() { } final AffinityLock lock = AffinityLock.acquireLock(); - assertTrue(Files.exists(Paths.get(lockChecker.doToFile(lock.cpuId()).getAbsolutePath()))); + Path lockFile = Paths.get(System.getProperty("java.io.tmpdir"), "cpu-" + lock.cpuId() + ".lock"); + assertTrue(Files.exists(lockFile)); lock.release(); - assertFalse(Files.exists(Paths.get(lockChecker.doToFile(lock.cpuId()).getAbsolutePath()))); + assertFalse(Files.exists(lockFile)); + } + + @Test + public void wholeCoreLockReservesAllLogicalCpus() throws IOException { + if (!Utilities.ISLINUX || !new File("/proc/cpuinfo").exists()) { + return; + } + AffinityLock.cpuLayout(VanillaCpuLayout.fromCpuInfo()); + + CpuLayout layout = AffinityLock.cpuLayout(); + try (AffinityLock lock = AffinityLock.acquireCore()) { + int socketId = layout.socketId(lock.cpuId()); + int coreId = layout.coreId(lock.cpuId()); + for (int i = 0; i < layout.cpus(); i++) { + if (layout.socketId(i) == socketId && layout.coreId(i) == coreId) { + assertFalse("CPU " + i + " should be reserved", LockCheck.isCpuFree(i)); + } + } + } + for (int i = 0; i < layout.cpus(); i++) { + assertTrue("CPU " + i + " should not be reserved", LockCheck.isCpuFree(i)); + } } private void displayStatus() { @@ -308,7 +330,7 @@ public void testTooHighCpuId() { @Test public void testTooHighCpuId2() { - try (AffinityLock ignored = AffinityLock.acquireLock(new int[] {123456})) { + try (AffinityLock ignored = AffinityLock.acquireLock(new int[]{123456})) { assertNotNull(ignored); } } diff --git a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java index 82b64435a..1d890d5fe 100644 --- a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java @@ -45,7 +45,7 @@ public void before() { @Test public void test() throws IOException { Assert.assertTrue(LockCheck.isCpuFree(cpu)); - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); Assert.assertEquals(LockCheck.getPID(), LockCheck.getProcessForCpu(cpu)); } @@ -58,13 +58,13 @@ public void testPidOnLinux() { public void testReplace() throws IOException { cpu++; Assert.assertTrue(LockCheck.isCpuFree(cpu + 1)); - LockCheck.replacePid(cpu, 123L); + LockCheck.replacePid(cpu, 0, 123L); Assert.assertEquals(123L, LockCheck.getProcessForCpu(cpu)); } @Test public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); final File file = lockChecker.doToFile(cpu); new RandomAccessFile(file, "rw").setLength(0); diff --git a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java index c7f04465b..40f5d18e5 100644 --- a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java @@ -46,7 +46,7 @@ public void before() { @Test public void test() throws IOException { Assert.assertTrue(LockCheck.isCpuFree(cpu)); - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); Assert.assertEquals(LockCheck.getPID(), LockCheck.getProcessForCpu(cpu)); } @@ -59,13 +59,13 @@ public void testPidOnLinux() { public void testReplace() throws IOException { cpu++; Assert.assertTrue(LockCheck.isCpuFree(cpu + 1)); - LockCheck.replacePid(cpu, 123L); + LockCheck.replacePid(cpu, 0, 123L); Assert.assertEquals(123L, LockCheck.getProcessForCpu(cpu)); } @Test public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); final File file = lockChecker.doToFile(cpu); new RandomAccessFile(file, "rw").setLength(0); @@ -75,7 +75,7 @@ public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { @Test public void shouldNotBlowUpIfPidFileIsCorrupt() throws Exception { - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); final File file = lockChecker.doToFile(cpu); try (final FileWriter writer = new FileWriter(file, false)) { diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java new file mode 100644 index 000000000..99986acd3 --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016-2025 chronicle.software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.affinity.impl; + +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.Assert.assertEquals; + +/** + * Tests for {@link VanillaCpuLayout#pair(int)} using sample cpuinfo files. + */ +public class VanillaCpuLayoutPairTest { + + @Test + public void testPairForI7() throws IOException { + try (InputStream is = getClass().getClassLoader().getResourceAsStream("i7.cpuinfo")) { + VanillaCpuLayout layout = VanillaCpuLayout.fromCpuInfo(is); + assertEquals(4, layout.pair(0)); + assertEquals(5, layout.pair(1)); + assertEquals(6, layout.pair(2)); + assertEquals(7, layout.pair(3)); + assertEquals(0, layout.pair(4)); + assertEquals(1, layout.pair(5)); + assertEquals(2, layout.pair(6)); + assertEquals(3, layout.pair(7)); + } + } + + @Test + public void testPairForI3() throws IOException { + try (InputStream is = getClass().getClassLoader().getResourceAsStream("i3.cpuinfo")) { + VanillaCpuLayout layout = VanillaCpuLayout.fromCpuInfo(is); + assertEquals(2, layout.pair(0)); + assertEquals(3, layout.pair(1)); + assertEquals(0, layout.pair(2)); + assertEquals(1, layout.pair(3)); + } + } +} From 526cfffaac65e3efd725bf361ce713583560d686 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:25:12 +0100 Subject: [PATCH 075/110] Add tests for AffinityLock behavior and exception handling --- .../openhft/affinity/AffinityLockTest.java | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index b8a14dd77..75397348d 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -30,6 +30,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; import static net.openhft.affinity.AffinityLock.PROCESSORS; @@ -300,16 +301,54 @@ public void testAffinityLockDescriptions() { } @Test + public void acquireLockWithoutBindingDoesNotChangeAffinity() { + BitSet before = (BitSet) Affinity.getAffinity().clone(); + try (AffinityLock lock = AffinityLock.acquireLock(false)) { + assertFalse(lock.isBound()); + assertEquals(before, Affinity.getAffinity()); + } + assertEquals(before, Affinity.getAffinity()); + } + + @Test(expected = IllegalArgumentException.class) public void testTooHighCpuId() { - try (AffinityLock ignored = AffinityLock.acquireLock(123456)) { - assertNotNull(ignored); + AffinityLock.acquireLock(123456); } + + @Test(expected = IllegalArgumentException.class) + public void testNegativeCpuId() { + AffinityLock.acquireLock(-1); } - @Test + @Test(expected = IllegalArgumentException.class) public void testTooHighCpuId2() { - try (AffinityLock ignored = AffinityLock.acquireLock(new int[] {123456})) { - assertNotNull(ignored); + AffinityLock.acquireLock(new int[]{123456}); + } + + @Test(expected = IllegalStateException.class) + public void bindingTwoThreadsToSameCpuThrows() throws InterruptedException { + assumeTrue(Runtime.getRuntime().availableProcessors() > 1); + + final AffinityLock lock = AffinityLock.acquireLock(false); + Thread t = new Thread(() -> { + lock.bind(); + try { + Thread.sleep(100); + } catch (InterruptedException ignored) { + // ignored + } + }); + t.start(); + + while (!lock.isBound()) { + Thread.sleep(10); + } + + try { + lock.bind(); + } finally { + t.join(); + lock.release(); } } From 69157afc7beea956dd178da9d286b1c12fb4d6e6 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:17:03 +0100 Subject: [PATCH 076/110] AffinityLock.acquireCore should lock/unlock all cpus ie 2 when hyperthreaded --- .../net/openhft/affinity/AffinityLock.java | 19 ++++-- .../java/net/openhft/affinity/CpuLayout.java | 6 ++ .../java/net/openhft/affinity/LockCheck.java | 12 ++-- .../net/openhft/affinity/LockInventory.java | 12 ++-- .../openhft/affinity/impl/NoCpuLayout.java | 5 ++ .../affinity/impl/VanillaCpuLayout.java | 13 +++++ .../lockchecker/FileLockBasedLockChecker.java | 18 +++++- .../affinity/lockchecker/LockChecker.java | 2 +- .../openhft/affinity/AffinityLockTest.java | 58 +++++++++++++------ .../affinity/FileLockLockCheckTest.java | 6 +- .../net/openhft/affinity/LockCheckTest.java | 8 +-- .../impl/VanillaCpuLayoutPairTest.java | 56 ++++++++++++++++++ 12 files changed, 169 insertions(+), 46 deletions(-) create mode 100644 affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 2fcdb4d95..79d576ac9 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -69,6 +69,7 @@ public class AffinityLock implements Closeable { * Logical ID of the CPU to which this lock belongs to. */ private final int cpuId; + private final int cpuId2; /** * CPU to which this lock belongs to is of general use. */ @@ -88,9 +89,10 @@ public class AffinityLock implements Closeable { Throwable boundHere; private boolean resetAffinity = true; - AffinityLock(int cpuId, boolean base, boolean reservable, LockInventory lockInventory) { + AffinityLock(int cpuId, int cpuId2, boolean base, boolean reservable, LockInventory lockInventory) { this.lockInventory = lockInventory; this.cpuId = cpuId; + this.cpuId2 = cpuId2; this.base = base; this.reservable = reservable; } @@ -133,7 +135,7 @@ private static BitSet getReservedAffinity0() { int end = reservedAffinity.length(); for (int i = 0; i < longs.length; i++) { int begin = Math.max(0, end - 16); - longs[i] = Long.parseLong(reservedAffinity.substring(begin, end), 16); + longs[i] = Long.parseUnsignedLong(reservedAffinity.substring(begin, end), 16); end = begin; } return BitSet.valueOf(longs); @@ -183,11 +185,11 @@ public static AffinityLock acquireLock(boolean bind) { * for defining your thread layout centrally and passing the handle via dependency injection. * * @param cpuId the CPU id to bind to - * @return A handle for an affinity lock. + * @return A handle for an affinity lock, or no lock if no available CPU in the array */ public static AffinityLock acquireLock(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpuId); + return LOCK_INVENTORY.noLock(); } return acquireLock(true, cpuId, AffinityStrategies.ANY); } @@ -204,7 +206,8 @@ public static AffinityLock acquireLock(int cpuId) { public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { if (cpu < 0 || cpu >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpu); + LOGGER.warn("cpuId {} is out of range", cpu); + continue; } AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { @@ -265,7 +268,7 @@ public static AffinityLock acquireLock(String desc) { } else if (desc.startsWith("csv:")) { String content = desc.substring(4); - int[] cpus = Arrays.asList(content.split(",")).stream() + int[] cpus = Arrays.stream(content.split(",")) .map(String::trim) .mapToInt(Integer::parseInt).toArray(); @@ -469,6 +472,10 @@ public int cpuId() { return cpuId; } + public int cpuId2() { + return cpuId2; + } + /** * @return Was a cpu found to bind this lock to. */ diff --git a/affinity/src/main/java/net/openhft/affinity/CpuLayout.java b/affinity/src/main/java/net/openhft/affinity/CpuLayout.java index 7221d7dfb..12cbce61e 100644 --- a/affinity/src/main/java/net/openhft/affinity/CpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/CpuLayout.java @@ -49,4 +49,10 @@ public interface CpuLayout { * @return which thread on a core this cpu is on. */ int threadId(int cpuId); + + /** + * @param cpuId the logical processor number + * @return the hyperthreaded pair number or 0 if not hyperthreaded. + */ + int pair(int cpuId); } diff --git a/affinity/src/main/java/net/openhft/affinity/LockCheck.java b/affinity/src/main/java/net/openhft/affinity/LockCheck.java index 259aaf40b..ac9ca6cc1 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockCheck.java +++ b/affinity/src/main/java/net/openhft/affinity/LockCheck.java @@ -55,8 +55,8 @@ public static boolean isCpuFree(int cpu) { return isLockFree(cpu); } - static boolean replacePid(int cpu, long processID) throws IOException { - return storePid(processID, cpu); + static boolean replacePid(int cpu, int cpu2, long processID) throws IOException { + return storePid(processID, cpu, cpu2); } public static boolean isProcessRunning(long pid) { @@ -70,8 +70,8 @@ public static boolean isProcessRunning(long pid) { * stores the pid in a file, named by the core, the pid is written to the file with the date * below */ - private synchronized static boolean storePid(long processID, int cpu) throws IOException { - return lockChecker.obtainLock(cpu, Long.toString(processID)); + private synchronized static boolean storePid(long processID, int cpu, int cpu2) throws IOException { + return lockChecker.obtainLock(cpu, cpu2, Long.toString(processID)); } private synchronized static boolean isLockFree(int id) { @@ -91,10 +91,10 @@ public static int getProcessForCpu(int core) throws IOException { return EMPTY_PID; } - static boolean updateCpu(int cpu) throws IOException { + static boolean updateCpu(int cpu, int cpu2) throws IOException { if (!canOSSupportOperation()) return true; - return replacePid(cpu, getPID()); + return replacePid(cpu, cpu2, getPID()); } public static void releaseLock(int cpu) { diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index b3743d3b6..0fa41b114 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -82,7 +82,7 @@ private static boolean isAnyCpu(final int cpuId) { */ private static boolean updateLockForCurrentThread(final boolean bind, final AffinityLock al, final boolean wholeCore) throws ClosedByInterruptException { try { - if (LockCheck.updateCpu(al.cpuId())) { + if (LockCheck.updateCpu(al.cpuId(), wholeCore ? al.cpuId2() : 0)) { al.assignCurrentThread(bind, wholeCore); return true; } @@ -108,7 +108,9 @@ public final synchronized void set(CpuLayout cpuLayout) { final boolean base = AffinityLock.BASE_AFFINITY.get(i); final boolean reservable = AffinityLock.RESERVED_AFFINITY.get(i); LOGGER.trace("cpu {} base={} reservable= {}", i, base, reservable); - AffinityLock lock = logicalCoreLocks[i] = newLock(i, base, reservable); + assert logicalCoreLocks != null; + @SuppressWarnings("resource") + AffinityLock lock = logicalCoreLocks[i] = newLock(i, cpuLayout.pair(i), base, reservable); int layoutId = lock.cpuId(); int physicalCore = toPhysicalCore(layoutId); @@ -277,8 +279,8 @@ public final synchronized String dumpLocks() { return dumpLocks(logicalCoreLocks); } - protected AffinityLock newLock(int cpuId, boolean base, boolean reservable) { - return new AffinityLock(cpuId, base, reservable, this); + protected AffinityLock newLock(int cpuId, int cpuId2, boolean base, boolean reservable) { + return new AffinityLock(cpuId, cpuId2, base, reservable, this); } private void reset(CpuLayout cpuLayout) { @@ -301,6 +303,6 @@ private void releaseAffinityLock(final Thread t, final AffinityLock al, final St } public AffinityLock noLock() { - return newLock(AffinityLock.ANY_CPU, false, false); + return newLock(AffinityLock.ANY_CPU, 0, false, false); } } diff --git a/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java b/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java index b22c36cf7..2996bdf0d 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java @@ -64,4 +64,9 @@ public int coreId(int cpuId) { public int threadId(int cpuId) { return 0; } + + @Override + public int pair(int cpuId) { + return 0; + } } diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java b/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java index 7c17d1788..74ff2d580 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java @@ -177,6 +177,19 @@ public int threadId(int cpuId) { return cpuDetails.get(cpuId).threadId; } + @Override + public int pair(int cpuId) { + for (int i = 0; i < cpuDetails.size(); i++) { + CpuInfo info = cpuDetails.get(i); + if (info.socketId == cpuDetails.get(cpuId).socketId && + info.coreId == cpuDetails.get(cpuId).coreId && + info.threadId != cpuDetails.get(cpuId).threadId) { + return i; + } + } + return 0; + } + @NotNull @Override public String toString() { diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java index a720efb67..265d8923f 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java @@ -98,14 +98,25 @@ public synchronized boolean isLockFree(int id) { } @Override - public synchronized boolean obtainLock(int id, String metaInfo) throws IOException { + public synchronized boolean obtainLock(int id, int id2, String metaInfo) throws IOException { int attempt = 0; while (attempt < MAX_LOCK_RETRIES) { try { LockReference lockReference = tryAcquireLockOnFile(id, metaInfo); if (lockReference != null) { - locks[id] = lockReference; - return true; + if (id2 <= 0) { + // no second lock to acquire, return success + locks[id] = lockReference; + return true; + } + LockReference lockReference2 = tryAcquireLockOnFile(id2, metaInfo); + if (lockReference2 != null) { + locks[id] = lockReference; + locks[id2] = lockReference2; + return true; + } else { + releaseLock(id); + } } return false; } catch (ConcurrentLockFileDeletionException e) { @@ -163,6 +174,7 @@ private void writeMetaInfoToFile(FileChannel fc, String metaInfo) throws IOExcep byte[] content = String.format("%s%n%s", metaInfo, dfTL.get().format(new Date())).getBytes(); ByteBuffer buffer = ByteBuffer.wrap(content); while (buffer.hasRemaining()) { + //noinspection ResultOfMethodCallIgnored fc.write(buffer); } } diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java index 8df4eafa1..62a6c2f52 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java @@ -26,7 +26,7 @@ public interface LockChecker { boolean isLockFree(int id); - boolean obtainLock(int id, String metaInfo) throws IOException; + boolean obtainLock(int id, int id2, String metaInfo) throws IOException; boolean releaseLock(int id); diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index 75397348d..18e4e666d 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -19,7 +19,6 @@ import net.openhft.affinity.impl.Utilities; import net.openhft.affinity.impl.VanillaCpuLayout; -import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; import org.hamcrest.MatcherAssert; import org.junit.Test; import org.slf4j.Logger; @@ -28,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.BitSet; @@ -44,20 +44,19 @@ public class AffinityLockTest extends BaseAffinityTest { private static final Logger logger = LoggerFactory.getLogger(AffinityLockTest.class); - private final TestFileLockBasedLockChecker lockChecker = new TestFileLockBasedLockChecker(); @Test public void dumpLocksI7() throws IOException { LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("i7.cpuinfo")); AffinityLock[] locks = { - new AffinityLock(0, true, false, lockInventory), - new AffinityLock(1, false, false, lockInventory), - new AffinityLock(2, false, true, lockInventory), - new AffinityLock(3, false, true, lockInventory), - new AffinityLock(4, true, false, lockInventory), - new AffinityLock(5, false, false, lockInventory), - new AffinityLock(6, false, true, lockInventory), - new AffinityLock(7, false, true, lockInventory), + new AffinityLock(0, 0, true, false, lockInventory), + new AffinityLock(1, 5, false, false, lockInventory), + new AffinityLock(2, 6, false, true, lockInventory), + new AffinityLock(3, 7, false, true, lockInventory), + new AffinityLock(4, 0, true, false, lockInventory), + new AffinityLock(5, 1, false, false, lockInventory), + new AffinityLock(6, 2, false, true, lockInventory), + new AffinityLock(7, 3, false, true, lockInventory), }; locks[2].assignedThread = new Thread(new InterrupedThread(), "logger"); locks[2].assignedThread.start(); @@ -87,10 +86,10 @@ public void dumpLocksI7() throws IOException { public void dumpLocksI3() throws IOException { LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("i3.cpuinfo")); AffinityLock[] locks = { - new AffinityLock(0, true, false, lockInventory), - new AffinityLock(1, false, true, lockInventory), - new AffinityLock(2, true, false, lockInventory), - new AffinityLock(3, false, true, lockInventory), + new AffinityLock(0, 0, true, false, lockInventory), + new AffinityLock(1, 3, false, true, lockInventory), + new AffinityLock(2, 0, true, false, lockInventory), + new AffinityLock(3, 1, false, true, lockInventory), }; locks[1].assignedThread = new Thread(new InterrupedThread(), "engine"); locks[1].assignedThread.start(); @@ -110,8 +109,8 @@ public void dumpLocksI3() throws IOException { public void dumpLocksCoreDuo() throws IOException { LockInventory lockInventory = new LockInventory(VanillaCpuLayout.fromCpuInfo("core.duo.cpuinfo")); AffinityLock[] locks = { - new AffinityLock(0, true, false, lockInventory), - new AffinityLock(1, false, true, lockInventory), + new AffinityLock(0, 0, true, false, lockInventory), + new AffinityLock(1, 0, false, true, lockInventory), }; locks[1].assignedThread = new Thread(new InterrupedThread(), "engine"); locks[1].assignedThread.start(); @@ -254,11 +253,34 @@ public void lockFilesShouldBeRemovedOnRelease() { } final AffinityLock lock = AffinityLock.acquireLock(); - assertTrue(Files.exists(Paths.get(lockChecker.doToFile(lock.cpuId()).getAbsolutePath()))); + Path lockFile = Paths.get(System.getProperty("java.io.tmpdir"), "cpu-" + lock.cpuId() + ".lock"); + assertTrue(Files.exists(lockFile)); lock.release(); - assertFalse(Files.exists(Paths.get(lockChecker.doToFile(lock.cpuId()).getAbsolutePath()))); + assertFalse(Files.exists(lockFile)); + } + + @Test + public void wholeCoreLockReservesAllLogicalCpus() throws IOException { + if (!Utilities.ISLINUX || !new File("/proc/cpuinfo").exists()) { + return; + } + AffinityLock.cpuLayout(VanillaCpuLayout.fromCpuInfo()); + + CpuLayout layout = AffinityLock.cpuLayout(); + try (AffinityLock lock = AffinityLock.acquireCore()) { + int socketId = layout.socketId(lock.cpuId()); + int coreId = layout.coreId(lock.cpuId()); + for (int i = 0; i < layout.cpus(); i++) { + if (layout.socketId(i) == socketId && layout.coreId(i) == coreId) { + assertFalse("CPU " + i + " should be reserved", LockCheck.isCpuFree(i)); + } + } + } + for (int i = 0; i < layout.cpus(); i++) { + assertTrue("CPU " + i + " should not be reserved", LockCheck.isCpuFree(i)); + } } private void displayStatus() { diff --git a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java index 82b64435a..1d890d5fe 100644 --- a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java @@ -45,7 +45,7 @@ public void before() { @Test public void test() throws IOException { Assert.assertTrue(LockCheck.isCpuFree(cpu)); - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); Assert.assertEquals(LockCheck.getPID(), LockCheck.getProcessForCpu(cpu)); } @@ -58,13 +58,13 @@ public void testPidOnLinux() { public void testReplace() throws IOException { cpu++; Assert.assertTrue(LockCheck.isCpuFree(cpu + 1)); - LockCheck.replacePid(cpu, 123L); + LockCheck.replacePid(cpu, 0, 123L); Assert.assertEquals(123L, LockCheck.getProcessForCpu(cpu)); } @Test public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); final File file = lockChecker.doToFile(cpu); new RandomAccessFile(file, "rw").setLength(0); diff --git a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java index c7f04465b..40f5d18e5 100644 --- a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java @@ -46,7 +46,7 @@ public void before() { @Test public void test() throws IOException { Assert.assertTrue(LockCheck.isCpuFree(cpu)); - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); Assert.assertEquals(LockCheck.getPID(), LockCheck.getProcessForCpu(cpu)); } @@ -59,13 +59,13 @@ public void testPidOnLinux() { public void testReplace() throws IOException { cpu++; Assert.assertTrue(LockCheck.isCpuFree(cpu + 1)); - LockCheck.replacePid(cpu, 123L); + LockCheck.replacePid(cpu, 0, 123L); Assert.assertEquals(123L, LockCheck.getProcessForCpu(cpu)); } @Test public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); final File file = lockChecker.doToFile(cpu); new RandomAccessFile(file, "rw").setLength(0); @@ -75,7 +75,7 @@ public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { @Test public void shouldNotBlowUpIfPidFileIsCorrupt() throws Exception { - LockCheck.updateCpu(cpu); + LockCheck.updateCpu(cpu, 0); final File file = lockChecker.doToFile(cpu); try (final FileWriter writer = new FileWriter(file, false)) { diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java new file mode 100644 index 000000000..99986acd3 --- /dev/null +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016-2025 chronicle.software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.affinity.impl; + +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.Assert.assertEquals; + +/** + * Tests for {@link VanillaCpuLayout#pair(int)} using sample cpuinfo files. + */ +public class VanillaCpuLayoutPairTest { + + @Test + public void testPairForI7() throws IOException { + try (InputStream is = getClass().getClassLoader().getResourceAsStream("i7.cpuinfo")) { + VanillaCpuLayout layout = VanillaCpuLayout.fromCpuInfo(is); + assertEquals(4, layout.pair(0)); + assertEquals(5, layout.pair(1)); + assertEquals(6, layout.pair(2)); + assertEquals(7, layout.pair(3)); + assertEquals(0, layout.pair(4)); + assertEquals(1, layout.pair(5)); + assertEquals(2, layout.pair(6)); + assertEquals(3, layout.pair(7)); + } + } + + @Test + public void testPairForI3() throws IOException { + try (InputStream is = getClass().getClassLoader().getResourceAsStream("i3.cpuinfo")) { + VanillaCpuLayout layout = VanillaCpuLayout.fromCpuInfo(is); + assertEquals(2, layout.pair(0)); + assertEquals(3, layout.pair(1)); + assertEquals(0, layout.pair(2)); + assertEquals(1, layout.pair(3)); + } + } +} From addd3eeab47396e1ed5495211239ea3b9af6d015 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:41:22 +0100 Subject: [PATCH 077/110] Improve logging in FileLockBasedLockChecker to include additional CPU identifier on lock failure --- .../openhft/affinity/lockchecker/FileLockBasedLockChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java index 265d8923f..8b06f7e39 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java @@ -123,7 +123,7 @@ public synchronized boolean obtainLock(int id, int id2, String metaInfo) throws attempt++; } } - LOGGER.warn("Exceeded maximum retries for locking CPU {}, failing acquire", id); + LOGGER.warn("Exceeded maximum retries for locking CPU {}, {}, failing acquire", id, id2); return false; } From 872cbffa41d94f5bb15c47b82c041e08ee66d18e Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:44:31 +0100 Subject: [PATCH 078/110] Deprecate obtainLock method with single id parameter in LockChecker --- .../openhft/affinity/lockchecker/LockChecker.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java index 62a6c2f52..79a783e95 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java @@ -26,6 +26,18 @@ public interface LockChecker { boolean isLockFree(int id); + /** + * Obtain a lock for the given id. + */ + @Deprecated(/* to be removed in x.29 */) + default boolean obtainLock(int id, String metaInfo) throws IOException { + return obtainLock(id, 0, metaInfo); + } + + /** + * Obtain a lock for the given id and id2. The id2 is used to distinguish between + * multiple locks for the same core + */ boolean obtainLock(int id, int id2, String metaInfo) throws IOException; boolean releaseLock(int id); From dee81ed5fd420ca6173ea1b62f1cd14707f0e30a Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:38:57 +0100 Subject: [PATCH 079/110] Shorter LICENSE.adoc --- LICENSE | 201 --------------------------------------------------- LICENSE.adoc | 9 +++ 2 files changed, 9 insertions(+), 201 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE.adoc diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f7f8b7f7d..000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014-2025 chronicle.software - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/LICENSE.adoc b/LICENSE.adoc new file mode 100644 index 000000000..f45056642 --- /dev/null +++ b/LICENSE.adoc @@ -0,0 +1,9 @@ +== Copyright 2016-2025 chronicle.software + +Licensed under the *Apache License, Version 2.0* (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and limitations under the License. From 996d83cee9dacc4edb9f0b2dfedbe8a0b607a24d Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:49:25 +0100 Subject: [PATCH 080/110] Refactor AffinityLock methods to improve CPU ID validation and logging --- .../java/net/openhft/affinity/AffinityLock.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 2fcdb4d95..b5c1f06b2 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -186,10 +186,14 @@ public static AffinityLock acquireLock(boolean bind) { * @return A handle for an affinity lock. */ public static AffinityLock acquireLock(int cpuId) { + checkCpuId(cpuId); + return acquireLock(true, cpuId, AffinityStrategies.ANY); + } + + private static void checkCpuId(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpuId); + LOGGER.warn("cpuId must be between 0 and {}: {}", PROCESSORS - 1, cpuId); } - return acquireLock(true, cpuId, AffinityStrategies.ANY); } /** @@ -203,9 +207,7 @@ public static AffinityLock acquireLock(int cpuId) { */ public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { - if (cpu < 0 || cpu >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpu); - } + checkCpuId(cpu); AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { LOGGER.info("Acquired lock on CPU {}", cpu); @@ -265,7 +267,7 @@ public static AffinityLock acquireLock(String desc) { } else if (desc.startsWith("csv:")) { String content = desc.substring(4); - int[] cpus = Arrays.asList(content.split(",")).stream() + int[] cpus = Arrays.stream(content.split(",")) .map(String::trim) .mapToInt(Integer::parseInt).toArray(); From 2d931c38d84178a74903f2ce5d19cd091f39b5d7 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:49:25 +0100 Subject: [PATCH 081/110] Refactor AffinityLock methods to improve CPU ID validation and logging --- .../java/net/openhft/affinity/AffinityLock.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 2fcdb4d95..b5c1f06b2 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -186,10 +186,14 @@ public static AffinityLock acquireLock(boolean bind) { * @return A handle for an affinity lock. */ public static AffinityLock acquireLock(int cpuId) { + checkCpuId(cpuId); + return acquireLock(true, cpuId, AffinityStrategies.ANY); + } + + private static void checkCpuId(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpuId); + LOGGER.warn("cpuId must be between 0 and {}: {}", PROCESSORS - 1, cpuId); } - return acquireLock(true, cpuId, AffinityStrategies.ANY); } /** @@ -203,9 +207,7 @@ public static AffinityLock acquireLock(int cpuId) { */ public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { - if (cpu < 0 || cpu >= PROCESSORS) { - throw new IllegalArgumentException("cpuId must be between 0 and " + (PROCESSORS - 1) + ": " + cpu); - } + checkCpuId(cpu); AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { LOGGER.info("Acquired lock on CPU {}", cpu); @@ -265,7 +267,7 @@ public static AffinityLock acquireLock(String desc) { } else if (desc.startsWith("csv:")) { String content = desc.substring(4); - int[] cpus = Arrays.asList(content.split(",")).stream() + int[] cpus = Arrays.stream(content.split(",")) .map(String::trim) .mapToInt(Integer::parseInt).toArray(); From fa423ea52ad447c843fbf4756a996353e0f67fda Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:57:12 +0100 Subject: [PATCH 082/110] Refactor CPU ID validation in AffinityLock and enhance test cases for invalid inputs --- .../net/openhft/affinity/AffinityLock.java | 9 ++++++--- .../net/openhft/affinity/AffinityLockTest.java | 18 +++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index b5c1f06b2..7c5701997 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -186,14 +186,17 @@ public static AffinityLock acquireLock(boolean bind) { * @return A handle for an affinity lock. */ public static AffinityLock acquireLock(int cpuId) { - checkCpuId(cpuId); + if (isInvalidCpuId(cpuId)) + return LOCK_INVENTORY.noLock(); return acquireLock(true, cpuId, AffinityStrategies.ANY); } - private static void checkCpuId(int cpuId) { + private static boolean isInvalidCpuId(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { LOGGER.warn("cpuId must be between 0 and {}: {}", PROCESSORS - 1, cpuId); + return true; } + return false; } /** @@ -207,7 +210,7 @@ private static void checkCpuId(int cpuId) { */ public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { - checkCpuId(cpu); + if (isInvalidCpuId(cpu)) continue; AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { LOGGER.info("Acquired lock on CPU {}", cpu); diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index 75397348d..bc059c6a8 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -310,19 +310,22 @@ public void acquireLockWithoutBindingDoesNotChangeAffinity() { assertEquals(before, Affinity.getAffinity()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTooHighCpuId() { - AffinityLock.acquireLock(123456); - } + AffinityLock lock = AffinityLock.acquireLock(123456); + assertFalse(lock.isBound()); + } - @Test(expected = IllegalArgumentException.class) + @Test public void testNegativeCpuId() { - AffinityLock.acquireLock(-1); + AffinityLock lock = AffinityLock.acquireLock(-1); + assertFalse(lock.isBound()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTooHighCpuId2() { - AffinityLock.acquireLock(new int[]{123456}); + AffinityLock lock = AffinityLock.acquireLock(new int[]{-1, 123456}); + assertFalse(lock.isBound()); } @Test(expected = IllegalStateException.class) @@ -341,6 +344,7 @@ public void bindingTwoThreadsToSameCpuThrows() throws InterruptedException { t.start(); while (!lock.isBound()) { + //noinspection BusyWait Thread.sleep(10); } From c22684498406c657c52a3479c78f85dd78538706 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:49:25 +0100 Subject: [PATCH 083/110] Refactor AffinityLock methods to improve CPU ID validation and logging --- .../java/net/openhft/affinity/AffinityLock.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 79d576ac9..dee1eedad 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -188,10 +188,14 @@ public static AffinityLock acquireLock(boolean bind) { * @return A handle for an affinity lock, or no lock if no available CPU in the array */ public static AffinityLock acquireLock(int cpuId) { + checkCpuId(cpuId); + return acquireLock(true, cpuId, AffinityStrategies.ANY); + } + + private static void checkCpuId(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { - return LOCK_INVENTORY.noLock(); + LOGGER.warn("cpuId must be between 0 and {}: {}", PROCESSORS - 1, cpuId); } - return acquireLock(true, cpuId, AffinityStrategies.ANY); } /** @@ -205,10 +209,7 @@ public static AffinityLock acquireLock(int cpuId) { */ public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { - if (cpu < 0 || cpu >= PROCESSORS) { - LOGGER.warn("cpuId {} is out of range", cpu); - continue; - } + checkCpuId(cpu); AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { LOGGER.info("Acquired lock on CPU {}", cpu); From df7941ec59ace9cb3761ec0b657f35f01b4c4f75 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:57:12 +0100 Subject: [PATCH 084/110] Refactor CPU ID validation in AffinityLock and enhance test cases for invalid inputs --- .../net/openhft/affinity/AffinityLock.java | 9 ++++++--- .../net/openhft/affinity/AffinityLockTest.java | 18 +++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index dee1eedad..625578b9a 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -188,14 +188,17 @@ public static AffinityLock acquireLock(boolean bind) { * @return A handle for an affinity lock, or no lock if no available CPU in the array */ public static AffinityLock acquireLock(int cpuId) { - checkCpuId(cpuId); + if (isInvalidCpuId(cpuId)) + return LOCK_INVENTORY.noLock(); return acquireLock(true, cpuId, AffinityStrategies.ANY); } - private static void checkCpuId(int cpuId) { + private static boolean isInvalidCpuId(int cpuId) { if (cpuId < 0 || cpuId >= PROCESSORS) { LOGGER.warn("cpuId must be between 0 and {}: {}", PROCESSORS - 1, cpuId); + return true; } + return false; } /** @@ -209,7 +212,7 @@ private static void checkCpuId(int cpuId) { */ public static AffinityLock acquireLock(int[] cpus) { for (int cpu : cpus) { - checkCpuId(cpu); + if (isInvalidCpuId(cpu)) continue; AffinityLock lock = tryAcquireLock(true, cpu); if (lock != null) { LOGGER.info("Acquired lock on CPU {}", cpu); diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index 18e4e666d..76416c74d 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -332,19 +332,22 @@ public void acquireLockWithoutBindingDoesNotChangeAffinity() { assertEquals(before, Affinity.getAffinity()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTooHighCpuId() { - AffinityLock.acquireLock(123456); - } + AffinityLock lock = AffinityLock.acquireLock(123456); + assertFalse(lock.isBound()); + } - @Test(expected = IllegalArgumentException.class) + @Test public void testNegativeCpuId() { - AffinityLock.acquireLock(-1); + AffinityLock lock = AffinityLock.acquireLock(-1); + assertFalse(lock.isBound()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTooHighCpuId2() { - AffinityLock.acquireLock(new int[]{123456}); + AffinityLock lock = AffinityLock.acquireLock(new int[]{-1, 123456}); + assertFalse(lock.isBound()); } @Test(expected = IllegalStateException.class) @@ -363,6 +366,7 @@ public void bindingTwoThreadsToSameCpuThrows() throws InterruptedException { t.start(); while (!lock.isBound()) { + //noinspection BusyWait Thread.sleep(10); } From d16bf605a9d740f2142ef66a6197a272aff819ef Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 10:49:25 +0100 Subject: [PATCH 085/110] Refactor AffinityLock methods to improve CPU ID validation and logging --- .../src/main/java/net/openhft/affinity/AffinityLock.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 625578b9a..b73a03f6d 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -201,6 +201,12 @@ private static boolean isInvalidCpuId(int cpuId) { return false; } + private static void checkCpuId(int cpuId) { + if (cpuId < 0 || cpuId >= PROCESSORS) { + LOGGER.warn("cpuId must be between 0 and {}: {}", PROCESSORS - 1, cpuId); + } + } + /** * Assign a cpu which can be bound to the current thread or another thread * Caller passes in an explicit set of preferred CPUs From 53f1286813efb4bcbd4d94ff9e46c6789dbbf145 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:25:12 +0100 Subject: [PATCH 086/110] Add tests for AffinityLock behavior and exception handling --- .../java/net/openhft/affinity/AffinityLockTest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index 76416c74d..b1c560da7 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -333,6 +333,16 @@ public void acquireLockWithoutBindingDoesNotChangeAffinity() { } @Test + public void acquireLockWithoutBindingDoesNotChangeAffinity() { + BitSet before = (BitSet) Affinity.getAffinity().clone(); + try (AffinityLock lock = AffinityLock.acquireLock(false)) { + assertFalse(lock.isBound()); + assertEquals(before, Affinity.getAffinity()); + } + assertEquals(before, Affinity.getAffinity()); + } + + @Test(expected = IllegalArgumentException.class) public void testTooHighCpuId() { AffinityLock lock = AffinityLock.acquireLock(123456); assertFalse(lock.isBound()); @@ -344,7 +354,7 @@ public void testNegativeCpuId() { assertFalse(lock.isBound()); } - @Test + @Test(expected = IllegalArgumentException.class) public void testTooHighCpuId2() { AffinityLock lock = AffinityLock.acquireLock(new int[]{-1, 123456}); assertFalse(lock.isBound()); From 08f97564d4ce541d81a295d6fbdddeb74287d839 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 23 May 2025 12:33:41 +0100 Subject: [PATCH 087/110] Fixes for java 9+ support --- affinity/pom.xml | 4 ++ .../net/openhft/affinity/BootClassPath.java | 49 ++++++++++++++++--- .../java/net/openhft/affinity/LockCheck.java | 8 +-- .../openhft/affinity/impl/NullAffinity.java | 4 +- .../openhft/affinity/impl/OSXJNAAffinity.java | 4 +- .../affinity/impl/SolarisJNAAffinity.java | 4 +- .../net/openhft/affinity/impl/Utilities.java | 26 ++++++++++ .../affinity/impl/WindowsJNAAffinity.java | 5 +- .../openhft/affinity/AffinityLockTest.java | 20 ++------ .../openhft/affinity/BootClassPathTest.java | 2 - .../affinity/FileLockLockCheckTest.java | 33 +++++++++++++ .../net/openhft/affinity/LockCheckTest.java | 5 ++ 12 files changed, 126 insertions(+), 38 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index f634d4435..53a072427 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -110,6 +110,10 @@ make-c + + linux + !arm + !dontMake diff --git a/affinity/src/main/java/net/openhft/affinity/BootClassPath.java b/affinity/src/main/java/net/openhft/affinity/BootClassPath.java index 5ae3ca125..b13d16684 100644 --- a/affinity/src/main/java/net/openhft/affinity/BootClassPath.java +++ b/affinity/src/main/java/net/openhft/affinity/BootClassPath.java @@ -21,7 +21,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; import java.io.IOException; +import java.net.URI; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; @@ -39,21 +41,56 @@ enum BootClassPath { private static Set getResourcesOnBootClasspath() { final Logger logger = LoggerFactory.getLogger(BootClassPath.class); final Set resources = new HashSet<>(); + final String bootClassPath = System.getProperty("sun.boot.class.path", ""); - logger.trace("Boot class-path is: {}", bootClassPath); + if (!bootClassPath.isEmpty()) { + logger.trace("Boot class-path is: {}", bootClassPath); - final String pathSeparator = System.getProperty("path.separator"); - logger.trace("Path separator is: '{}'", pathSeparator); + final String pathSeparator = File.pathSeparator; + logger.trace("Path separator is: '{}'", pathSeparator); - final String[] pathElements = bootClassPath.split(pathSeparator); + final String[] pathElements = bootClassPath.split(pathSeparator); - for (final String pathElement : pathElements) { - resources.addAll(findResources(Paths.get(pathElement), logger)); + for (final String pathElement : pathElements) { + resources.addAll(findResources(Paths.get(pathElement), logger)); + } + } else { + resources.addAll(findResourcesInJrt(logger)); } return resources; } + private static Set findResourcesInJrt(final Logger logger) { + final Set jrtResources = new HashSet<>(); + try { + FileSystem fs; + try { + fs = FileSystems.getFileSystem(URI.create("jrt:/")); + } catch (FileSystemNotFoundException | ProviderNotFoundException e) { + fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap()); + } + final Path modules = fs.getPath("/modules"); + Files.walkFileTree(modules, new SimpleFileVisitor() { + @Override + public @NotNull FileVisitResult visitFile(final @NotNull Path file, + final @NotNull BasicFileAttributes attrs) throws IOException { + if (file.getFileName().toString().endsWith(".class")) { + Path relative = modules.relativize(file); + if (relative.getNameCount() > 1) { + Path classPath = relative.subpath(1, relative.getNameCount()); + jrtResources.add(classPath.toString()); + } + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + logger.warn("Error walking jrt filesystem", e); + } + return jrtResources; + } + private static Set findResources(final Path path, final Logger logger) { if (!Files.exists(path)) { return Collections.emptySet(); diff --git a/affinity/src/main/java/net/openhft/affinity/LockCheck.java b/affinity/src/main/java/net/openhft/affinity/LockCheck.java index ac9ca6cc1..2953637c3 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockCheck.java +++ b/affinity/src/main/java/net/openhft/affinity/LockCheck.java @@ -17,6 +17,7 @@ package net.openhft.affinity; +import net.openhft.affinity.impl.Utilities; import net.openhft.affinity.lockchecker.FileLockBasedLockChecker; import net.openhft.affinity.lockchecker.LockChecker; import org.slf4j.Logger; @@ -39,9 +40,7 @@ public enum LockCheck { private static final LockChecker lockChecker = FileLockBasedLockChecker.getInstance(); public static long getPID() { - String processName = - java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); - return Long.parseLong(processName.split("@")[0]); + return Utilities.currentProcessId(); } static boolean canOSSupportOperation() { @@ -79,6 +78,9 @@ private synchronized static boolean isLockFree(int id) { } public static int getProcessForCpu(int core) throws IOException { + if (!canOSSupportOperation()) + return EMPTY_PID; + String meta = lockChecker.getMetaInfo(core); if (meta != null && !meta.isEmpty()) { diff --git a/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java index 9ee9f1844..c9ebc183c 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java @@ -21,7 +21,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.management.ManagementFactory; import java.util.BitSet; /** @@ -48,8 +47,7 @@ public int getCpu() { @Override public int getProcessId() { - final String name = ManagementFactory.getRuntimeMXBean().getName(); - return Integer.parseInt(name.split("@")[0]); + return Utilities.currentProcessId(); } @Override diff --git a/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java index 9a944ecc6..39db80875 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.management.ManagementFactory; import java.util.BitSet; /** @@ -55,8 +54,7 @@ public int getCpu() { @Override public int getProcessId() { - final String name = ManagementFactory.getRuntimeMXBean().getName(); - return Integer.parseInt(name.split("@")[0]); + return Utilities.currentProcessId(); } @Override diff --git a/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java index 4b58eca56..ebe49b154 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.lang.management.ManagementFactory; import java.util.BitSet; /** @@ -55,8 +54,7 @@ public int getCpu() { @Override public int getProcessId() { - final String name = ManagementFactory.getRuntimeMXBean().getName(); - return Integer.parseInt(name.split("@")[0]); + return Utilities.currentProcessId(); } @Override diff --git a/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java b/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java index 676f1567f..4d3bfd13b 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java @@ -79,4 +79,30 @@ private static boolean is64Bit0() { systemProp = System.getProperty("java.vm.version"); return systemProp != null && systemProp.contains("_64"); } + + /** + * Returns the current process id. Uses {@code ProcessHandle} when running + * on Java 9 or later and falls back to parsing + * {@code RuntimeMXBean#getName()} on earlier versions. + * + * @return the process id or {@code -1} if it cannot be determined + */ + public static int currentProcessId() { + try { + // Java 9+ provides ProcessHandle which has a pid() method. + Class phClass = Class.forName("java.lang.ProcessHandle"); + Object current = phClass.getMethod("current").invoke(null); + long pid = (Long) phClass.getMethod("pid").invoke(current); + return (int) pid; + } catch (Throwable ignored) { + // ignore and fallback to the pre-Java 9 approach + } + + try { + String name = java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); + return Integer.parseInt(name.split("@")[0]); + } catch (Throwable e) { + return -1; + } + } } diff --git a/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java index 27b3af156..c64bd15be 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java @@ -89,8 +89,9 @@ public void setAffinity(final BitSet affinity) { throw new IllegalStateException("SetThreadAffinityMask((" + pid + ") , &(" + affinity + ") ) errorNo=" + e.getErrorCode(), e); } BitSet affinity2 = getAffinity0(); - if (!affinity2.equals(affinity)) { - LoggerFactory.getLogger(WindowsJNAAffinity.class).warn("Tried to set affinity to " + affinity + " but was " + affinity2 + " you may have insufficient access rights"); + assert affinity2 != null; + if (!affinity2.intersects(affinity)) { + LoggerFactory.getLogger(WindowsJNAAffinity.class).warn("Tried to set affinity to {} but was {} you may have insufficient access rights", affinity, affinity2); } currentAffinity.set((BitSet) affinity.clone()); } diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index b1c560da7..8bafde68a 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -333,30 +333,18 @@ public void acquireLockWithoutBindingDoesNotChangeAffinity() { } @Test - public void acquireLockWithoutBindingDoesNotChangeAffinity() { - BitSet before = (BitSet) Affinity.getAffinity().clone(); - try (AffinityLock lock = AffinityLock.acquireLock(false)) { - assertFalse(lock.isBound()); - assertEquals(before, Affinity.getAffinity()); - } - assertEquals(before, Affinity.getAffinity()); - } - - @Test(expected = IllegalArgumentException.class) public void testTooHighCpuId() { - AffinityLock lock = AffinityLock.acquireLock(123456); - assertFalse(lock.isBound()); + assertFalse(AffinityLock.acquireLock(123456).isBound()); } @Test public void testNegativeCpuId() { - AffinityLock lock = AffinityLock.acquireLock(-1); - assertFalse(lock.isBound()); + assertFalse(AffinityLock.acquireLock(-1).isBound()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTooHighCpuId2() { - AffinityLock lock = AffinityLock.acquireLock(new int[]{-1, 123456}); + AffinityLock lock = AffinityLock.acquireLock(new int[]{123456}); assertFalse(lock.isBound()); } diff --git a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java index bf0cb8268..9e1db8097 100644 --- a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java @@ -23,8 +23,6 @@ public class BootClassPathTest { @Test public void shouldDetectClassesOnClassPath() { - if (!System.getProperty("java.version").startsWith("1.8")) - return; assertTrue(BootClassPath.INSTANCE.has("java.lang.Thread")); assertTrue(BootClassPath.INSTANCE.has("java.lang.Runtime")); } diff --git a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java index 1d890d5fe..6be18c5d7 100644 --- a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java @@ -71,4 +71,37 @@ public void shouldNotBlowUpIfPidFileIsEmpty() throws Exception { LockCheck.isCpuFree(cpu); } + + @Test + public void lockFileDeletedWhileHeld() throws Exception { + cpu++; + + Assert.assertTrue(LockCheck.isCpuFree(cpu)); + LockCheck.updateCpu(cpu, 0); + + File lockFile = lockChecker.doToFile(cpu); + Assert.assertTrue(lockFile.exists()); + + Assert.assertTrue("Could not delete lock file", lockFile.delete()); + Assert.assertFalse(lockFile.exists()); + + Assert.assertFalse("CPU should remain locked despite missing file", LockCheck.isCpuFree(cpu)); + Assert.assertEquals(LockCheck.getPID(), LockCheck.getProcessForCpu(cpu)); + + LockCheck.releaseLock(cpu); + + Assert.assertTrue("Lock should be free after release", LockCheck.isCpuFree(cpu)); + LockCheck.updateCpu(cpu, 0); + + lockFile = lockChecker.doToFile(cpu); + Assert.assertTrue("Lock file should be recreated", lockFile.exists()); + } + + @Test + public void getProcessForCpuReturnsEmptyPidWhenNoFile() throws IOException { + int freeCpu = 99; + File lockFile = lockChecker.doToFile(freeCpu); + Assert.assertFalse(lockFile.exists()); + Assert.assertEquals(Integer.MIN_VALUE, LockCheck.getProcessForCpu(freeCpu)); + } } diff --git a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java index 40f5d18e5..2612886ce 100644 --- a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java @@ -55,6 +55,11 @@ public void testPidOnLinux() { Assert.assertTrue(LockCheck.isProcessRunning(LockCheck.getPID())); } + @Test + public void testNegativePidOnLinux() { + Assert.assertFalse(LockCheck.isProcessRunning(-1)); + } + @Test public void testReplace() throws IOException { cpu++; From 4685c33ada79c871dd4533fe44b128510cd5e15d Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 3 Jun 2025 11:12:31 +0100 Subject: [PATCH 088/110] Replace busy wait with Waiters utility for lock binding in AffinityLockTest --- .../test/java/net/openhft/affinity/AffinityLockTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index 8bafde68a..b1f422871 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -19,6 +19,7 @@ import net.openhft.affinity.impl.Utilities; import net.openhft.affinity.impl.VanillaCpuLayout; +import net.openhft.chronicle.testframework.Waiters; import org.hamcrest.MatcherAssert; import org.junit.Test; import org.slf4j.Logger; @@ -363,10 +364,7 @@ public void bindingTwoThreadsToSameCpuThrows() throws InterruptedException { }); t.start(); - while (!lock.isBound()) { - //noinspection BusyWait - Thread.sleep(10); - } + Waiters.waitForCondition("Waiting for lock to be bound", lock::isBound, 1000); try { lock.bind(); From c489075a82c8682ade39289bf32841b6857a71c1 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Thu, 3 Jul 2025 16:30:59 +0100 Subject: [PATCH 089/110] Updating parent POM (automated) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index e90b2d811..897ee4010 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.27ea0 + 1.27ea1 diff --git a/affinity/pom.xml b/affinity/pom.xml index 53a072427..f3ea41994 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.27ea0 + 1.27ea1 diff --git a/pom.xml b/pom.xml index 9d328d8d4..eaaeebf26 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ net.openhft java-parent-pom - 1.27ea0 + 1.27ea1 From c6bf7da4d07074e11b2130f8670d34f58cbf807f Mon Sep 17 00:00:00 2001 From: Kevin Powe <140356637+chroniclekevinpowe@users.noreply.github.com> Date: Tue, 8 Jul 2025 17:44:01 +1000 Subject: [PATCH 090/110] Update third party BOM version to 3.27ea2 to remove references to legacy staging repository URL. (#184) --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index f3ea41994..2b0b51701 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -42,7 +42,7 @@ net.openhft third-party-bom - 3.27ea0 + 3.27ea2 pom import From 675403433e0a0b412f51e2460982871675b2f630 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 9 Jul 2025 09:31:51 +0100 Subject: [PATCH 091/110] Add assertion to verify base affinity in BaseAffinityTest --- .../test/java/net/openhft/affinity/BaseAffinityTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java index 63f4f46af..d25764f0a 100644 --- a/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java @@ -21,6 +21,8 @@ import org.junit.Rule; import org.junit.rules.TemporaryFolder; +import static org.junit.Assert.assertEquals; + public class BaseAffinityTest { @Rule @@ -41,4 +43,9 @@ public void restoreTmpDirectoryAndReleaseAllLocks() { } System.setProperty("java.io.tmpdir", originalTmpDir); } + + @After + public void baseAffinity() { + assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); + } } From 954a4dfb9b26778b848ed40e990abca249c8bf14 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 9 Jul 2025 09:50:16 +0100 Subject: [PATCH 092/110] Add assertion to verify base affinity in BaseAffinityTest --- .../affinity/AffinityLockDumpLocksTest.java | 8 +++---- .../openhft/affinity/AffinityLockTest.java | 17 +++++++-------- .../affinity/AffinityThreadFactoryTest.java | 6 +----- .../openhft/affinity/BaseAffinityTest.java | 6 +++++- .../openhft/affinity/BootClassPathTest.java | 2 +- .../affinity/MultiProcessAffinityTest.java | 10 ++++----- .../impl/AbstractAffinityImplTest.java | 3 ++- .../impl/CpuInfoLayoutMappingTest.java | 21 ++++++++++--------- .../affinity/impl/LinuxJNAAffinityTest.java | 3 ++- .../openhft/affinity/impl/UtilitiesTest.java | 3 ++- .../impl/VanillaCpuLayoutPairTest.java | 3 ++- .../VanillaCpuLayoutPropertiesParseTest.java | 3 ++- .../affinity/impl/VanillaCpuLayoutTest.java | 3 ++- .../affinity/impl/VersionHelperTest.java | 3 ++- .../net/openhft/ticker/impl/JNIClockTest.java | 3 ++- .../enterprise/internals/JnaAffinityTest.java | 3 ++- .../internals/NativeAffinityTest.java | 3 ++- 17 files changed, 55 insertions(+), 45 deletions(-) diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java index e981e4e12..0336ab660 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java @@ -14,6 +14,10 @@ public class AffinityLockDumpLocksTest extends BaseAffinityTest { + static void supressUnusedWarning(AutoCloseable c) { + // do nothing + } + @Test public void dumpLocksListsThreadsHoldingLocks() throws Exception { Assume.assumeTrue(new File("/proc/cpuinfo").exists()); @@ -51,8 +55,4 @@ public void dumpLocksListsThreadsHoldingLocks() throws Exception { t.join(); } } - - static void supressUnusedWarning(AutoCloseable c) { - // do nothing - } } diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index b1f422871..a101f477d 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -45,6 +45,14 @@ public class AffinityLockTest extends BaseAffinityTest { private static final Logger logger = LoggerFactory.getLogger(AffinityLockTest.class); + /** + * In Java 21 the toString contents of Thread changed to include an ID. This breaks the tests here in Java 21. + * Strip out the thread ID here so that existing tests continue to pass. + */ + private static String dumpLocks(AffinityLock[] locks) { + String value = LockInventory.dumpLocks(locks); + return value.replaceAll("#[0-9]+(,)?", ""); + } @Test public void dumpLocksI7() throws IOException { @@ -373,13 +381,4 @@ public void bindingTwoThreadsToSameCpuThrows() throws InterruptedException { lock.release(); } } - - /** - * In Java 21 the toString contents of Thread changed to include an ID. This breaks the tests here in Java 21. - * Strip out the thread ID here so that existing tests continue to pass. - */ - private static String dumpLocks(AffinityLock[] locks) { - String value = LockInventory.dumpLocks(locks); - return value.replaceAll("#[0-9]+(,)?", ""); - } } diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java index 7377cc7ea..7368178d7 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java @@ -5,11 +5,7 @@ import org.junit.Test; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import static org.junit.Assert.*; diff --git a/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java index d25764f0a..85491595c 100644 --- a/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java @@ -21,6 +21,8 @@ import org.junit.Rule; import org.junit.rules.TemporaryFolder; +import java.util.BitSet; + import static org.junit.Assert.assertEquals; public class BaseAffinityTest { @@ -46,6 +48,8 @@ public void restoreTmpDirectoryAndReleaseAllLocks() { @After public void baseAffinity() { - assertEquals(AffinityLock.BASE_AFFINITY, Affinity.getAffinity()); + BitSet affinity = Affinity.getAffinity(); + Affinity.resetToBaseAffinity(); + assertEquals(AffinityLock.BASE_AFFINITY, affinity); } } diff --git a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java index 9e1db8097..426ad9f22 100644 --- a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertTrue; -public class BootClassPathTest { +public class BootClassPathTest extends BaseAffinityTest { @Test public void shouldDetectClassesOnClassPath() { assertTrue(BootClassPath.INSTANCE.has("java.lang.Thread")); diff --git a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java index 6aa948297..98eeb0a2b 100644 --- a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java @@ -155,6 +155,11 @@ static class RepeatedAffinityLocker implements Callable { private final int iterations; private final String cpuIdToLock; + public RepeatedAffinityLocker(String cpuIdToLock, int iterations) { + this.iterations = iterations; + this.cpuIdToLock = cpuIdToLock; + } + public static void main(String[] args) throws InterruptedException, ExecutionException { String cpuIdToLock = args[0]; int iterations = Integer.parseInt(args[1]); @@ -174,11 +179,6 @@ public static void main(String[] args) throws InterruptedException, ExecutionExc } } - public RepeatedAffinityLocker(String cpuIdToLock, int iterations) { - this.iterations = iterations; - this.cpuIdToLock = cpuIdToLock; - } - @Override public Void call() throws Exception { for (int i = 0; i < iterations; i++) { diff --git a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java index 5757e32ba..9cf1b7119 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java @@ -17,6 +17,7 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import net.openhft.affinity.IAffinity; import org.junit.After; import org.junit.Test; @@ -29,7 +30,7 @@ * @author cheremin * @since 29.12.11, 20:25 */ -public abstract class AbstractAffinityImplTest { +public abstract class AbstractAffinityImplTest extends BaseAffinityTest { protected static final int CORES = Runtime.getRuntime().availableProcessors(); protected static final BitSet CORES_MASK = new BitSet(CORES); diff --git a/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java b/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java index 3cee5d4bc..f58bcfb01 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java @@ -16,6 +16,7 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Test; import java.io.IOException; @@ -23,21 +24,21 @@ import static org.junit.Assert.assertEquals; -public class CpuInfoLayoutMappingTest { +public class CpuInfoLayoutMappingTest extends BaseAffinityTest { @Test public void verifyI7CpuInfoMapping() throws IOException { final InputStream i7 = getClass().getClassLoader().getResourceAsStream("i7.cpuinfo"); VanillaCpuLayout vcl = VanillaCpuLayout.fromCpuInfo(i7); - assertEquals( - "0: CpuInfo{socketId=0, coreId=0, threadId=0}\n" + - "1: CpuInfo{socketId=0, coreId=1, threadId=0}\n" + - "2: CpuInfo{socketId=0, coreId=2, threadId=0}\n" + - "3: CpuInfo{socketId=0, coreId=3, threadId=0}\n" + - "4: CpuInfo{socketId=0, coreId=0, threadId=1}\n" + - "5: CpuInfo{socketId=0, coreId=1, threadId=1}\n" + - "6: CpuInfo{socketId=0, coreId=2, threadId=1}\n" + - "7: CpuInfo{socketId=0, coreId=3, threadId=1}\n", + assertEquals("" + + "0: CpuInfo{socketId=0, coreId=0, threadId=0}\n" + + "1: CpuInfo{socketId=0, coreId=1, threadId=0}\n" + + "2: CpuInfo{socketId=0, coreId=2, threadId=0}\n" + + "3: CpuInfo{socketId=0, coreId=3, threadId=0}\n" + + "4: CpuInfo{socketId=0, coreId=0, threadId=1}\n" + + "5: CpuInfo{socketId=0, coreId=1, threadId=1}\n" + + "6: CpuInfo{socketId=0, coreId=2, threadId=1}\n" + + "7: CpuInfo{socketId=0, coreId=3, threadId=1}\n", vcl.toString()); } } diff --git a/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java index 0a4e924e4..760201c04 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java @@ -17,6 +17,7 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; @@ -28,7 +29,7 @@ /* * Created by Peter Lawrey on 23/03/16. */ -public class LinuxJNAAffinityTest { +public class LinuxJNAAffinityTest extends BaseAffinityTest { @BeforeClass public static void checkJniLibraryPresent() { Assume.assumeTrue(LinuxJNAAffinity.LOADED); diff --git a/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java b/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java index 45d05dbfd..9b282ac15 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java @@ -16,13 +16,14 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Test; import java.util.BitSet; import static org.junit.Assert.assertEquals; -public class UtilitiesTest { +public class UtilitiesTest extends BaseAffinityTest { private static String hex(BitSet set, int... bits) { set.clear(); diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java index 99986acd3..a09e6cd07 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java @@ -16,6 +16,7 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Test; import java.io.IOException; @@ -26,7 +27,7 @@ /** * Tests for {@link VanillaCpuLayout#pair(int)} using sample cpuinfo files. */ -public class VanillaCpuLayoutPairTest { +public class VanillaCpuLayoutPairTest extends BaseAffinityTest { @Test public void testPairForI7() throws IOException { diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java index b539ccf98..32c6ae11b 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java @@ -1,12 +1,13 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Test; import java.io.InputStream; import static org.junit.Assert.assertEquals; -public class VanillaCpuLayoutPropertiesParseTest { +public class VanillaCpuLayoutPropertiesParseTest extends BaseAffinityTest { @Test public void testCountsI7() throws Exception { diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java index 73ceb7fee..b712dab54 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java @@ -17,6 +17,7 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Test; import java.io.IOException; @@ -27,7 +28,7 @@ /** * @author peter.lawrey */ -public class VanillaCpuLayoutTest { +public class VanillaCpuLayoutTest extends BaseAffinityTest { @Test public void testFromCpuInfoI7() throws IOException { diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java index 9521d5cb2..ba6a08b84 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java @@ -17,10 +17,11 @@ package net.openhft.affinity.impl; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Assert; import org.junit.Test; -public class VersionHelperTest { +public class VersionHelperTest extends BaseAffinityTest { @Test public void isSameOrNewerTest() { diff --git a/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java b/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java index 56335a56c..84d39c833 100644 --- a/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java +++ b/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java @@ -18,6 +18,7 @@ package net.openhft.ticker.impl; import net.openhft.affinity.Affinity; +import net.openhft.affinity.BaseAffinityTest; import org.junit.Ignore; import org.junit.Test; @@ -26,7 +27,7 @@ /* * Created by Peter Lawrey on 13/07/15. */ -public class JNIClockTest { +public class JNIClockTest extends BaseAffinityTest { @Test @Ignore("TODO Fix") diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java index 85f0d7372..5f49c8503 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java @@ -17,6 +17,7 @@ package software.chronicle.enterprise.internals; +import net.openhft.affinity.BaseAffinityTest; import net.openhft.affinity.IAffinity; import net.openhft.affinity.impl.LinuxJNAAffinity; import net.openhft.affinity.impl.Utilities; @@ -32,7 +33,7 @@ /** * @author peter.lawrey */ -public class JnaAffinityTest { +public class JnaAffinityTest extends BaseAffinityTest { protected static final int CORES = Runtime.getRuntime().availableProcessors(); protected static final BitSet CORES_MASK = new BitSet(CORES); diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java index 6534082b6..7f7afecd3 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java @@ -17,6 +17,7 @@ package software.chronicle.enterprise.internals; +import net.openhft.affinity.BaseAffinityTest; import net.openhft.affinity.IAffinity; import net.openhft.affinity.impl.LinuxJNAAffinity; import net.openhft.affinity.impl.Utilities; @@ -30,7 +31,7 @@ /** * @author peter.lawrey */ -public class NativeAffinityTest { +public class NativeAffinityTest extends BaseAffinityTest { protected static final int CORES = Runtime.getRuntime().availableProcessors(); protected static final BitSet CORES_MASK = new BitSet(CORES); From af6d763c3f280c7e68bfff2575e712ae9251c000 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 9 Jul 2025 10:52:25 +0100 Subject: [PATCH 093/110] Suspend a flaky tests for functionality which isn't used AFAIK --- .../java/net/openhft/affinity/impl/PosixJNAAffinityTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java index e04c06610..82a20f2e3 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java @@ -24,6 +24,8 @@ import org.junit.Test; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; /** * @author peter.lawrey @@ -31,7 +33,8 @@ public class PosixJNAAffinityTest extends AbstractAffinityImplTest { @BeforeClass public static void checkJniLibraryPresent() { - Assume.assumeTrue("linux".equalsIgnoreCase(System.getProperty("os.name"))); + assumeTrue("TODO FIX JNA library is not used, but the test is flaky", false); + assumeTrue("linux".equalsIgnoreCase(System.getProperty("os.name"))); } @Override From b2392cfbe891c7ab1ac102af247c4e93a0e1c711 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 9 Jul 2025 12:28:30 +0100 Subject: [PATCH 094/110] Updating to bom version 2.27ea52 --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index 2b0b51701..db8b0381e 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.27ea-SNAPSHOT + 2.27ea52 pom import From 6dd6ecf61de5f584851223a66184d78d9304e5e1 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 9 Jul 2025 12:28:49 +0100 Subject: [PATCH 095/110] [maven-release-plugin] prepare release Java-Thread-Affinity-3.27ea1 --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 897ee4010..ff433733e 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.27ea1-SNAPSHOT + 3.27ea1 bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.27ea1 scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index db8b0381e..b4f16d4c8 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.27ea1-SNAPSHOT + 3.27ea1 bundle OpenHFT/Java-Thread-Affinity/affinity @@ -280,7 +280,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.27ea1 diff --git a/pom.xml b/pom.xml index eaaeebf26..e46d2e2b8 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.27ea1-SNAPSHOT + 3.27ea1 pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - ea + Java-Thread-Affinity-3.27ea1 From f429f06b9ab2bfbbdc0a25cbb1bbdc8478b409ec Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 9 Jul 2025 12:28:52 +0100 Subject: [PATCH 096/110] [maven-release-plugin] prepare for next development iteration --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index ff433733e..baa74ad86 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -26,7 +26,7 @@ affinity-test - 3.27ea1 + 3.27ea2-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -203,7 +203,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.27ea1 + ea scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git diff --git a/affinity/pom.xml b/affinity/pom.xml index b4f16d4c8..e896dc5d5 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -26,7 +26,7 @@ affinity - 3.27ea1 + 3.27ea2-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -280,7 +280,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.27ea1 + ea diff --git a/pom.xml b/pom.xml index e46d2e2b8..e08693cd9 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ Java-Thread-Affinity - 3.27ea1 + 3.27ea2-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent @@ -42,7 +42,7 @@ scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git scm:git:git@github.com:OpenHFT/Java-Thread-Affinity.git - Java-Thread-Affinity-3.27ea1 + ea From 27df98d7440f95dd1de23eddb0ad066890d3df17 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 9 Jul 2025 12:29:08 +0100 Subject: [PATCH 097/110] Reverting back to bom version 2.27ea-SNAPSHOT --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index e896dc5d5..b1c9e4561 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -49,7 +49,7 @@ net.openhft chronicle-bom - 2.27ea52 + 2.27ea-SNAPSHOT pom import From afd9574ea0f895feae4ce5b3ca3f4eaa91c302d2 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Fri, 17 Oct 2025 14:48:21 +0100 Subject: [PATCH 098/110] Documentation polish (LICENSE/README/requirements) + test import cleanup (#189) * Refactor requirements document for clarity and formatting improvements * Remove unused imports in PosixJNAAffinityTest * Format LICENSE.adoc for improved readability * Fix formatting and punctuation in README.adoc for improved readability --- LICENSE.adoc | 10 +- README.adoc | 140 +++++++++--------- affinity/src/main/adoc/requirements.adoc | 55 ++++--- .../affinity/impl/PosixJNAAffinityTest.java | 2 - 4 files changed, 111 insertions(+), 96 deletions(-) diff --git a/LICENSE.adoc b/LICENSE.adoc index f45056642..f93a31eb3 100644 --- a/LICENSE.adoc +++ b/LICENSE.adoc @@ -1,9 +1,13 @@ == Copyright 2016-2025 chronicle.software -Licensed under the *Apache License, Version 2.0* (the "License"); you may not use this file except in compliance with the License. +Licensed under the *Apache License, Version 2.0* (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and limitations under the License. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.adoc b/README.adoc index 91b0eeb06..61367bd58 100644 --- a/README.adoc +++ b/README.adoc @@ -5,7 +5,7 @@ image::docs/images/Thread-Affinity_line.png[width=20%] == Version [#image-maven] -[caption="", link=https://maven-badges.herokuapp.com/maven-central/net.openhft/affinity] +[caption="",link=https://maven-badges.herokuapp.com/maven-central/net.openhft/affinity] image::https://maven-badges.herokuapp.com/maven-central/net.openhft/affinity/badge.svg[] image:https://javadoc.io/badge2/net.openhft/affinity/javadoc.svg[link="https://www.javadoc.io/doc/net.openhft/affinity/latest/index.html"] @@ -14,22 +14,20 @@ Lets you bind a thread to a given core, this can improve performance (this libra OpenHFT Java Thread Affinity library -See https://github.com/OpenHFT/Java-Thread-Affinity/tree/master/affinity/src/test/java[affinity/src/test/java] +See https://github.com/OpenHFT/Java-Thread-Affinity/tree/master/affinity/src/test/java[affinity/src/test/java] for working examples of how to use this library. === Supported operating systems -The library detects the running platform in `Affinity.java` and selects an -implementation for that OS. Features differ between systems: +The library detects the running platform in `Affinity.java` and selects an implementation for that OS. +Features differ between systems: -* *Linux* - full affinity control via JNA. The implementation can get and set - thread affinity, query the current CPU, and obtain process and thread IDs. -* *Windows* - thread affinity is managed through the kernel API. Process and - thread IDs are available, while `getCpu()` returns `-1`. -* *macOS* - provides process and thread IDs but does not modify affinity and - reports the CPU id as `-1`. -* *Solaris* - mirrors the macOS implementation: only process and thread IDs are - returned with no affinity or CPU querying support. +* *Linux* - full affinity control via JNA. +The implementation can get and set thread affinity, query the current CPU, and obtain process and thread IDs. +* *Windows* - thread affinity is managed through the kernel API. +Process and thread IDs are available, while `getCpu()` returns `-1`. +* *macOS* - provides process and thread IDs but does not modify affinity and reports the CPU id as `-1`. +* *Solaris* - mirrors the macOS implementation: only process and thread IDs are returned with no affinity or CPU querying support. === Changes @@ -39,19 +37,15 @@ implementation for that OS. Features differ between systems: === Dependencies -Java-Thread-Affinity will try to use https://github.com/java-native-access/jna[JNA] -to provide access to native thread-handling functions. JNA should be installed on -your system to get the most from this library. +Java-Thread-Affinity will try to use link:https://github.com/java-native-access/jna[JNA] +to provide access to native thread-handling functions. +JNA should be installed on your system to get the most from this library. === JNA version -Java-Thread-Affinity currently depends on JNA version 4.4.0, which in turn -depends on a version of GLIBC >= 2.14. If your operating system is an old one, -with a version of GLIBC released before 2011, this library will not be able to -invoke native functions. +Java-Thread-Affinity currently depends on JNA version 4.4.0, which in turn depends on a version of GLIBC >= 2.14. If your operating system is an old one, with a version of GLIBC released before 2011, this library will not be able to invoke native functions. -To work around this problem, fork the repository, and override the `` tag -for the artifacts `jna` and `jna-platform` in the project's `pom` file. +To work around this problem, fork the repository, and override the `` tag for the artifacts `jna` and `jna-platform` in the project's `pom` file. === Installing JNA on Ubuntu @@ -68,17 +62,17 @@ for the artifacts `jna` and `jna-platform` in the project's `pom` file. Or download jna.jar and jna-platform.jar from the JNA project and add them to your classpath. === How does CPU allocation work? -The library will read your `/proc/cpuinfo` if you have one or provide one and it will determine your CPU layout. If you don't have one it will assume every CPU is on one CPU socket. +The library will read your `/proc/cpuinfo` if you have one or provide one and it will determine your CPU layout. +If you don't have one it will assume every CPU is on one CPU socket. -The library looks for isolated CPUs determined by looking at the CPUs you are not running on by default. +The library looks for isolated CPUs determined by looking at the CPUs you are not running on by default. i.e. if you have 16 CPUs but 8 of them are not available for general use (as determined by the affinity of the process on startup) it will start assigning to those CPUs. Note: if you have more than one process using this library you need to specify which CPUs the process can use otherwise it will assign the same CPUs to both processes. -To control which CPUs a process can use, add `-Daffinity.reserved={cpu-mask-in-hex}` -to the command line of the process. The mask is a hexadecimal bit mask without -the `0x` prefix where bit `0` represents CPU `0`, bit `1` represents CPU `1` and -so on. Multiple CPUs can be specified by setting more than one bit. +To control which CPUs a process can use, add `-Daffinity.reserved={cpu-mask-in-hex}` to the command line of the process. +The mask is a hexadecimal bit mask without the `0x` prefix where bit `0` represents CPU `0`, bit `1` represents CPU `1` and so on. +Multiple CPUs can be specified by setting more than one bit. For example: @@ -86,8 +80,7 @@ For example: * `-Daffinity.reserved=6` reserves CPUs `1` and `2`. * `-Daffinity.reserved=10` reserves CPUs `1` and `3` (hexadecimal `a`). -Use an appropriate mask when starting each process to avoid reserving the same -cores for multiple JVMs. +Use an appropriate mask when starting each process to avoid reserving the same cores for multiple JVMs. Note: the CPU 0 is reserved for the Operating System, it has to run somewhere. @@ -103,13 +96,14 @@ http://vanillajava.blogspot.co.uk/2013/07/micro-jitter-busy-waiting-and-binding. Java-Thread-Affinity requires that you first isolate some CPU's. -Once a CPU core is isolated, the Linux scheduler will not use the CPU core to run any user-space processes. The isolated CPUs will not participate in load balancing, and will not have tasks running on them unless explicitly assigned. +Once a CPU core is isolated, the Linux scheduler will not use the CPU core to run any user-space processes. +The isolated CPUs will not participate in load balancing, and will not have tasks running on them unless explicitly assigned. To isolate the 1st and 3rd CPU cores (CPU numbers start from 0) on your system, add the following to the kernel command line during boot: isolcpus=1,3 -Using GRUB +.Using GRUB [source] ---- sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=1,3 /' /etc/default/grub @@ -117,7 +111,7 @@ sudo update-grub sudo reboot ---- -Using systemd-boot +.Using systemd-boot [source] ---- sudo sed -i 's/^options \(.*\)/options \1 isolcpus=1,3/' /boot/loader/entries/*.conf @@ -129,8 +123,8 @@ sudo reboot === Acquiring a CPU lock for a thread You can acquire a lock for a CPU in the following way: -In Java 6 -[source, java] +.In Java 6 +[source,java] ---- AffinityLock al = AffinityLock.acquireLock(); try { @@ -140,26 +134,32 @@ try { } ---- -In Java 7 or 8 -[source, java] +.In Java 7 or 8 +[source,java] ---- try (AffinityLock al = AffinityLock.acquireLock()) { // do some work while locked to a CPU. } ---- + You have further options such as === Acquiring a CORE lock for a thread -You can reserve a whole core. If you have hyper-threading enabled, this will use one CPU and leave it's twin CPU unused. -[source, java] +You can reserve a whole core. +If you have hyper-threading enabled, this will use one CPU and leave it's twin CPU unused. + +[source,java] ---- try (AffinityLock al = AffinityLock.acquireCore()) { // do some work while locked to a CPU. } ---- + === Controlling layout + You can chose a layout relative to an existing lock. -[source, java] + +[source,java] ---- try (final AffinityLock al = AffinityLock.acquireLock()) { System.out.println("Main locked"); @@ -175,6 +175,7 @@ try (final AffinityLock al = AffinityLock.acquireLock()) { t.start(); } ---- + In this example, the library will prefer a free CPU on the same Socket as the first thread, otherwise it will pick any free CPU. === Affinity strategies @@ -193,32 +194,39 @@ The `AffinityStrategies` enum defines hints for selecting a CPU relative to an e === Getting the thread id You can get the current thread id using -[source, java] ----- +[source,java] +---- int threadId = AffinitySupport.getThreadId(); ---- + === Determining which CPU you are running on You can get the current CPU being used by -[source, java] ----- +[source,java] +---- int cpuId = AffinitySupport.getCpu(); ---- + === Controlling the affinity more directly + The affinity of the process on start up is -[source, java] ----- +[source,java] +---- long baseAffinity = AffinityLock.BASE_AFFINITY; ---- + The available CPU for reservation is -[source, java] + +[source,java] ---- long reservedAffinity = AffinityLock.RESERVED_AFFINITY; ---- + If you want to get/set the affinity directly you can do -[source, java] + +[source,java] ---- long currentAffinity = AffinitySupport.getAffinity(); AffinitySupport.setAffinity(1L << 5); // lock to CPU 5. @@ -227,8 +235,8 @@ AffinitySupport.setAffinity(1L << 5); // lock to CPU 5. === Understanding dumpLocks() output Several examples print the current CPU assignments using `AffinityLock.dumpLocks()`. -Each line of the output begins with the zero based CPU id followed by the status -of that CPU. Example output might look like: +Each line of the output begins with the zero based CPU id followed by the status of that CPU. +Example output might look like: [source] ---- @@ -239,35 +247,32 @@ of that CPU. Example output might look like: ---- The number on each line is the logical CPU index as recognised by the library. -The text after the colon describes whether that CPU is free, reserved or already -bound to a thread. Use these indices when calling `AffinityLock.acquireLock(n)` +The text after the colon describes whether that CPU is free, reserved or already bound to a thread. +Use these indices when calling `AffinityLock.acquireLock(n)` or when constructing explicit affinity masks. === Lock file directory -AffinityLock stores a small lock file for each CPU. These files are placed in -the directory specified by the `java.io.tmpdir` system property, which by -default points to your system's temporary directory (usually `/tmp` on Linux). +AffinityLock stores a small lock file for each CPU. +These files are placed in the directory specified by the `java.io.tmpdir` system property, which by default points to your system's temporary directory (usually `/tmp` on Linux). -If you want to keep the lock files elsewhere, set this property before using any -affinity APIs: +If you want to keep the lock files elsewhere, set this property before using any affinity APIs: -[source, bash] +[source,bash] ---- java -Djava.io.tmpdir=/path/to/dir ... ---- or in code -[source, java] +[source,java] ---- System.setProperty("java.io.tmpdir", "/path/to/dir"); ---- === Debugging affinity state -For a detailed of view of the current affinity state (as seen by the library), -execute the following script on Linux systems: +For a detailed of view of the current affinity state (as seen by the library), execute the following script on Linux systems: [source] ---- @@ -289,11 +294,10 @@ $ for i in "$(ls cpu-*)"; == Using AffinityThreadFactory -`AffinityThreadFactory` binds each thread it creates according to a set of -`AffinityStrategy` rules. This allows executors to automatically run tasks on -cores selected by the library. +`AffinityThreadFactory` binds each thread it creates according to a set of `AffinityStrategy` rules. +This allows executors to automatically run tasks on cores selected by the library. -[source, java] +[source,java] ---- ExecutorService es = Executors.newFixedThreadPool(4, new AffinityThreadFactory("worker", @@ -315,12 +319,14 @@ For an article on how much difference affinity can make and how to use it http:/ == Questions and Answers === Question: How to lock a specific cpuId -I am currently working on a project related to deadlock detection in multithreaded programs in java. We are trying to run threads on different processors and thus came across your github posts regarding the same. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started -Being a beginner, I have little knowledge and thus need your assistance. We need to know how to run threads on specified cpu number and then switch threads when one is waiting. +I am currently working on a project related to deadlock detection in multithreaded programs in java. +We are trying to run threads on different processors and thus came across your github posts regarding the same. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started +Being a beginner, I have little knowledge and thus need your assistance. +We need to know how to run threads on specified cpu number and then switch threads when one is waiting. === Answer -[source, java] +[source,java] ---- // lock a cpuId try (AffinityLock lock = AffinityLock.acquireLock(n)) { diff --git a/affinity/src/main/adoc/requirements.adoc b/affinity/src/main/adoc/requirements.adoc index f15cf0ed4..8132561a5 100644 --- a/affinity/src/main/adoc/requirements.adoc +++ b/affinity/src/main/adoc/requirements.adoc @@ -1,14 +1,11 @@ = Requirements Document: Java Thread Affinity -Author: Gemini AI -Date: 23 May 2025 -Version: 1.0 -:toc: left -:toclevels: 3 -:sectnums: +:toc: == 1. Introduction -This document outlines the requirements for the *Java Thread Affinity* library. The primary purpose of this library is to provide Java applications with the capability to control Central Processing Unit (CPU) affinity for their threads. This allows developers to bind specific threads to designated CPU cores, which can lead to performance improvements, especially in latency-sensitive applications, by reducing context switching and improving cache utilisation. +This document outlines the requirements for the *Java Thread Affinity* library. +The primary purpose of this library is to provide Java applications with the capability to control Central Processing Unit (CPU) affinity for their threads. +This allows developers to bind specific threads to designated CPU cores, which can lead to performance improvements, especially in latency-sensitive applications, by reducing context switching and improving cache utilisation. The library aims to offer a cross-platform API, with the most comprehensive support for Linux systems, leveraging Java Native Access (JNA) and, where applicable, Java Native Interface (JNI) for low-level system interactions. @@ -26,23 +23,25 @@ The scope of the Java Thread Affinity project includes: == 3. Definitions, Acronyms, and Abbreviations -* *CPU*: Central Processing Unit -* *JNA*: Java Native Access -* *JNI*: Java Native Interface -* *OS*: Operating System -* *PID*: Process Identifier -* *OSGi*: Open Service Gateway initiative -* *POM*: Project Object Model (Maven) -* *API*: Application Programming Interface +CPU :: Central Processing Unit +JNA :: Java Native Access +JNI :: Java Native Interface +OS :: Operating System +PID :: Process Identifier +OSGi :: Open Service Gateway initiative +POM :: Project Object Model (Maven) +API :: Application Programming Interface == 4. References -* Project Repository: https://github.com/OpenHFT/Java-Thread-Affinity -* JNA: https://github.com/java-native-access/jna +* Project Repository: link:https://github.com/OpenHFT/Java-Thread-Affinity[] +* JNA: link:https://github.com/java-native-access/jna[] == 5. Project Overview -The *Java Thread Affinity* library enables fine-grained control over which CPU cores Java threads execute on. This is particularly beneficial for high-performance computing and low-latency applications where minimising jitter and maximising cache efficiency is critical. The library abstracts OS-specific details, providing a unified Java API. +The *Java Thread Affinity* library enables fine-grained control over which CPU cores Java threads execute on. +This is particularly beneficial for high-performance computing and low-latency applications where minimising jitter and maximising cache efficiency is critical. +The library abstracts OS-specific details, providing a unified Java API. === 5.1. Purpose @@ -127,8 +126,10 @@ The *Java Thread Affinity* library enables fine-grained control over which CPU c * *FR9.1*: The system _shall_ provide tailored implementations of `IAffinity` for different operating systems: ** *Linux*: Full affinity control, CPU ID, Process ID, Thread ID via JNA (`LinuxJNAAffinity`, `PosixJNAAffinity`) or JNI (`NativeAffinity`). ** *Windows*: Thread affinity control, Process ID, Thread ID via JNA (`WindowsJNAAffinity`). `getCpu()` returns -1. -** *macOS*: Process ID, Thread ID via JNA (`OSXJNAAffinity`). No affinity modification; `getCpu()` returns -1. -** *Solaris*: Process ID, Thread ID via JNA (`SolarisJNAAffinity`). No affinity modification; `getCpu()` returns -1. +** *macOS*: Process ID, Thread ID via JNA (`OSXJNAAffinity`). +No affinity modification; `getCpu()` returns -1. +** *Solaris*: Process ID, Thread ID via JNA (`SolarisJNAAffinity`). +No affinity modification; `getCpu()` returns -1. * *FR9.2*: A `NullAffinity` implementation _shall_ be used as a fallback if no suitable native implementation can be loaded or for unsupported OS. === 6.6. Affinity Thread Factory (net.openhft.affinity.AffinityThreadFactory) @@ -166,10 +167,14 @@ The *Java Thread Affinity* library enables fine-grained control over which CPU c ** *Partial Support*: Windows (affinity setting, PID/TID, no `getCpu()`). ** *Limited Support*: macOS, Solaris (PID/TID only, no affinity setting or `getCpu()`). * *NFR2. Dependencies*: -** *JNA*: `net.java.dev.jna:jna`, `net.java.dev.jna:jna-platform`. Version 5.x or higher is recommended for full functionality. The project currently uses version 4.4.0 (as per README, though POMs might show updates). +** *JNA*: `net.java.dev.jna:jna`, `net.java.dev.jna:jna-platform`. +Version 5.x or higher is recommended for full functionality. +The project currently uses version 4.4.0 (as per README, though POMs might show updates). ** *SLF4J API*: `org.slf4j:slf4j-api` for logging. ** *JetBrains Annotations*: `org.jetbrains:annotations` for code quality. -* *NFR3. Performance*: The library _should_ introduce minimal overhead. Native calls _should_ be efficient. The primary goal is to enable performance improvements in the client application. +* *NFR3. Performance*: The library _should_ introduce minimal overhead. +Native calls _should_ be efficient. +The primary goal is to enable performance improvements in the client application. * *NFR4. Licensing*: The project _shall_ be licensed under the Apache License, Version 2.0. * *NFR5. Build System*: The project _shall_ use Apache Maven for building and dependency management. * *NFR6. Language*: @@ -192,7 +197,8 @@ The *Java Thread Affinity* library enables fine-grained control over which CPU c === 8.1. High-Level Architecture -The Java Thread Affinity library is a Java-based system that interfaces with the underlying operating system through JNA (primarily) and JNI (for specific `libCEInternals.so` functionalities). It abstracts OS-specific system calls related to thread affinity, CPU information, and timing. +The Java Thread Affinity library is a Java-based system that interfaces with the underlying operating system through JNA (primarily) and JNI (for specific `libCEInternals.so` functionalities). +It abstracts OS-specific system calls related to thread affinity, CPU information, and timing. === 8.2. Key Components @@ -241,7 +247,8 @@ The library can utilise an optional native shared library, `libCEInternals.so`, ** `Java_net_openhft_ticker_impl_JNIClock_rdtsc0` * *Platform Specifics*: ** *Linux*: Uses `sched_getaffinity`, `sched_setaffinity`, `sched_getcpu`, `getpid`, `syscall(SYS_gettid)`. -** *macOS*: (Separate C file `software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c`) Uses `pthread_mach_thread_np`, `thread_policy_get`, `thread_policy_set`. Note: JNA implementations are generally preferred on macOS. +** *macOS*: (Separate C file `software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c`) Uses `pthread_mach_thread_np`, `thread_policy_get`, `thread_policy_set`. +Note: JNA implementations are generally preferred on macOS. * *Loading*: The `NativeAffinity.java` class attempts to load `System.loadLibrary("CEInternals")`. == 10. API Overview diff --git a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java index 82a20f2e3..3c7ec1a7f 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java @@ -19,12 +19,10 @@ import net.openhft.affinity.Affinity; import net.openhft.affinity.IAffinity; -import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; /** From d1e39805e62d7f616d7299a07a76a0ab8964bb33 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 11 Nov 2025 15:07:47 +0000 Subject: [PATCH 099/110] Update copyright headers to reflect 2013-2025 and SPDX-License-Identifier: Apache-2.0 --- affinity-test/pom.xml | 20 +-- .../affinity/osgi/OSGiPlaceholder.java | 16 +-- .../openhft/affinity/osgi/OSGiBundleTest.java | 16 +-- .../openhft/affinity/osgi/OSGiTestBase.java | 16 +-- affinity/pom.xml | 20 +-- .../c/net_openhft_ticker_impl_JNIClock.cpp | 17 +-- ...terprise_internals_impl_NativeAffinity.cpp | 17 +-- ...ise_internals_impl_NativeAffinity_MacOSX.c | 17 +-- .../java/net/openhft/affinity/Affinity.java | 16 +-- .../net/openhft/affinity/AffinityLock.java | 16 +-- .../openhft/affinity/AffinityStrategies.java | 16 +-- .../openhft/affinity/AffinityStrategy.java | 16 +-- .../affinity/AffinityThreadFactory.java | 16 +-- .../net/openhft/affinity/BootClassPath.java | 16 +-- .../java/net/openhft/affinity/CpuLayout.java | 16 +-- .../java/net/openhft/affinity/IAffinity.java | 16 +-- .../java/net/openhft/affinity/LockCheck.java | 16 +-- .../net/openhft/affinity/LockInventory.java | 16 +-- .../openhft/affinity/MicroJitterSampler.java | 15 +-- .../openhft/affinity/impl/LinuxHelper.java | 16 +-- .../affinity/impl/LinuxJNAAffinity.java | 16 +-- .../openhft/affinity/impl/NoCpuLayout.java | 16 +-- .../openhft/affinity/impl/NullAffinity.java | 16 +-- .../openhft/affinity/impl/OSXJNAAffinity.java | 16 +-- .../affinity/impl/PosixJNAAffinity.java | 16 +-- .../affinity/impl/SolarisJNAAffinity.java | 16 +-- .../net/openhft/affinity/impl/Utilities.java | 16 +-- .../affinity/impl/VanillaCpuLayout.java | 16 +-- .../openhft/affinity/impl/VersionHelper.java | 16 +-- .../affinity/impl/WindowsJNAAffinity.java | 16 +-- .../lockchecker/FileLockBasedLockChecker.java | 15 +-- .../affinity/lockchecker/LockChecker.java | 79 +++++------- .../affinity/lockchecker/LockReference.java | 63 ++++------ .../affinity/main/AffinityTestMain.java | 119 ++++++++---------- .../main/java/net/openhft/ticker/ITicker.java | 16 +-- .../main/java/net/openhft/ticker/Ticker.java | 16 +-- .../net/openhft/ticker/impl/JNIClock.java | 16 +-- .../net/openhft/ticker/impl/SystemClock.java | 16 +-- .../internals/impl/NativeAffinity.java | 16 +-- .../affinity/AffinityLockBindMain.java | 16 +-- .../affinity/AffinityLockDumpLocksTest.java | 3 + .../openhft/affinity/AffinityLockMain.java | 16 +-- .../affinity/AffinityLockReleaseTest.java | 15 +-- .../openhft/affinity/AffinityLockTest.java | 16 +-- .../AffinityResetToBaseAffinityTest.java | 3 + .../openhft/affinity/AffinitySupportMain.java | 16 +-- .../affinity/AffinityThreadFactoryMain.java | 16 +-- .../affinity/AffinityThreadFactoryTest.java | 3 + .../openhft/affinity/BaseAffinityTest.java | 15 +-- .../openhft/affinity/BootClassPathTest.java | 15 +-- .../affinity/FileLockLockCheckTest.java | 16 +-- .../openhft/affinity/InterrupedThread.java | 16 +-- .../net/openhft/affinity/LockCheckTest.java | 16 +-- .../affinity/MultiProcessAffinityTest.java | 15 +-- .../impl/AbstractAffinityImplTest.java | 16 +-- .../impl/CpuInfoLayoutMappingTest.java | 15 +-- .../affinity/impl/LinuxJNAAffinityTest.java | 16 +-- .../affinity/impl/NativeAffinityImpTest.java | 16 +-- .../affinity/impl/PosixJNAAffinityTest.java | 16 +-- .../openhft/affinity/impl/UtilitiesTest.java | 15 +-- .../impl/VanillaCpuLayoutPairTest.java | 15 +-- .../VanillaCpuLayoutPropertiesParseTest.java | 3 + .../affinity/impl/VanillaCpuLayoutTest.java | 16 +-- .../affinity/impl/VersionHelperTest.java | 16 +-- .../TestFileLockBasedLockChecker.java | 15 +-- .../net/openhft/ticker/impl/JNIClockTest.java | 16 +-- .../enterprise/internals/JnaAffinityTest.java | 16 +-- .../internals/NativeAffinityTest.java | 16 +-- pom.xml | 20 +-- 69 files changed, 200 insertions(+), 1070 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index baa74ad86..9b75487b5 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -1,19 +1,9 @@ + + Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + +--> 4.0.0 @@ -21,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea1 + 1.27ea2-SNAPSHOT diff --git a/affinity-test/src/main/java/net/openhft/affinity/osgi/OSGiPlaceholder.java b/affinity-test/src/main/java/net/openhft/affinity/osgi/OSGiPlaceholder.java index bd9b2d0a3..a6e7ef36d 100644 --- a/affinity-test/src/main/java/net/openhft/affinity/osgi/OSGiPlaceholder.java +++ b/affinity-test/src/main/java/net/openhft/affinity/osgi/OSGiPlaceholder.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.osgi; /** diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java index 80949898f..7896c6d7a 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.osgi; import org.junit.Ignore; diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java index a1e9fcc96..347d2edf0 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.osgi; import org.ops4j.pax.exam.CoreOptions; diff --git a/affinity/pom.xml b/affinity/pom.xml index b1c9e4561..e778dd9e1 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -1,19 +1,9 @@ + + Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + +--> 4.0.0 @@ -21,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea1 + 1.27ea2-SNAPSHOT diff --git a/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp b/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp index e68c32036..2cf233d3a 100644 --- a/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp +++ b/affinity/src/main/c/net_openhft_ticker_impl_JNIClock.cpp @@ -1,19 +1,6 @@ -/* vim: syntax=cpp - * Copyright 2015-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/** + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif diff --git a/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp b/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp index 721f1e7f3..f13d566a1 100644 --- a/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp +++ b/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity.cpp @@ -1,19 +1,6 @@ -/* vim: syntax=cpp - * Copyright 2011-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/** + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif diff --git a/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c b/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c index f0f2fdc09..67dafb1ef 100644 --- a/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c +++ b/affinity/src/main/c/software_chronicle_enterprise_internals_impl_NativeAffinity_MacOSX.c @@ -1,19 +1,6 @@ -/* - * Copyright 2011-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/** + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - #include #include #include diff --git a/affinity/src/main/java/net/openhft/affinity/Affinity.java b/affinity/src/main/java/net/openhft/affinity/Affinity.java index d4654749a..8dadd8a15 100644 --- a/affinity/src/main/java/net/openhft/affinity/Affinity.java +++ b/affinity/src/main/java/net/openhft/affinity/Affinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import com.sun.jna.Native; diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java index 625578b9a..cf0ed4ca0 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityLock.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityLock.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.impl.NoCpuLayout; diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityStrategies.java b/affinity/src/main/java/net/openhft/affinity/AffinityStrategies.java index b833eaa87..65ee0cbf9 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityStrategies.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityStrategies.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; /** diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityStrategy.java b/affinity/src/main/java/net/openhft/affinity/AffinityStrategy.java index ccdc782f0..400c6d3c6 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityStrategy.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityStrategy.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; /** diff --git a/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java b/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java index 7f789a4e5..6e1d67e5a 100644 --- a/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java +++ b/affinity/src/main/java/net/openhft/affinity/AffinityThreadFactory.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import org.jetbrains.annotations.NotNull; diff --git a/affinity/src/main/java/net/openhft/affinity/BootClassPath.java b/affinity/src/main/java/net/openhft/affinity/BootClassPath.java index b13d16684..85efa3279 100644 --- a/affinity/src/main/java/net/openhft/affinity/BootClassPath.java +++ b/affinity/src/main/java/net/openhft/affinity/BootClassPath.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import org.jetbrains.annotations.NotNull; diff --git a/affinity/src/main/java/net/openhft/affinity/CpuLayout.java b/affinity/src/main/java/net/openhft/affinity/CpuLayout.java index 12cbce61e..0cbdd6412 100644 --- a/affinity/src/main/java/net/openhft/affinity/CpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/CpuLayout.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; /** diff --git a/affinity/src/main/java/net/openhft/affinity/IAffinity.java b/affinity/src/main/java/net/openhft/affinity/IAffinity.java index d389c5afa..c473a5400 100644 --- a/affinity/src/main/java/net/openhft/affinity/IAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/IAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import java.util.BitSet; diff --git a/affinity/src/main/java/net/openhft/affinity/LockCheck.java b/affinity/src/main/java/net/openhft/affinity/LockCheck.java index 2953637c3..e3c485fed 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockCheck.java +++ b/affinity/src/main/java/net/openhft/affinity/LockCheck.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.impl.Utilities; diff --git a/affinity/src/main/java/net/openhft/affinity/LockInventory.java b/affinity/src/main/java/net/openhft/affinity/LockInventory.java index 0fa41b114..b54615219 100644 --- a/affinity/src/main/java/net/openhft/affinity/LockInventory.java +++ b/affinity/src/main/java/net/openhft/affinity/LockInventory.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.impl.NullAffinity; diff --git a/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java b/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java index 21a6e5b3c..30e27d221 100644 --- a/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java +++ b/affinity/src/main/java/net/openhft/affinity/MicroJitterSampler.java @@ -1,19 +1,6 @@ /* - * Copyright 2014-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import java.io.PrintStream; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java index df5cbbc3d..a52404bba 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxHelper.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import com.sun.jna.*; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java index 313f8c8ec..d16fc3beb 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/LinuxJNAAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import com.sun.jna.NativeLong; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java b/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java index 2996bdf0d..e57b1decc 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/NoCpuLayout.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.CpuLayout; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java index c9ebc183c..4c5e8e304 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/NullAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.IAffinity; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java index 39db80875..fd020fd21 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/OSXJNAAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import com.sun.jna.LastErrorException; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/PosixJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/PosixJNAAffinity.java index 50b0f299d..39aed93ab 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/PosixJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/PosixJNAAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import com.sun.jna.*; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java index ebe49b154..fcb5b8db0 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/SolarisJNAAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import com.sun.jna.LastErrorException; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java b/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java index 4d3bfd13b..babf6b360 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/Utilities.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import java.io.ByteArrayOutputStream; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java b/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java index 74ff2d580..4fac94fe4 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VanillaCpuLayout.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.CpuLayout; diff --git a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java index 616f49232..08a01ab19 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/VersionHelper.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; public class VersionHelper { diff --git a/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java b/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java index c64bd15be..bdeef6710 100644 --- a/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java +++ b/affinity/src/main/java/net/openhft/affinity/impl/WindowsJNAAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import com.sun.jna.*; diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java index 8b06f7e39..eb2394ddd 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/FileLockBasedLockChecker.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.lockchecker; import org.jetbrains.annotations.NotNull; diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java index 79a783e95..ddbe0d49c 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockChecker.java @@ -1,46 +1,33 @@ -/* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.openhft.affinity.lockchecker; - -import java.io.IOException; - -/** - * @author Tom Shercliff - */ - -public interface LockChecker { - - boolean isLockFree(int id); - - /** - * Obtain a lock for the given id. - */ - @Deprecated(/* to be removed in x.29 */) - default boolean obtainLock(int id, String metaInfo) throws IOException { - return obtainLock(id, 0, metaInfo); - } - - /** - * Obtain a lock for the given id and id2. The id2 is used to distinguish between - * multiple locks for the same core - */ - boolean obtainLock(int id, int id2, String metaInfo) throws IOException; - - boolean releaseLock(int id); - - String getMetaInfo(int id) throws IOException; -} +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.affinity.lockchecker; + +import java.io.IOException; + +/** + * @author Tom Shercliff + */ + +public interface LockChecker { + + boolean isLockFree(int id); + + /** + * Obtain a lock for the given id. + */ + @Deprecated(/* to be removed in x.29 */) + default boolean obtainLock(int id, String metaInfo) throws IOException { + return obtainLock(id, 0, metaInfo); + } + + /** + * Obtain a lock for the given id and id2. The id2 is used to distinguish between + * multiple locks for the same core + */ + boolean obtainLock(int id, int id2, String metaInfo) throws IOException; + + boolean releaseLock(int id); + + String getMetaInfo(int id) throws IOException; +} diff --git a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockReference.java b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockReference.java index 82d89489d..10e2b1bdf 100644 --- a/affinity/src/main/java/net/openhft/affinity/lockchecker/LockReference.java +++ b/affinity/src/main/java/net/openhft/affinity/lockchecker/LockReference.java @@ -1,38 +1,25 @@ -/* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.openhft.affinity.lockchecker; - -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; - -/** - * @author Tom Shercliff - */ - -public class LockReference { - protected final FileChannel channel; - protected final FileLock lock; - - public LockReference(final FileChannel channel, final FileLock lock) { - this.channel = channel; - this.lock = lock; - } - - public FileChannel getChannel() { - return channel; - } -} +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.affinity.lockchecker; + +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; + +/** + * @author Tom Shercliff + */ + +public class LockReference { + protected final FileChannel channel; + protected final FileLock lock; + + public LockReference(final FileChannel channel, final FileLock lock) { + this.channel = channel; + this.lock = lock; + } + + public FileChannel getChannel() { + return channel; + } +} diff --git a/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java b/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java index 78ca56302..fcaa3281a 100644 --- a/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java +++ b/affinity/src/main/java/net/openhft/affinity/main/AffinityTestMain.java @@ -1,66 +1,53 @@ -/* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.openhft.affinity.main; - -import net.openhft.affinity.Affinity; -import net.openhft.affinity.AffinityLock; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * @author Tom Shercliff - */ -public class AffinityTestMain { - - public static void main(String[] args) { - - int cpus; - if (args.length == 0) { - cpus = AffinityLock.cpuLayout().cpus() / 12; - } else { - cpus = Integer.parseInt(args[0]); - } - - for (int i = 0; i < cpus; i++) { - acquireAndDoWork(); - } - } - - private static void acquireAndDoWork() { - - Thread t = new Thread(() -> { - final SimpleDateFormat df = new SimpleDateFormat("yyyy.MM" + ".dd 'at' HH:mm:ss z"); - try (AffinityLock al = Affinity.acquireLock()) { - String threadName = Thread.currentThread().getName(); - System.out.println("Thread (" + threadName + ") locked onto cpu " + al.cpuId()); - - while (true) { - System.out.println(df.format(new Date()) + " - Thread (" + threadName + ") doing work on cpu " + al.cpuId() + ". IsAllocated = " + al.isAllocated() + ", isBound = " + al.isBound() + ". " + al); - - try { - //noinspection BusyWait - Thread.sleep(10000L); - } catch (InterruptedException e) { - //nothing - } - } - } - }); - t.start(); - } -} +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.affinity.main; + +import net.openhft.affinity.Affinity; +import net.openhft.affinity.AffinityLock; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author Tom Shercliff + */ +public class AffinityTestMain { + + public static void main(String[] args) { + + int cpus; + if (args.length == 0) { + cpus = AffinityLock.cpuLayout().cpus() / 12; + } else { + cpus = Integer.parseInt(args[0]); + } + + for (int i = 0; i < cpus; i++) { + acquireAndDoWork(); + } + } + + private static void acquireAndDoWork() { + + Thread t = new Thread(() -> { + final SimpleDateFormat df = new SimpleDateFormat("yyyy.MM" + ".dd 'at' HH:mm:ss z"); + try (AffinityLock al = Affinity.acquireLock()) { + String threadName = Thread.currentThread().getName(); + System.out.println("Thread (" + threadName + ") locked onto cpu " + al.cpuId()); + + while (true) { + System.out.println(df.format(new Date()) + " - Thread (" + threadName + ") doing work on cpu " + al.cpuId() + ". IsAllocated = " + al.isAllocated() + ", isBound = " + al.isBound() + ". " + al); + + try { + //noinspection BusyWait + Thread.sleep(10000L); + } catch (InterruptedException e) { + //nothing + } + } + } + }); + t.start(); + } +} diff --git a/affinity/src/main/java/net/openhft/ticker/ITicker.java b/affinity/src/main/java/net/openhft/ticker/ITicker.java index 0763f0871..3a9ab33d3 100644 --- a/affinity/src/main/java/net/openhft/ticker/ITicker.java +++ b/affinity/src/main/java/net/openhft/ticker/ITicker.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.ticker; /** diff --git a/affinity/src/main/java/net/openhft/ticker/Ticker.java b/affinity/src/main/java/net/openhft/ticker/Ticker.java index 596fe9f2b..4d057cf2a 100644 --- a/affinity/src/main/java/net/openhft/ticker/Ticker.java +++ b/affinity/src/main/java/net/openhft/ticker/Ticker.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.ticker; import net.openhft.ticker.impl.JNIClock; diff --git a/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java b/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java index 58cb01ab6..c50c3826c 100644 --- a/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java +++ b/affinity/src/main/java/net/openhft/ticker/impl/JNIClock.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.ticker.impl; import net.openhft.ticker.ITicker; diff --git a/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java b/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java index 8c88c2aef..cbbd3545e 100644 --- a/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java +++ b/affinity/src/main/java/net/openhft/ticker/impl/SystemClock.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.ticker.impl; import net.openhft.ticker.ITicker; diff --git a/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java b/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java index 2071dd77e..cf95002bb 100644 --- a/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java +++ b/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package software.chronicle.enterprise.internals.impl; import net.openhft.affinity.IAffinity; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockBindMain.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockBindMain.java index 1935e105f..b1ed7effe 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockBindMain.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockBindMain.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import static net.openhft.affinity.AffinityStrategies.*; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java index 0336ab660..984b18b5f 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java @@ -1,3 +1,6 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ package net.openhft.affinity; import net.openhft.affinity.impl.VanillaCpuLayout; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockMain.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockMain.java index 5f09608c9..cf7388ec6 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockMain.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockMain.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; /** diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java index 4cbc15f4d..dc964296f 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockReleaseTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.impl.VanillaCpuLayout; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java index a101f477d..4e8ff5519 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.impl.Utilities; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java index 502cb0e0b..86ad17fed 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityResetToBaseAffinityTest.java @@ -1,3 +1,6 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ package net.openhft.affinity; import net.openhft.affinity.impl.VanillaCpuLayout; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinitySupportMain.java b/affinity/src/test/java/net/openhft/affinity/AffinitySupportMain.java index 9e0d8efc9..d7cf5b35d 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinitySupportMain.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinitySupportMain.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; /** diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java index 9052239b3..3dbd15396 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryMain.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import java.util.concurrent.Callable; diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java index 7368178d7..4c95b8bd4 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityThreadFactoryTest.java @@ -1,3 +1,6 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ package net.openhft.affinity; import org.junit.Assume; diff --git a/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java index 85491595c..f147ce33b 100644 --- a/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BaseAffinityTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import org.junit.After; diff --git a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java index 426ad9f22..17558a01e 100644 --- a/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java +++ b/affinity/src/test/java/net/openhft/affinity/BootClassPathTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import org.junit.Test; diff --git a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java index 6be18c5d7..f1a88ddc1 100644 --- a/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/FileLockLockCheckTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; diff --git a/affinity/src/test/java/net/openhft/affinity/InterrupedThread.java b/affinity/src/test/java/net/openhft/affinity/InterrupedThread.java index 92441d61a..9e85c0790 100644 --- a/affinity/src/test/java/net/openhft/affinity/InterrupedThread.java +++ b/affinity/src/test/java/net/openhft/affinity/InterrupedThread.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; /** diff --git a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java index 2612886ce..3f19a4a2f 100644 --- a/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java +++ b/affinity/src/test/java/net/openhft/affinity/LockCheckTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; diff --git a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java index 98eeb0a2b..56fd81b69 100644 --- a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity; import net.openhft.affinity.testimpl.TestFileLockBasedLockChecker; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java index 9cf1b7119..ec45f0e3f 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java b/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java index f58bcfb01..7687f6967 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/CpuInfoLayoutMappingTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java index 760201c04..cf0db12bd 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/LinuxJNAAffinityTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java b/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java index 4b807d7a2..2b9cbb73a 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.Affinity; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java index 3c7ec1a7f..180506e70 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.Affinity; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java b/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java index 9b282ac15..80eed46ea 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/UtilitiesTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java index a09e6cd07..c356f3c81 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPairTest.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java index 32c6ae11b..7452c060f 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutPropertiesParseTest.java @@ -1,3 +1,6 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java index b712dab54..0e90d5069 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VanillaCpuLayoutTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java b/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java index ba6a08b84..a7f21afff 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/VersionHelperTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2017-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.impl; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/net/openhft/affinity/testimpl/TestFileLockBasedLockChecker.java b/affinity/src/test/java/net/openhft/affinity/testimpl/TestFileLockBasedLockChecker.java index 8e93c0f21..56b47d9e1 100644 --- a/affinity/src/test/java/net/openhft/affinity/testimpl/TestFileLockBasedLockChecker.java +++ b/affinity/src/test/java/net/openhft/affinity/testimpl/TestFileLockBasedLockChecker.java @@ -1,19 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.affinity.testimpl; import net.openhft.affinity.lockchecker.FileLockBasedLockChecker; diff --git a/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java b/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java index 84d39c833..359c06e02 100644 --- a/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java +++ b/affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package net.openhft.ticker.impl; import net.openhft.affinity.Affinity; diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java index 5f49c8503..19be7b0b4 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package software.chronicle.enterprise.internals; import net.openhft.affinity.BaseAffinityTest; diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java index 7f7afecd3..138d64337 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java @@ -1,20 +1,6 @@ /* - * Copyright 2016-2025 chronicle.software - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - package software.chronicle.enterprise.internals; import net.openhft.affinity.BaseAffinityTest; diff --git a/pom.xml b/pom.xml index e08693cd9..0cf19304e 100644 --- a/pom.xml +++ b/pom.xml @@ -1,19 +1,9 @@ + + Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + +--> 4.0.0 @@ -21,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea1 + 1.27ea2-SNAPSHOT From 4b22ead225ae98c514041499c4bf21354189f250 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 11 Nov 2025 16:15:48 +0000 Subject: [PATCH 100/110] Fix URL in README for micro-jitter article --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 61367bd58..13720fe77 100644 --- a/README.adoc +++ b/README.adoc @@ -90,7 +90,7 @@ https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/How-it-works -http://vanillajava.blogspot.co.uk/2013/07/micro-jitter-busy-waiting-and-binding.html +https://vanillajava.blogspot.com/2013/07/micro-jitter-busy-waiting-and-binding.html === isolcpus From e9b0f01b9f7f258e09fb7485b01fbcd183389592 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 11 Nov 2025 16:46:32 +0000 Subject: [PATCH 101/110] Refactor access modifiers and suppress warnings in affinity classes --- affinity-test/pom.xml | 2 ++ .../openhft/affinity/osgi/OSGiBundleTest.java | 2 +- .../openhft/affinity/osgi/OSGiTestBase.java | 8 ++--- affinity/pom.xml | 31 ++----------------- .../internals/impl/NativeAffinity.java | 1 + .../affinity/AffinityLockDumpLocksTest.java | 2 +- .../affinity/MultiProcessAffinityTest.java | 4 +-- .../impl/AbstractAffinityImplTest.java | 6 ++-- .../enterprise/internals/JnaAffinityTest.java | 6 ++-- .../internals/NativeAffinityTest.java | 6 ++-- 10 files changed, 22 insertions(+), 46 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 9b75487b5..97d18e308 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -24,6 +24,8 @@ UTF-8 + 0 + 0 diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java index 7896c6d7a..a3213a6e7 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiBundleTest.java @@ -21,7 +21,7 @@ @RunWith(PaxExam.class) public class OSGiBundleTest extends net.openhft.affinity.osgi.OSGiTestBase { @Inject - BundleContext context; + private BundleContext context; @Configuration public Option[] config() { diff --git a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java index 347d2edf0..a5fb702dd 100644 --- a/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java +++ b/affinity-test/src/test/java/net/openhft/affinity/osgi/OSGiTestBase.java @@ -11,9 +11,9 @@ import java.io.File; -public class OSGiTestBase { +class OSGiTestBase { - public static Option workspaceBundle(String projectName) { + static Option workspaceBundle(String projectName) { String baseDir = System.getProperty("main.basedir"); String bundleDir; @@ -30,11 +30,11 @@ public static Option workspaceBundle(String projectName) { return null; } - public static MavenArtifactProvisionOption mavenBundleAsInProject(final String groupId, final String artifactId) { + static MavenArtifactProvisionOption mavenBundleAsInProject(final String groupId, final String artifactId) { return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject(); } - public static Bundle findBundle(BundleContext context, String symbolicName) { + static Bundle findBundle(BundleContext context, String symbolicName) { Bundle[] bundles = context.getBundles(); for (Bundle bundle : bundles) { if (bundle != null) { diff --git a/affinity/pom.xml b/affinity/pom.xml index e778dd9e1..b2071fe41 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -25,6 +25,8 @@ src/main/c UTF-8 + 0.5 + 0.4 @@ -132,35 +134,6 @@ - - sonar - - - - org.sonarsource.scanner.maven - sonar-maven-plugin - - - org.jacoco - jacoco-maven-plugin - - - - prepare-agent - - - - report - prepare-package - - report - - - - - - - diff --git a/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java b/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java index cf95002bb..aa501a8f0 100644 --- a/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java +++ b/affinity/src/main/java/software/chronicle/enterprise/internals/impl/NativeAffinity.java @@ -28,6 +28,7 @@ public enum NativeAffinity implements IAffinity { private native static long rdtsc0(); + @SuppressWarnings("restricted") private static boolean loadAffinityNativeLibrary() { try { System.loadLibrary("CEInternals"); diff --git a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java index 984b18b5f..dd87e4f4e 100644 --- a/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java +++ b/affinity/src/test/java/net/openhft/affinity/AffinityLockDumpLocksTest.java @@ -17,7 +17,7 @@ public class AffinityLockDumpLocksTest extends BaseAffinityTest { - static void supressUnusedWarning(AutoCloseable c) { + private static void supressUnusedWarning(AutoCloseable c) { // do nothing } diff --git a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java index 56fd81b69..63dd9105b 100644 --- a/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java +++ b/affinity/src/test/java/net/openhft/affinity/MultiProcessAffinityTest.java @@ -142,7 +142,7 @@ static class RepeatedAffinityLocker implements Callable { private final int iterations; private final String cpuIdToLock; - public RepeatedAffinityLocker(String cpuIdToLock, int iterations) { + RepeatedAffinityLocker(String cpuIdToLock, int iterations) { this.iterations = iterations; this.cpuIdToLock = cpuIdToLock; } @@ -255,7 +255,7 @@ public static void main(String[] args) throws InterruptedException, IOException } @NotNull - protected static File toFile(int id) { + static File toFile(int id) { return new TestFileLockBasedLockChecker().doToFile(id); } } diff --git a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java index ec45f0e3f..6c1cc5fbf 100644 --- a/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java +++ b/affinity/src/test/java/net/openhft/affinity/impl/AbstractAffinityImplTest.java @@ -18,14 +18,14 @@ */ public abstract class AbstractAffinityImplTest extends BaseAffinityTest { - protected static final int CORES = Runtime.getRuntime().availableProcessors(); - protected static final BitSet CORES_MASK = new BitSet(CORES); + private static final int CORES = Runtime.getRuntime().availableProcessors(); + private static final BitSet CORES_MASK = new BitSet(CORES); static { CORES_MASK.set(0, CORES, true); } - public abstract IAffinity getImpl(); + protected abstract IAffinity getImpl(); @Test public void getAffinityCompletesGracefully() { diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java index 19be7b0b4..a65863c1d 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/JnaAffinityTest.java @@ -20,8 +20,8 @@ * @author peter.lawrey */ public class JnaAffinityTest extends BaseAffinityTest { - protected static final int CORES = Runtime.getRuntime().availableProcessors(); - protected static final BitSet CORES_MASK = new BitSet(CORES); + private static final int CORES = Runtime.getRuntime().availableProcessors(); + private static final BitSet CORES_MASK = new BitSet(CORES); static { CORES_MASK.set(0, CORES, true); @@ -90,7 +90,7 @@ public void tearDown() { getImpl().setAffinity(CORES_MASK); } - public IAffinity getImpl() { + private IAffinity getImpl() { return LinuxJNAAffinity.INSTANCE; } } diff --git a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java index 138d64337..fa2bc7fba 100644 --- a/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java +++ b/affinity/src/test/java/software/chronicle/enterprise/internals/NativeAffinityTest.java @@ -18,8 +18,8 @@ * @author peter.lawrey */ public class NativeAffinityTest extends BaseAffinityTest { - protected static final int CORES = Runtime.getRuntime().availableProcessors(); - protected static final BitSet CORES_MASK = new BitSet(CORES); + private static final int CORES = Runtime.getRuntime().availableProcessors(); + private static final BitSet CORES_MASK = new BitSet(CORES); static { CORES_MASK.set(0, CORES, true); @@ -116,7 +116,7 @@ public void tearDown() { getImpl().setAffinity(CORES_MASK); } - public IAffinity getImpl() { + private IAffinity getImpl() { return NativeAffinity.INSTANCE; } } From ddda97892e3e5ea9162d1be58e48f55f144d74ba Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Wed, 12 Nov 2025 18:43:13 +0000 Subject: [PATCH 102/110] Updating parent POM (automated) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 97d18e308..dda8870da 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea2-SNAPSHOT + 1.27ea1 diff --git a/affinity/pom.xml b/affinity/pom.xml index b2071fe41..5a9e309eb 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea2-SNAPSHOT + 1.27ea1 diff --git a/pom.xml b/pom.xml index 0cf19304e..ca8cfcb7b 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea2-SNAPSHOT + 1.27ea1 From 4fd4253a565a53c71fea45f733c6744d21048d65 Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 14 Nov 2025 22:02:39 +0000 Subject: [PATCH 103/110] Updating third-party-bom version (automated) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index dda8870da..8f7a2baa3 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -33,7 +33,7 @@ net.openhft third-party-bom - 3.27ea0 + 3.27ea5 pom import diff --git a/affinity/pom.xml b/affinity/pom.xml index 5a9e309eb..8b9a31249 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -34,7 +34,7 @@ net.openhft third-party-bom - 3.27ea2 + 3.27ea5 pom import From 7078d184258da23a63388c7c8ca21771ecb12a0e Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Mon, 1 Dec 2025 16:49:24 +0000 Subject: [PATCH 104/110] Initial update of version 2026.0-SNAPSHOT --- affinity-test/pom.xml | 4 ++-- affinity/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 8f7a2baa3..8ff70df8e 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -16,7 +16,7 @@ affinity-test - 3.27ea2-SNAPSHOT + 2026.0-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity-test @@ -33,7 +33,7 @@ net.openhft third-party-bom - 3.27ea5 + 2026.0-SNAPSHOT pom import diff --git a/affinity/pom.xml b/affinity/pom.xml index 8b9a31249..8a477942f 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -16,7 +16,7 @@ affinity - 3.27ea2-SNAPSHOT + 2026.0-SNAPSHOT bundle OpenHFT/Java-Thread-Affinity/affinity @@ -34,7 +34,7 @@ net.openhft third-party-bom - 3.27ea5 + 2026.0-SNAPSHOT pom import diff --git a/pom.xml b/pom.xml index ca8cfcb7b..5d9698d72 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ Java-Thread-Affinity - 3.27ea2-SNAPSHOT + 2026.0-SNAPSHOT pom OpenHFT/Java-Thread-Affinity Parent From 7ba30baf9ae34fd7671fa980b8dcc1e196d0fcc4 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 2 Dec 2025 09:57:02 +0000 Subject: [PATCH 105/110] Add the quality profile --- affinity/pom.xml | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/affinity/pom.xml b/affinity/pom.xml index 8a477942f..c1e94865b 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -134,6 +134,82 @@ + + + quality + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.6.0 + + + validate + validate + + check + + + + + net/openhft/quality/checkstyle26/chronicle-baseline-checkstyle.xml + true + true + true + warning + + + + com.puppycrawl.tools + checkstyle + 10.26.1 + + + net.openhft + quality + 2026.0-SNAPSHOT + + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.9.8.1 + + Max + Low + true + true + net/openhft/quality/spotbugs26/chronicle-spotbugs-include.xml + net/openhft/quality/spotbugs26/chronicle-spotbugs-exclude.xml + + + + net.openhft + quality + 2026.0-SNAPSHOT + + + + + spotbugs-main + + process-test-classes + + check + + + + + + + From ee3af8e598a96a1714fa328920660627863746eb Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 2 Dec 2025 13:58:12 +0000 Subject: [PATCH 106/110] Update dependencies and add third-party smoke tests --- affinity-test/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 8ff70df8e..c7f3168eb 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -51,8 +51,8 @@ affinity - javax.inject - javax.inject + jakarta.inject + jakarta.inject-api test From 780e34cb5b4658ca8d31a493052b53be168b9bfd Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Tue, 2 Dec 2025 14:27:51 +0000 Subject: [PATCH 107/110] quality rules to be moved to OpenHFT and inherited --- affinity/pom.xml | 76 ------------------------------------------------ 1 file changed, 76 deletions(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index c1e94865b..8a477942f 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -134,82 +134,6 @@ - - - quality - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.6.0 - - - validate - validate - - check - - - - - net/openhft/quality/checkstyle26/chronicle-baseline-checkstyle.xml - true - true - true - warning - - - - com.puppycrawl.tools - checkstyle - 10.26.1 - - - net.openhft - quality - 2026.0-SNAPSHOT - - - - - com.github.spotbugs - spotbugs-maven-plugin - 4.9.8.1 - - Max - Low - true - true - net/openhft/quality/spotbugs26/chronicle-spotbugs-include.xml - net/openhft/quality/spotbugs26/chronicle-spotbugs-exclude.xml - - - - net.openhft - quality - 2026.0-SNAPSHOT - - - - - spotbugs-main - - process-test-classes - - check - - - - - - - From c7df5f7d5a3cd794981e97f8ad6c08b38acf0307 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Wed, 3 Dec 2025 11:18:42 +0000 Subject: [PATCH 108/110] Update POM versions to 2026.0-SNAPSHOT --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index c7f3168eb..7304c6eb2 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea1 + 2026.0-SNAPSHOT diff --git a/affinity/pom.xml b/affinity/pom.xml index 8a477942f..e4e8e4bd6 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea1 + 2026.0-SNAPSHOT @@ -41,7 +41,7 @@ net.openhft chronicle-bom - 2.27ea-SNAPSHOT + 2026.0-SNAPSHOT pom import diff --git a/pom.xml b/pom.xml index 5d9698d72..ee5a566df 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 1.27ea1 + 2026.0-SNAPSHOT From 41db4a3b1b6b98d6c18b1ffa8b38846f71177b28 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 4 Dec 2025 09:12:47 +0000 Subject: [PATCH 109/110] Update JaCoCo coverage thresholds and clean up pom.xml properties --- affinity/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/affinity/pom.xml b/affinity/pom.xml index e4e8e4bd6..76c3d50d9 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -25,7 +25,7 @@ src/main/c UTF-8 - 0.5 + 0.40 0.4 From 5f6ec5c44ec5b129a385b20f765f45fd692c61fa Mon Sep 17 00:00:00 2001 From: hft-team-city Date: Fri, 19 Dec 2025 21:06:19 +0000 Subject: [PATCH 110/110] Updating parent POM (automated) --- affinity-test/pom.xml | 2 +- affinity/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/affinity-test/pom.xml b/affinity-test/pom.xml index 7304c6eb2..c7f3168eb 100644 --- a/affinity-test/pom.xml +++ b/affinity-test/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 2026.0-SNAPSHOT + 1.27ea1 diff --git a/affinity/pom.xml b/affinity/pom.xml index 76c3d50d9..e3cd6173d 100644 --- a/affinity/pom.xml +++ b/affinity/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 2026.0-SNAPSHOT + 1.27ea1 diff --git a/pom.xml b/pom.xml index ee5a566df..5d9698d72 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.openhft java-parent-pom - 2026.0-SNAPSHOT + 1.27ea1