Search in sources :

Example 41 with ProxyLanguage

use of com.oracle.truffle.api.test.polyglot.ProxyLanguage in project graal by oracle.

the class TruffleSafepointTest method testNoSafepointAfterThreadDispose.

@Test
public void testNoSafepointAfterThreadDispose() {
    final ThreadLocal<Boolean> tl = new ThreadLocal<>();
    ProxyLanguage.setDelegate(new ProxyLanguage() {

        @Override
        @TruffleBoundary
        protected void initializeThread(LanguageContext context, Thread thread) {
            tl.set(Boolean.TRUE);
        }

        @Override
        @TruffleBoundary
        protected void disposeThread(LanguageContext context, Thread thread) {
            tl.set(Boolean.FALSE);
        }

        @Override
        protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
            return true;
        }
    });
    forEachConfig((threads, events) -> {
        CountDownLatch awaitThreadStart = new CountDownLatch(1);
        AtomicBoolean threadsStopped = new AtomicBoolean();
        try (TestSetup setup = setupSafepointLoop(threads, new NodeCallable() {

            @TruffleBoundary
            public boolean call(@SuppressWarnings("hiding") TestSetup setup, TestRootNode node) {
                try {
                    List<Throwable> errors = Collections.synchronizedList(new ArrayList<>());
                    List<Thread> polyglotThreads = new ArrayList<>();
                    try {
                        for (int i = 0; i < threads; i++) {
                            Thread t = node.setup.env.createThread(() -> {
                                do {
                                    TruffleContext context = node.setup.env.getContext();
                                    TruffleSafepoint safepoint = TruffleSafepoint.getCurrent();
                                    boolean prevSideEffects = safepoint.setAllowSideEffects(false);
                                    try {
                                        context.leaveAndEnter(null, () -> {
                                            // cached thread local
                                            return null;
                                        });
                                    } finally {
                                        safepoint.setAllowSideEffects(prevSideEffects);
                                    }
                                } while (!threadsStopped.get());
                            });
                            t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {

                                public void uncaughtException(@SuppressWarnings("hiding") Thread t, Throwable e) {
                                    threadsStopped.set(true);
                                    e.printStackTrace();
                                    errors.add(e);
                                }
                            });
                            t.start();
                            polyglotThreads.add(t);
                        }
                    } finally {
                        awaitThreadStart.countDown();
                    }
                    for (Thread thread : polyglotThreads) {
                        thread.join();
                    }
                    for (Throwable t : errors) {
                        throw new AssertionError("thread threw error ", t);
                    }
                    return true;
                } catch (InterruptedException e1) {
                    throw new AssertionError(e1);
                }
            }
        })) {
            try {
                awaitThreadStart.await();
                // important to let leaving and submitting race against each other
                threadsStopped.set(true);
                List<Future<?>> futures = new ArrayList<>();
                for (int i = 0; i < events; i++) {
                    futures.add(setup.env.submitThreadLocal(null, new ThreadLocalAction(true, false) {

                        @Override
                        protected void perform(Access access) {
                            assertEquals(Boolean.TRUE, tl.get());
                        }
                    }));
                }
                for (Future<?> future : futures) {
                    try {
                        future.get();
                    } catch (ExecutionException e) {
                        throw new AssertionError(e);
                    }
                }
            } catch (InterruptedException e) {
                throw new AssertionError(e);
            }
            setup.stopAndAwait();
        }
    });
    ProxyLanguage.setDelegate(new ProxyLanguage());
}
Also used : ArrayList(java.util.ArrayList) LanguageContext(com.oracle.truffle.api.test.polyglot.ProxyLanguage.LanguageContext) ThreadLocalAction(com.oracle.truffle.api.ThreadLocalAction) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary) List(java.util.List) ArrayList(java.util.ArrayList) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) ExecutionException(java.util.concurrent.ExecutionException) TruffleSafepoint(com.oracle.truffle.api.TruffleSafepoint) TruffleContext(com.oracle.truffle.api.TruffleContext) CountDownLatch(java.util.concurrent.CountDownLatch) TruffleSafepoint(com.oracle.truffle.api.TruffleSafepoint) ProxyLanguage(com.oracle.truffle.api.test.polyglot.ProxyLanguage) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Future(java.util.concurrent.Future) AbstractPolyglotTest(com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest) Test(org.junit.Test)

