Path: blob/master/test/jdk/java/foreign/TestSharedAccess.java
41145 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324/*25* @test26* @run testng/othervm --enable-native-access=ALL-UNNAMED TestSharedAccess27*/2829import jdk.incubator.foreign.*;30import org.testng.annotations.*;3132import java.lang.invoke.VarHandle;33import java.nio.ByteBuffer;34import java.util.ArrayList;35import java.util.List;36import java.util.Spliterator;37import java.util.concurrent.CompletableFuture;38import java.util.concurrent.CountDownLatch;39import java.util.concurrent.atomic.AtomicInteger;4041import static org.testng.Assert.*;4243public class TestSharedAccess {4445static final VarHandle intHandle = MemoryLayouts.JAVA_INT.varHandle(int.class);4647@Test48public void testShared() throws Throwable {49SequenceLayout layout = MemoryLayout.sequenceLayout(1024, MemoryLayouts.JAVA_INT);50try (ResourceScope scope = ResourceScope.newSharedScope()) {51MemorySegment s = MemorySegment.allocateNative(layout, scope);52for (int i = 0 ; i < layout.elementCount().getAsLong() ; i++) {53setInt(s.asSlice(i * 4), 42);54}55List<Thread> threads = new ArrayList<>();56List<Spliterator<MemorySegment>> spliterators = new ArrayList<>();57spliterators.add(s.spliterator(layout.elementLayout()));58while (true) {59boolean progress = false;60List<Spliterator<MemorySegment>> newSpliterators = new ArrayList<>();61for (Spliterator<MemorySegment> spliterator : spliterators) {62Spliterator<MemorySegment> sub = spliterator.trySplit();63if (sub != null) {64progress = true;65newSpliterators.add(sub);66}67}68spliterators.addAll(newSpliterators);69if (!progress) break;70}7172AtomicInteger accessCount = new AtomicInteger();73for (Spliterator<MemorySegment> spliterator : spliterators) {74threads.add(new Thread(() -> {75spliterator.tryAdvance(local -> {76assertEquals(getInt(local), 42);77accessCount.incrementAndGet();78});79}));80}81threads.forEach(Thread::start);82threads.forEach(t -> {83try {84t.join();85} catch (Throwable e) {86throw new IllegalStateException(e);87}88});89assertEquals(accessCount.get(), 1024);90}91}9293@Test94public void testSharedUnsafe() throws Throwable {95try (ResourceScope scope = ResourceScope.newSharedScope()) {96MemorySegment s = MemorySegment.allocateNative(4, 1, scope);97setInt(s, 42);98assertEquals(getInt(s), 42);99List<Thread> threads = new ArrayList<>();100MemorySegment sharedSegment = s.address().asSegment(s.byteSize(), scope);101for (int i = 0 ; i < 1000 ; i++) {102threads.add(new Thread(() -> {103assertEquals(getInt(sharedSegment), 42);104}));105}106threads.forEach(Thread::start);107threads.forEach(t -> {108try {109t.join();110} catch (Throwable e) {111throw new IllegalStateException(e);112}113});114}115}116117@Test118public void testOutsideConfinementThread() throws Throwable {119CountDownLatch a = new CountDownLatch(1);120CountDownLatch b = new CountDownLatch(1);121CompletableFuture<?> r;122try (ResourceScope scope = ResourceScope.newConfinedScope()) {123MemorySegment s1 = MemorySegment.allocateNative(MemoryLayout.sequenceLayout(2, MemoryLayouts.JAVA_INT), scope);124r = CompletableFuture.runAsync(() -> {125try {126ByteBuffer bb = s1.asByteBuffer();127128MemorySegment s2 = MemorySegment.ofByteBuffer(bb);129a.countDown();130131try {132b.await();133} catch (InterruptedException e) {134}135136setInt(s2.asSlice(4), -42);137fail();138} catch (IllegalStateException ex) {139assertTrue(ex.getMessage().contains("owning thread"));140}141});142143a.await();144setInt(s1.asSlice(4), 42);145}146147b.countDown();148r.get();149}150151static int getInt(MemorySegment base) {152return (int)intHandle.getVolatile(base);153}154155static void setInt(MemorySegment base, int value) {156intHandle.setVolatile(base, value);157}158}159160161