From 337698b408d7bb49cb2a8bbd4282846a29f728c2 Mon Sep 17 00:00:00 2001 From: Peter Lawrey Date: Thu, 13 Sep 2018 16:56:44 +0100 Subject: [PATCH 1/2] Added ARM support for UnsafeMemory, https://github.com/OpenHFT/OpenHFT/issues/23 --- .../map/impl/stage/data/ZeroBytesStore.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) mode change 100644 => 100755 src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java b/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java old mode 100644 new mode 100755 index 66e48eeb9..e3c2e4d51 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java @@ -23,7 +23,6 @@ import net.openhft.chronicle.core.OS; import org.jetbrains.annotations.Nullable; import java.nio.BufferOverflowException; -import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; public enum ZeroBytesStore implements BytesStore { @@ -40,22 +39,22 @@ public enum ZeroBytesStore implements BytesStore { } @Override - public byte readVolatileByte(long offset) throws BufferUnderflowException { + public byte readVolatileByte(long offset) { return 0; } @Override - public short readVolatileShort(long offset) throws BufferUnderflowException { + public short readVolatileShort(long offset) { return 0; } @Override - public int readVolatileInt(long offset) throws BufferUnderflowException { + public int readVolatileInt(long offset) { return 0; } @Override - public long readVolatileLong(long offset) throws BufferUnderflowException { + public long readVolatileLong(long offset) { return 0; } @@ -128,20 +127,29 @@ public enum ZeroBytesStore implements BytesStore { } @Override - public long addressForRead(long offset) throws UnsupportedOperationException { + public long addressForRead(long offset) { return offset; } @Override - public boolean compareAndSwapInt(long offset, int expected, int value) - throws BufferOverflowException, IllegalArgumentException { - throw new UnsupportedOperationException(); + public boolean compareAndSwapInt(long offset, int expected, int value) { + if (expected != 0 || value != 0) + throw new UnsupportedOperationException(); + return true; } @Override - public boolean compareAndSwapLong(long offset, long expected, long value) - throws BufferOverflowException, IllegalArgumentException { - throw new UnsupportedOperationException(); + public void testAndSetInt(long offset, int expected, int value) { + if (expected != 0 || value != 0) + throw new UnsupportedOperationException(); + } + + + @Override + public boolean compareAndSwapLong(long offset, long expected, long value) { + if (expected != 0 || value != 0) + throw new UnsupportedOperationException(); + return true; } @Override From b413c026ee4ac67ca96dd760e7f386612574ab73 Mon Sep 17 00:00:00 2001 From: peter lawrey Date: Fri, 14 Sep 2018 11:26:13 +0000 Subject: [PATCH 2/2] Added ARM support for UnsafeMemory, https://github.com/OpenHFT/OpenHFT/issues/23 --- .../java/net/openhft/chronicle/map/ChronicleMapBuilder.java | 3 +++ .../chronicle/map/impl/stage/data/ZeroBytesStore.java | 2 +- .../java/net/openhft/chronicle/map/ChronicleMapTest.java | 6 +++--- .../net/openhft/chronicle/map/DemoChronicleMapTest.java | 6 ++++++ src/test/java/net/openhft/chronicle/map/RecoverTest.java | 3 +++ .../openhft/chronicle/map/fromdocs/ChecksumEntryTest.java | 4 ++++ .../map/fromdocs/OpenJDKAndHashMapExamplesTest.java | 4 ++-- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index d71fa4148..0b5a99d75 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -750,6 +750,7 @@ public final class ChronicleMapBuilder implements double valueSize = averageValueSize(); size += averageSizeStoringLength(valueBuilder, valueSize); int alignment = valueAlignment(); + size = alignAddr((long) Math.ceil(size), alignment); // so the value starts aligned int worstAlignment; if (worstAlignmentComputationRequiresValueSize(alignment)) { long constantSizeBeforeAlignment = toLong(size); @@ -925,6 +926,8 @@ public final class ChronicleMapBuilder implements throw new IllegalArgumentException("Alignment should be a power of 2, " + alignment + " given"); } + if (Jvm.isArm() && alignment < 8) + return this; this.alignment = alignment; return this; } diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java b/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java index e3c2e4d51..71c7b7eaa 100755 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/data/ZeroBytesStore.java @@ -144,7 +144,6 @@ public enum ZeroBytesStore implements BytesStore { throw new UnsupportedOperationException(); } - @Override public boolean compareAndSwapLong(long offset, long expected, long value) { if (expected != 0 || value != 0) @@ -152,6 +151,7 @@ public enum ZeroBytesStore implements BytesStore { return true; } + @Override public void reserve() throws IllegalStateException { } diff --git a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java index 761a3fd16..75d4560b6 100755 --- a/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/ChronicleMapTest.java @@ -619,7 +619,7 @@ public class ChronicleMapTest { .entries((long) entries) .minSegments(1) .averageKeySize(10) - .entryAndValueOffsetAlignment(4) + .entryAndValueOffsetAlignment(8) .create()) { LongValue value4 = Values.newNativeReference(LongValue.class); LongValue value22 = Values.newNativeReference(LongValue.class); @@ -651,9 +651,9 @@ public class ChronicleMapTest { try (ChronicleMap map1 = ChronicleMapBuilder.of(CharSequence.class, LongValue.class) .entries((long) entries) - .minSegments(1) +// .minSegments(1) .averageKeySize(10) - .entryAndValueOffsetAlignment(1) +// .entryAndValueOffsetAlignment(8) .create()) { LongValue value1 = Values.newNativeReference(LongValue.class); LongValue value21 = Values.newNativeReference(LongValue.class); diff --git a/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java index 6fca59a77..a3c457fe0 100755 --- a/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/DemoChronicleMapTest.java @@ -17,6 +17,7 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.values.IntValue; import net.openhft.chronicle.values.MaxUtf8Length; import net.openhft.chronicle.values.Values; @@ -29,6 +30,7 @@ import java.util.Map; import static net.openhft.chronicle.values.Values.newNativeReference; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assume.assumeFalse; interface DemoOrderVOInterface { public CharSequence getSymbol(); @@ -48,6 +50,7 @@ public class DemoChronicleMapTest { @Test public void testMap() throws IOException { + assumeFalse(Jvm.isArm()); File file = File.createTempFile("DummyOrders" + System.currentTimeMillis(), ".test"); file.deleteOnExit(); int maxEntries = 1000; @@ -56,6 +59,7 @@ public class DemoChronicleMapTest { .putReturnsNull(true) .removeReturnsNull(true) .entries(maxEntries) + .entryAndValueOffsetAlignment(8) .createPersistedTo(file)) { IntValue key = Values.newHeapInstance(IntValue.class); @@ -90,6 +94,7 @@ public class DemoChronicleMapTest { @Test public void testMapLocked() throws IOException { + assumeFalse(Jvm.isArm()); File file = File.createTempFile("DummyOrders-" + System.currentTimeMillis(), ".test"); file.deleteOnExit(); int maxEntries = 1000; @@ -98,6 +103,7 @@ public class DemoChronicleMapTest { .putReturnsNull(true) .removeReturnsNull(true) .entries(maxEntries) + .entryAndValueOffsetAlignment(8) .createPersistedTo(file)) { IntValue key = Values.newHeapInstance(IntValue.class); diff --git a/src/test/java/net/openhft/chronicle/map/RecoverTest.java b/src/test/java/net/openhft/chronicle/map/RecoverTest.java index fd00cb67d..3e6e4ec18 100644 --- a/src/test/java/net/openhft/chronicle/map/RecoverTest.java +++ b/src/test/java/net/openhft/chronicle/map/RecoverTest.java @@ -17,6 +17,7 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.values.LongValue; import net.openhft.chronicle.hash.ChecksumEntry; import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; @@ -40,6 +41,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static net.openhft.chronicle.map.ChronicleMapTest.getPersistenceFile; import static org.junit.Assert.*; +import static org.junit.Assume.assumeFalse; public class RecoverTest { @@ -126,6 +128,7 @@ public class RecoverTest { @Test public void testCorruptedEntryRecovery() throws IOException { + assumeFalse(Jvm.isArm()); File file = getPersistenceFile(); try (ChronicleMap map = ChronicleMap .of(Integer.class, LongValue.class) diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java b/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java index 8605e9d06..e0c7559c6 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/ChecksumEntryTest.java @@ -17,6 +17,7 @@ package net.openhft.chronicle.map.fromdocs; +import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.values.LongValue; import net.openhft.chronicle.hash.ChecksumEntry; import net.openhft.chronicle.map.ChronicleMap; @@ -30,10 +31,13 @@ import org.junit.Test; import java.io.File; import java.io.IOException; +import static org.junit.Assume.assumeFalse; + public class ChecksumEntryTest { @Test public void testChecksumEntriesWithValueInterface() throws IOException { + assumeFalse(Jvm.isArm()); File file = Builder.getPersistenceFile(); try (ChronicleMap map = ChronicleMap diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java b/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java index 32e3e8fde..1d0aca340 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/OpenJDKAndHashMapExamplesTest.java @@ -23,6 +23,7 @@ import net.openhft.chronicle.map.ExternalMapQueryContext; import net.openhft.chronicle.values.Values; import org.junit.Test; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.text.ParseException; @@ -99,8 +100,7 @@ public class OpenJDKAndHashMapExamplesTest { BondVOInterface bond = Values.newNativeReference(BondVOInterface.class); // lookup the key and give me a reference I can update in a thread safe way. - try (net.openhft.chronicle.core.io.Closeable c = - chm.acquireContext("369604103", bond)) { + try (Closeable c = chm.acquireContext("369604103", bond)) { // found a key and bond has been set // get directly without touching the rest of the record. long _matDate = bond.getMaturityDate();