Example 42 with ProxyLanguage

use of com.oracle.truffle.api.test.polyglot.ProxyLanguage in project graal by oracle.

the class TruffleContextTest method testNoInitializeMultiContextForInnerContext.

@Test
public void testNoInitializeMultiContextForInnerContext() {
    AtomicBoolean multiContextInitialized = new AtomicBoolean(false);
    setupEnv(Context.create(), new ProxyLanguage() {

        @Override
        protected CallTarget parse(ParsingRequest request) throws Exception {
            return RootNode.createConstantNode(42).getCallTarget();
        }

        @Override
        protected void initializeMultipleContexts() {
            multiContextInitialized.set(true);
        }

        @Override
        protected boolean areOptionsCompatible(OptionValues firstOptions, OptionValues newOptions) {
            return true;
        }
    });
    TruffleContext internalContext = languageEnv.newContextBuilder().initializeCreatorContext(false).build();
    internalContext.evalInternal(null, com.oracle.truffle.api.source.Source.newBuilder(ProxyLanguage.ID, "", "").build());
    assertFalse(multiContextInitialized.get());
    internalContext.close();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) OptionValues(org.graalvm.options.OptionValues) CallTarget(com.oracle.truffle.api.CallTarget) TruffleContext(com.oracle.truffle.api.TruffleContext) InteropException(com.oracle.truffle.api.interop.InteropException) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) AbstractTruffleException(com.oracle.truffle.api.exception.AbstractTruffleException) PolyglotException(org.graalvm.polyglot.PolyglotException) UnsupportedTypeException(com.oracle.truffle.api.interop.UnsupportedTypeException) ArityException(com.oracle.truffle.api.interop.ArityException) ExecutionException(java.util.concurrent.ExecutionException) ProxyLanguage(com.oracle.truffle.api.test.polyglot.ProxyLanguage) AbstractPolyglotTest(com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest) LanguageSPIOrderTest(com.oracle.truffle.api.test.polyglot.LanguageSPIOrderTest) Test(org.junit.Test)

Example 43 with ProxyLanguage

use of com.oracle.truffle.api.test.polyglot.ProxyLanguage in project graal by oracle.

the class TruffleContextTest method testExiting.

