18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @run testng TestSpliterator
27 */
28
29 import jdk.incubator.foreign.MemoryAddress;
30 import jdk.incubator.foreign.MemoryLayout;
31 import jdk.incubator.foreign.MemoryLayouts;
32 import jdk.incubator.foreign.MemorySegment;
33 import jdk.incubator.foreign.SequenceLayout;
34
35 import java.lang.invoke.VarHandle;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Spliterator;
39 import java.util.concurrent.CountedCompleter;
40 import java.util.concurrent.RecursiveTask;
41 import java.util.concurrent.atomic.AtomicLong;
42 import java.util.stream.LongStream;
43 import java.util.stream.StreamSupport;
44
45 import org.testng.annotations.*;
46 import static org.testng.Assert.*;
47
48 public class TestSpliterator {
49
50 static final VarHandle INT_HANDLE = MemoryLayout.ofSequence(MemoryLayouts.JAVA_INT)
51 .varHandle(int.class, MemoryLayout.PathElement.sequenceElement());
52
53 final static int CARRIER_SIZE = 4;
54
55 @Test(dataProvider = "splits")
56 public void testSum(int size, int threshold) {
57 SequenceLayout layout = MemoryLayout.ofSequence(size, MemoryLayouts.JAVA_INT);
58
59 //setup
60 MemorySegment segment = MemorySegment.allocateNative(layout);
61 for (int i = 0; i < layout.elementCount().getAsLong(); i++) {
62 INT_HANDLE.set(segment.baseAddress(), (long) i, i);
63 }
64 long expected = LongStream.range(0, layout.elementCount().getAsLong()).sum();
65 //serial
73 assertEquals(parallelRecursive, expected);
74 //parallel stream
75 long streamParallel = StreamSupport.stream(MemorySegment.spliterator(segment, layout), true)
76 .reduce(0L, TestSpliterator::sumSingle, Long::sum);
77 assertEquals(streamParallel, expected);
78 segment.close();
79 }
80
81 public void testSumSameThread() {
82 SequenceLayout layout = MemoryLayout.ofSequence(1024, MemoryLayouts.JAVA_INT);
83
84 //setup
85 MemorySegment segment = MemorySegment.allocateNative(layout);
86 for (int i = 0; i < layout.elementCount().getAsLong(); i++) {
87 INT_HANDLE.set(segment.baseAddress(), (long) i, i);
88 }
89 long expected = LongStream.range(0, layout.elementCount().getAsLong()).sum();
90
91 //check that a segment w/o ACQUIRE access mode can still be used from same thread
92 AtomicLong spliteratorSum = new AtomicLong();
93 MemorySegment.spliterator(segment.withAccessModes(MemorySegment.READ), layout)
94 .forEachRemaining(s -> spliteratorSum.addAndGet(sumSingle(0L, s)));
95 assertEquals(spliteratorSum.get(), expected);
96 }
97
98 static long sumSingle(long acc, MemorySegment segment) {
99 return acc + (int)INT_HANDLE.get(segment.baseAddress(), 0L);
100 }
101
102 static long sum(long start, MemorySegment segment) {
103 long sum = start;
104 MemoryAddress base = segment.baseAddress();
105 int length = (int)segment.byteSize();
106 for (int i = 0 ; i < length / CARRIER_SIZE ; i++) {
107 sum += (int)INT_HANDLE.get(base, (long)i);
108 }
109 return sum;
110 }
111
112 static class SumSegmentCounted extends CountedCompleter<Long> {
113
183 { 1000, 1 },
184 { 10000, 1 },
185 { 10, 10 },
186 { 100, 10 },
187 { 1000, 10 },
188 { 10000, 10 },
189 { 10, 100 },
190 { 100, 100 },
191 { 1000, 100 },
192 { 10000, 100 },
193 { 10, 1000 },
194 { 100, 1000 },
195 { 1000, 1000 },
196 { 10000, 1000 },
197 { 10, 10000 },
198 { 100, 10000 },
199 { 1000, 10000 },
200 { 10000, 10000 },
201 };
202 }
203 }
|
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @run testng TestSpliterator
27 */
28
29 import jdk.incubator.foreign.MemoryAddress;
30 import jdk.incubator.foreign.MemoryLayout;
31 import jdk.incubator.foreign.MemoryLayouts;
32 import jdk.incubator.foreign.MemorySegment;
33 import jdk.incubator.foreign.SequenceLayout;
34
35 import java.lang.invoke.VarHandle;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Spliterator;
40 import java.util.concurrent.CountedCompleter;
41 import java.util.concurrent.RecursiveTask;
42 import java.util.concurrent.atomic.AtomicLong;
43 import java.util.function.Consumer;
44 import java.util.function.Supplier;
45 import java.util.stream.LongStream;
46 import java.util.stream.StreamSupport;
47
48 import org.testng.annotations.*;
49 import static jdk.incubator.foreign.MemorySegment.*;
50 import static org.testng.Assert.*;
51
52 public class TestSpliterator {
53
54 static final VarHandle INT_HANDLE = MemoryLayout.ofSequence(MemoryLayouts.JAVA_INT)
55 .varHandle(int.class, MemoryLayout.PathElement.sequenceElement());
56
57 final static int CARRIER_SIZE = 4;
58
59 @Test(dataProvider = "splits")
60 public void testSum(int size, int threshold) {
61 SequenceLayout layout = MemoryLayout.ofSequence(size, MemoryLayouts.JAVA_INT);
62
63 //setup
64 MemorySegment segment = MemorySegment.allocateNative(layout);
65 for (int i = 0; i < layout.elementCount().getAsLong(); i++) {
66 INT_HANDLE.set(segment.baseAddress(), (long) i, i);
67 }
68 long expected = LongStream.range(0, layout.elementCount().getAsLong()).sum();
69 //serial
77 assertEquals(parallelRecursive, expected);
78 //parallel stream
79 long streamParallel = StreamSupport.stream(MemorySegment.spliterator(segment, layout), true)
80 .reduce(0L, TestSpliterator::sumSingle, Long::sum);
81 assertEquals(streamParallel, expected);
82 segment.close();
83 }
84
85 public void testSumSameThread() {
86 SequenceLayout layout = MemoryLayout.ofSequence(1024, MemoryLayouts.JAVA_INT);
87
88 //setup
89 MemorySegment segment = MemorySegment.allocateNative(layout);
90 for (int i = 0; i < layout.elementCount().getAsLong(); i++) {
91 INT_HANDLE.set(segment.baseAddress(), (long) i, i);
92 }
93 long expected = LongStream.range(0, layout.elementCount().getAsLong()).sum();
94
95 //check that a segment w/o ACQUIRE access mode can still be used from same thread
96 AtomicLong spliteratorSum = new AtomicLong();
97 spliterator(segment.withAccessModes(MemorySegment.READ), layout)
98 .forEachRemaining(s -> spliteratorSum.addAndGet(sumSingle(0L, s)));
99 assertEquals(spliteratorSum.get(), expected);
100 }
101
102 static long sumSingle(long acc, MemorySegment segment) {
103 return acc + (int)INT_HANDLE.get(segment.baseAddress(), 0L);
104 }
105
106 static long sum(long start, MemorySegment segment) {
107 long sum = start;
108 MemoryAddress base = segment.baseAddress();
109 int length = (int)segment.byteSize();
110 for (int i = 0 ; i < length / CARRIER_SIZE ; i++) {
111 sum += (int)INT_HANDLE.get(base, (long)i);
112 }
113 return sum;
114 }
115
116 static class SumSegmentCounted extends CountedCompleter<Long> {
117
187 { 1000, 1 },
188 { 10000, 1 },
189 { 10, 10 },
190 { 100, 10 },
191 { 1000, 10 },
192 { 10000, 10 },
193 { 10, 100 },
194 { 100, 100 },
195 { 1000, 100 },
196 { 10000, 100 },
197 { 10, 1000 },
198 { 100, 1000 },
199 { 1000, 1000 },
200 { 10000, 1000 },
201 { 10, 10000 },
202 { 100, 10000 },
203 { 1000, 10000 },
204 { 10000, 10000 },
205 };
206 }
207
208 static final int ALL_ACCESS_MODES = READ | WRITE | CLOSE | ACQUIRE | HANDOFF;
209
210 @DataProvider(name = "accessScenarios")
211 public Object[][] accessScenarios() {
212 SequenceLayout layout = MemoryLayout.ofSequence(16, MemoryLayouts.JAVA_INT);
213 var mallocSegment = MemorySegment.allocateNative(layout);
214
215 Map<Supplier<Spliterator<MemorySegment>>,Integer> l = Map.of(
216 () -> spliterator(mallocSegment.withAccessModes(ALL_ACCESS_MODES), layout), ALL_ACCESS_MODES,
217 () -> spliterator(mallocSegment.withAccessModes(0), layout), 0,
218 () -> spliterator(mallocSegment.withAccessModes(READ), layout), READ,
219 () -> spliterator(mallocSegment.withAccessModes(CLOSE), layout), 0,
220 () -> spliterator(mallocSegment.withAccessModes(READ|WRITE), layout), READ|WRITE,
221 () -> spliterator(mallocSegment.withAccessModes(READ|WRITE|ACQUIRE), layout), READ|WRITE|ACQUIRE,
222 () -> spliterator(mallocSegment.withAccessModes(READ|WRITE|ACQUIRE|HANDOFF), layout), READ|WRITE|ACQUIRE|HANDOFF
223
224 );
225 return l.entrySet().stream().map(e -> new Object[] { e.getKey(), e.getValue() }).toArray(Object[][]::new);
226 }
227
228 static Consumer<MemorySegment> assertAccessModes(int accessModes) {
229 return segment -> {
230 assertTrue(segment.hasAccessModes(accessModes & ~CLOSE));
231 assertEquals(segment.accessModes(), accessModes & ~CLOSE);
232 };
233 }
234
235 @Test(dataProvider = "accessScenarios")
236 public void testAccessModes(Supplier<Spliterator<MemorySegment>> spliteratorSupplier,
237 int expectedAccessModes) {
238 Spliterator<MemorySegment> spliterator = spliteratorSupplier.get();
239 spliterator.forEachRemaining(assertAccessModes(expectedAccessModes));
240
241 spliterator = spliteratorSupplier.get();
242 do { } while (spliterator.tryAdvance(assertAccessModes(expectedAccessModes)));
243
244 splitOrConsume(spliteratorSupplier.get(), assertAccessModes(expectedAccessModes));
245 }
246
247 static void splitOrConsume(Spliterator<MemorySegment> spliterator,
248 Consumer<MemorySegment> consumer) {
249 var s1 = spliterator.trySplit();
250 if (s1 != null) {
251 splitOrConsume(s1, consumer);
252 splitOrConsume(spliterator, consumer);
253 } else {
254 spliterator.forEachRemaining(consumer);
255 }
256 }
257 }
|