Checkpoint panama work
authorNot Zed <notzed@gmail.com>
Wed, 8 Dec 2021 21:56:36 +0000 (08:26 +1030)
committerNot Zed <notzed@gmail.com>
Wed, 8 Dec 2021 21:56:36 +0000 (08:26 +1030)
src/notzed.zcl/classes/api/Frame.java [new file with mode: 0644]
src/notzed.zcl/tests/au/notzed/zcl/MemoryTest.java [new file with mode: 0644]

diff --git a/src/notzed.zcl/classes/api/Frame.java b/src/notzed.zcl/classes/api/Frame.java
new file mode 100644 (file)
index 0000000..b5ca8c9
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 Michael Zucchi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package api;
+
+import jdk.incubator.foreign.MemoryAccess;
+import jdk.incubator.foreign.MemorySegment;
+
+public interface Frame extends AutoCloseable {
+
+       MemorySegment allocate(long size, long alignment);
+
+       @Override
+       public void close();
+
+       default MemorySegment allocate(long size) {
+               return allocate(size, 1);
+       }
+
+       default MemorySegment copy(byte value) {
+               MemorySegment mem = allocate(1);
+               MemoryAccess.setByte(mem, value);
+               return mem;
+       }
+
+       default MemorySegment copy(int value) {
+               MemorySegment mem = allocate(4, 4);
+               MemoryAccess.setInt(mem, value);
+               return mem;
+       }
+
+       default MemorySegment copy(long value) {
+               MemorySegment mem = allocate(8, 8);
+               MemoryAccess.setLong(mem, value);
+               return mem;
+       }
+
+       default MemorySegment copy(byte[] value, int alignment) {
+               MemorySegment mem = allocate(value.length, alignment);
+               mem.copyFrom(MemorySegment.ofArray(value));
+               return mem;
+       }
+
+       default MemorySegment copy(int[] value, int alignment) {
+               MemorySegment mem = allocate(value.length * 4, alignment);
+               mem.copyFrom(MemorySegment.ofArray(value));
+               return mem;
+       }
+
+       default MemorySegment copy(long[] value, int alignment) {
+               MemorySegment mem = allocate(value.length * 8, alignment);
+               mem.copyFrom(MemorySegment.ofArray(value));
+               return mem;
+       }
+       
+}
diff --git a/src/notzed.zcl/tests/au/notzed/zcl/MemoryTest.java b/src/notzed.zcl/tests/au/notzed/zcl/MemoryTest.java
new file mode 100644 (file)
index 0000000..bcbac8f
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2021 Michael Zucchi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package au.notzed.zcl;
+
+import api.Frame;
+import api.Memory;
+import jdk.incubator.foreign.MemorySegment;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MemoryTest {
+
+       @Before
+       public void setup() {
+       }
+
+       @Test
+       public void testFrameAlignment() throws Exception {
+               System.out.println("testFrame Alignment");
+
+               try (Frame frame = Memory.createFrame()) {
+                       MemorySegment a = frame.allocate(1, 1);
+                       MemorySegment b = frame.allocate(16, 16);
+                       MemorySegment c = frame.allocate(2, 2);
+                       MemorySegment d = frame.allocate(8, 8);
+
+                       assertEquals(b.address().toRawLongValue() & 15, 0);
+                       assertEquals(d.address().toRawLongValue() & 7, 0);
+               }
+       }
+
+       /*
+       @Test
+       public void testFrameExhaustion() throws Exception {
+               Throwable x = null;
+
+               System.out.println("testFrame Exhaustion");
+
+               try (Frame frame = Memory.createFrame()) {
+                       while (true)
+                               frame.allocate(8);
+               } catch (OutOfMemoryError e) {
+                       x = e;
+               }
+
+               assertNotNull(x);
+               assertEquals(x.getClass(), OutOfMemoryError.class);
+       }*/
+       @Test
+       public void testFrameLarge() throws Exception {
+               System.out.println("testFrame Large");
+
+               try (Frame frame = Memory.createFrame()) {
+                       MemorySegment a = frame.allocate(1024 * 1024);
+                       MemorySegment b = frame.allocate(1024 * 1024);
+                       MemorySegment c = frame.allocate(1024 * 1024);
+                       assertNotNull(a);
+                       assertNotNull(b);
+                       assertNotNull(c);
+               }
+       }
+
+       @Test
+       public void testBadAlignment() throws Exception {
+               Throwable x = null;
+
+               System.out.println("testFrame Bad alignment");
+
+               try (Frame frame = Memory.createFrame()) {
+                       MemorySegment a = frame.allocate(1, 3);
+               } catch (IllegalArgumentException e) {
+                       x = e;
+               }
+
+               assertNotNull(x);
+               assertEquals(x.getClass(), IllegalArgumentException.class);
+       }
+
+       @Test
+       public void testAfterClose() throws Exception {
+               Throwable x = null;
+
+               System.out.println("testFrame use after close");
+
+               Frame frame = Memory.createFrame();
+               frame.close();
+               try {
+                       MemorySegment a = frame.allocate(1, 3);
+               } catch (IllegalStateException e) {
+                       x = e;
+               }
+
+               assertNotNull(x);
+               assertEquals(x.getClass(), IllegalStateException.class);
+       }
+
+       static void assertSeparate(MemorySegment a, MemorySegment b) {
+               long ap = a.address().toRawLongValue();
+               long as = a.byteSize();
+               long bp = b.address().toRawLongValue();
+               long bs = b.byteSize();
+
+               assertNotEquals(ap, bp);
+               if (ap < bp) {
+                       assertTrue(String.format("memory overlap %016x - %016x, %016x - %016x", ap, ap + as, bp, bp + bs), ap + as <= bp);
+               } else {
+                       assertTrue(String.format("memory overlap %016x - %016x, %016x - %016x", bp, bp + bs, ap, ap + as), bp + bs <= ap);
+               }
+
+       }
+
+       @Test
+       public void testFrameAlloc() throws Exception {
+               System.out.println("testFrame Alloc");
+
+               try (Frame frame = Memory.createFrame()) {
+                       MemorySegment a = frame.allocate(1, 1);
+                       MemorySegment b = frame.allocate(16, 16);
+                       MemorySegment c = frame.allocate(2, 2);
+                       MemorySegment d = frame.allocate(8, 8);
+
+                       assertEquals(a.byteSize(), 1);
+                       assertEquals(b.byteSize(), 16);
+                       assertEquals(c.byteSize(), 2);
+                       assertEquals(d.byteSize(), 8);
+
+                       assertSeparate(a, b);
+                       assertSeparate(a, c);
+                       assertSeparate(a, d);
+
+                       assertSeparate(b, c);
+                       assertSeparate(b, d);
+
+                       assertSeparate(c, d);
+               }
+       }
+
+       @Test
+       public void testFrameNested() throws Exception {
+               System.out.println("testFrame Nested");
+
+               try (Frame framea = Memory.createFrame()) {
+                       MemorySegment a = framea.allocate(1, 1);
+                       MemorySegment b = framea.allocate(16, 16);
+
+                       try (Frame frameb = Memory.createFrame()) {
+                               MemorySegment c = frameb.allocate(2, 2);
+                               MemorySegment d = frameb.allocate(8, 8);
+
+                               assertEquals(a.byteSize(), 1);
+                               assertEquals(b.byteSize(), 16);
+                               assertEquals(c.byteSize(), 2);
+                               assertEquals(d.byteSize(), 8);
+
+                               assertSeparate(a, b);
+                               assertSeparate(a, c);
+                               assertSeparate(a, d);
+
+                               assertSeparate(b, c);
+                               assertSeparate(b, d);
+
+                               assertSeparate(c, d);
+                       }
+
+                       MemorySegment c = framea.allocate(2, 2);
+                       MemorySegment d = framea.allocate(8, 8);
+
+                       assertEquals(c.byteSize(), 2);
+                       assertEquals(d.byteSize(), 8);
+
+                       assertSeparate(a, b);
+                       assertSeparate(a, c);
+                       assertSeparate(a, d);
+
+                       assertSeparate(b, c);
+                       assertSeparate(b, d);
+
+                       assertSeparate(c, d);
+               }
+       }
+
+}