@Test
public void testExiting() throws ExecutionException, InterruptedException {
    setupEnv(Context.newBuilder(), new ProxyLanguage() {

        @Override
        protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
            return true;
        }
    });
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    try {
        AtomicReference<TruffleContext> entered = new AtomicReference<>();
        CountDownLatch waitUntilExited = new CountDownLatch(1);
        instrumentEnv.getInstrumenter().attachExecutionEventListener(SourceSectionFilter.newBuilder().tagIs(StandardTags.StatementTag.class).build(), new ExecutionEventListener() {

            @TruffleBoundary
            @Override
            public void onEnter(EventContext ctx, VirtualFrame frame) {
                entered.set(instrumentEnv.getEnteredContext());
            }

            @Override
            public void onReturnValue(EventContext ctx, VirtualFrame frame, Object result) {
            }

            @Override
            public void onReturnExceptional(EventContext ctx, VirtualFrame frame, Throwable exception) {
            }
        });
        Future<?> future = executorService.submit(() -> {
            context.enter();
            try {
                context.eval(InstrumentationTestLanguage.ID, "ROOT(STATEMENT,EXIT(1))");
                fail();
            } catch (PolyglotException pe) {
                if (!pe.isExit()) {
                    throw pe;
                }
                assertEquals(1, pe.getExitStatus());
                assertTrue(entered.get().isExiting());
            } finally {
                context.leave();
            }
            waitUntilExited.countDown();
        });
        boolean othrerThreadExited = false;
        while (!othrerThreadExited) {
            try {
                waitUntilExited.await();
                othrerThreadExited = true;
            } catch (InterruptedException ie) {
            }
        }
        /*
             * Multi-threading is necessary, otherwise the context is closed while entered and we
             * cannot check isExiting().
             */
        context.leave();
        TruffleContext tc = entered.get();
        tc.close();
        future.get();
        assertFalse(tc.isExiting());
        assertTrue(tc.isClosed());
    } finally {
        executorService.shutdownNow();
        executorService.awaitTermination(100, TimeUnit.SECONDS);
    }
}
Also used : TruffleContext(com.oracle.truffle.api.TruffleContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) PolyglotException(org.graalvm.polyglot.PolyglotException) StandardTags(com.oracle.truffle.api.instrumentation.StandardTags) ProxyLanguage(com.oracle.truffle.api.test.polyglot.ProxyLanguage) ExecutionEventListener(com.oracle.truffle.api.instrumentation.ExecutionEventListener) EventContext(com.oracle.truffle.api.instrumentation.EventContext) VirtualFrame(com.oracle.truffle.api.frame.VirtualFrame) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary) ExecutorService(java.util.concurrent.ExecutorService) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) AbstractPolyglotTest(com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest) LanguageSPIOrderTest(com.oracle.truffle.api.test.polyglot.LanguageSPIOrderTest) Test(org.junit.Test)

Example 44 with ProxyLanguage

use of com.oracle.truffle.api.test.polyglot.ProxyLanguage in project graal by oracle.

the class ThreadsActivationListenerTest method testMultiContext.

@Test
public void testMultiContext() {
    Engine engine = Engine.create();
    setupEnv(Context.newBuilder().engine(engine).build(), new ProxyLanguage() {

        @Override
        protected CallTarget parse(ParsingRequest request) throws Exception {
            return RootNode.createConstantNode(42).getCallTarget();
        }
    });
    Context c0 = this.context;
    TruffleContext tc0 = this.languageEnv.getContext();
    setupEnv(Context.newBuilder().engine(engine).build(), new ProxyLanguage() {

        @Override
        protected CallTarget parse(ParsingRequest request) throws Exception {
            return RootNode.createConstantNode(42).getCallTarget();
        }
    });
    Context c1 = this.context;
    TruffleContext tc1 = languageEnv.getContext();
    List<TruffleContext> entered = new ArrayList<>();
    List<TruffleContext> left = new ArrayList<>();
    EventBinding<?> binding = instrumentEnv.getInstrumenter().attachThreadsActivationListener(new ThreadsActivationListener() {

        @TruffleBoundary
        public void onEnterThread(TruffleContext c) {
            entered.add(c);
        }

        @TruffleBoundary
        public void onLeaveThread(TruffleContext c) {
            left.add(c);
        }
    });
    assertList(entered);
    assertList(left);
    c0.enter();
    assertList(entered, tc0);
    assertList(left);
    c1.enter();
    assertList(entered, tc0, tc1);
    assertList(left);
    c1.leave();
    assertList(entered, tc0, tc1);
    assertList(left, tc1);
    c0.leave();
    assertList(entered, tc0, tc1);
    assertList(left, tc1, tc0);
    binding.dispose();
    c0.enter();
    c1.enter();
    c1.leave();
    c0.leave();
    assertList(entered, tc0, tc1);
    assertList(left, tc1, tc0);
    c0.close();
    c1.close();
    engine.close();
}
Also used : TruffleContext(com.oracle.truffle.api.TruffleContext) LanguageContext(com.oracle.truffle.api.test.polyglot.ProxyLanguage.LanguageContext) Context(org.graalvm.polyglot.Context) CallTarget(com.oracle.truffle.api.CallTarget) TruffleContext(com.oracle.truffle.api.TruffleContext) ArrayList(java.util.ArrayList) PolyglotException(org.graalvm.polyglot.PolyglotException) ProxyLanguage(com.oracle.truffle.api.test.polyglot.ProxyLanguage) ThreadsActivationListener(com.oracle.truffle.api.instrumentation.ThreadsActivationListener) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary) Engine(org.graalvm.polyglot.Engine) Test(org.junit.Test) AbstractPolyglotTest(com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest)

