--- old/test/jdk/java/foreign/TestSpliterator.java 2020-04-30 16:04:13.000000000 +0100 +++ new/test/jdk/java/foreign/TestSpliterator.java 2020-04-30 16:04:13.000000000 +0100 @@ -35,14 +35,18 @@ import java.lang.invoke.VarHandle; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Spliterator; import java.util.concurrent.CountedCompleter; import java.util.concurrent.RecursiveTask; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; +import java.util.function.Supplier; import java.util.stream.LongStream; import java.util.stream.StreamSupport; import org.testng.annotations.*; +import static jdk.incubator.foreign.MemorySegment.*; import static org.testng.Assert.*; public class TestSpliterator { @@ -90,7 +94,7 @@ //check that a segment w/o ACQUIRE access mode can still be used from same thread AtomicLong spliteratorSum = new AtomicLong(); - MemorySegment.spliterator(segment.withAccessModes(MemorySegment.READ), layout) + spliterator(segment.withAccessModes(MemorySegment.READ), layout) .forEachRemaining(s -> spliteratorSum.addAndGet(sumSingle(0L, s))); assertEquals(spliteratorSum.get(), expected); } @@ -200,4 +204,54 @@ { 10000, 10000 }, }; } + + static final int ALL_ACCESS_MODES = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; + + @DataProvider(name = "accessScenarios") + public Object[][] accessScenarios() { + SequenceLayout layout = MemoryLayout.ofSequence(16, MemoryLayouts.JAVA_INT); + var mallocSegment = MemorySegment.allocateNative(layout); + + Map>,Integer> l = Map.of( + () -> spliterator(mallocSegment.withAccessModes(ALL_ACCESS_MODES), layout), ALL_ACCESS_MODES, + () -> spliterator(mallocSegment.withAccessModes(0), layout), 0, + () -> spliterator(mallocSegment.withAccessModes(READ), layout), READ, + () -> spliterator(mallocSegment.withAccessModes(CLOSE), layout), 0, + () -> spliterator(mallocSegment.withAccessModes(READ|WRITE), layout), READ|WRITE, + () -> spliterator(mallocSegment.withAccessModes(READ|WRITE|ACQUIRE), layout), READ|WRITE|ACQUIRE, + () -> spliterator(mallocSegment.withAccessModes(READ|WRITE|ACQUIRE|HANDOFF), layout), READ|WRITE|ACQUIRE|HANDOFF + + ); + return l.entrySet().stream().map(e -> new Object[] { e.getKey(), e.getValue() }).toArray(Object[][]::new); + } + + static Consumer assertAccessModes(int accessModes) { + return segment -> { + assertTrue(segment.hasAccessModes(accessModes & ~CLOSE)); + assertEquals(segment.accessModes(), accessModes & ~CLOSE); + }; + } + + @Test(dataProvider = "accessScenarios") + public void testAccessModes(Supplier> spliteratorSupplier, + int expectedAccessModes) { + Spliterator spliterator = spliteratorSupplier.get(); + spliterator.forEachRemaining(assertAccessModes(expectedAccessModes)); + + spliterator = spliteratorSupplier.get(); + do { } while (spliterator.tryAdvance(assertAccessModes(expectedAccessModes))); + + splitOrConsume(spliteratorSupplier.get(), assertAccessModes(expectedAccessModes)); + } + + static void splitOrConsume(Spliterator spliterator, + Consumer consumer) { + var s1 = spliterator.trySplit(); + if (s1 != null) { + splitOrConsume(s1, consumer); + splitOrConsume(spliterator, consumer); + } else { + spliterator.forEachRemaining(consumer); + } + } }