Example 45 with ProxyLanguage

use of com.oracle.truffle.api.test.polyglot.ProxyLanguage in project graal by oracle.

the class ThreadsActivationListenerTest method testMultiThreading.

@Test
public void testMultiThreading() throws InterruptedException {
    setupEnv(Context.create(), new ProxyLanguage() {

        @Override
        protected CallTarget parse(ParsingRequest request) throws Exception {
            return RootNode.createConstantNode(42).getCallTarget();
        }

        @Override
        protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
            return true;
        }
    });
    List<TruffleContext> entered = new ArrayList<>();
    List<TruffleContext> left = new ArrayList<>();
    instrumentEnv.getInstrumenter().attachThreadsActivationListener(new ThreadsActivationListener() {

        @TruffleBoundary
        public void onEnterThread(TruffleContext c) {
            synchronized (entered) {
                entered.add(c);
            }
        }

        @TruffleBoundary
        public void onLeaveThread(TruffleContext c) {
            synchronized (left) {
                left.add(c);
            }
        }
    });
    assertList(entered);
    assertList(left);
    TruffleContext to = languageEnv.getContext();
    context.enter();
    assertList(entered, to);
    assertList(left);
    Thread t = new Thread(new Runnable() {

        public void run() {
            assertList(entered, to);
            assertList(left);
            context.enter();
            assertList(entered, to, to);
            assertList(left);
            context.leave();
            assertList(entered, to, to);
            assertList(left, to);
        }
    });
    t.start();
    t.join();
    context.leave();
    assertList(entered, to, to);
    assertList(left, to, to);
}
Also used : CallTarget(com.oracle.truffle.api.CallTarget) TruffleContext(com.oracle.truffle.api.TruffleContext) ArrayList(java.util.ArrayList) PolyglotException(org.graalvm.polyglot.PolyglotException) ProxyLanguage(com.oracle.truffle.api.test.polyglot.ProxyLanguage) ThreadsActivationListener(com.oracle.truffle.api.instrumentation.ThreadsActivationListener) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary) Test(org.junit.Test) AbstractPolyglotTest(com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest)

Aggregations

ProxyLanguage (com.oracle.truffle.api.test.polyglot.ProxyLanguage)64 Test (org.junit.Test)47 CallTarget (com.oracle.truffle.api.CallTarget)32 AbstractPolyglotTest (com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest)28 PolyglotException (org.graalvm.polyglot.PolyglotException)26 RootNode (com.oracle.truffle.api.nodes.RootNode)21 Source (org.graalvm.polyglot.Source)21 VirtualFrame (com.oracle.truffle.api.frame.VirtualFrame)20 UnsupportedMessageException (com.oracle.truffle.api.interop.UnsupportedMessageException)20 Context (org.graalvm.polyglot.Context)17 TruffleContext (com.oracle.truffle.api.TruffleContext)16 Before (org.junit.Before)16 TruffleLanguage (com.oracle.truffle.api.TruffleLanguage)14 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)13 CountDownLatch (java.util.concurrent.CountDownLatch)11 InteropLibrary (com.oracle.truffle.api.interop.InteropLibrary)10 ArrayList (java.util.ArrayList)10 ExecutionException (java.util.concurrent.ExecutionException)10 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)9 ExecutorService (java.util.concurrent.ExecutorService)9