Search in sources :

Example 16 with ThreadLocalAction

use of com.oracle.truffle.api.ThreadLocalAction in project graal by oracle.

the class TruffleSafepointTest method testHasPendingSideEffectingActions.

@Test
public void testHasPendingSideEffectingActions() {
    AtomicReference<Thread> thread = new AtomicReference<>();
    CountDownLatch waitSideEffectsDisabled = new CountDownLatch(1);
    CountDownLatch waitSubmitted = new CountDownLatch(1);
    try (TestSetup setup = setupSafepointLoop(1, (s, node) -> {
        testHasPendingSideEffectingActionsBoundary(thread, waitSideEffectsDisabled, waitSubmitted, node);
        return true;
    })) {
        waitSideEffectsDisabled.await();
        setup.env.submitThreadLocal(new Thread[] { thread.get() }, new ThreadLocalAction(true, false) {

            @Override
            protected void perform(Access access) {
                throw new RuntimeException("interrupt");
            }
        });
        waitSubmitted.countDown();
        setup.stopAndAwait();
    } catch (InterruptedException e) {
        throw new AssertionError(e);
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ThreadLocalAction(com.oracle.truffle.api.ThreadLocalAction) AbstractPolyglotTest(com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest) Test(org.junit.Test)

Example 17 with ThreadLocalAction

use of com.oracle.truffle.api.ThreadLocalAction 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 18 with ThreadLocalAction

use of com.oracle.truffle.api.ThreadLocalAction in project graal by oracle.

the class PolyglotThreadLocalActions method notifyThreadActivation.

Set<ThreadLocalAction> notifyThreadActivation(PolyglotThreadInfo info, boolean active) {
    assert !active || info.getEnteredCount() == 1 : "must be currently entered successfully";
    assert Thread.holdsLock(context);
    if (activeEvents.isEmpty()) {
        // fast common path
        return Collections.emptySet();
    }
    Set<ThreadLocalAction> updatedActions = new HashSet<>();
    // we cannot process the events while the context lock is held
    // so we need to collect them first.
    TruffleSafepoint s = TruffleSafepoint.getCurrent();
    /*
         * The set can be modified during the subsequent iteration.
         */
    ArrayList<AbstractTLHandshake> activeEventsList = new ArrayList<>(activeEvents.keySet());
    for (AbstractTLHandshake handshake : activeEventsList) {
        if (!handshake.isEnabledForThread(Thread.currentThread())) {
            continue;
        }
        Future<?> f = handshake.future;
        if (f instanceof RecurringFuture) {
            f = ((RecurringFuture) f).getCurrentFuture();
            assert f != null : "current future must never be null";
        }
        if (active) {
            if (traceActions) {
                log("activate", handshake, "");
            }
            if (f == COMPLETED_FUTURE) {
                assert handshake.future instanceof RecurringFuture;
                handshake.resubmitRecurring();
            } else {
                if (TL_HANDSHAKE.activateThread(s, f)) {
                    updatedActions.add(handshake.action);
                }
            }
        } else {
            if (traceActions) {
                log("deactivate", handshake, "");
            }
            if (f == COMPLETED_FUTURE) {
                assert handshake.future instanceof RecurringFuture;
            // nothing to do, wait for reactivation
            } else {
                if (TL_HANDSHAKE.deactivateThread(s, f)) {
                    updatedActions.add(handshake.action);
                }
            }
        }
    }
    return updatedActions;
}
Also used : TruffleSafepoint(com.oracle.truffle.api.TruffleSafepoint) ArrayList(java.util.ArrayList) ThreadLocalAction(com.oracle.truffle.api.ThreadLocalAction) HashSet(java.util.HashSet)

Example 19 with ThreadLocalAction

use of com.oracle.truffle.api.ThreadLocalAction in project graal by oracle.

the class ContextPreInitializationTest method testThreadLocalActions.

@Test
public void testThreadLocalActions() throws Exception {
    BaseLanguage.registerAction(ContextPreInitializationTestFirstLanguage.class, ActionKind.ON_EXECUTE, (env) -> {
        env.submitThreadLocal(new Thread[] { Thread.currentThread() }, new ThreadLocalAction(false, false) {

            @Override
            protected void perform(Access access) {
            // Empty action just to do TraceStackTraceInterval logging
            }
        });
    });
    setPatchable(FIRST);
    doContextPreinitialize(FIRST);
    List<CountingContext> contexts = new ArrayList<>(emittedContexts);
    assertEquals(1, contexts.size());
    CountingContext firstLangCtx = findContext(FIRST, contexts);
    assertNotNull(firstLangCtx);
    assertEquals(1, firstLangCtx.createContextCount);
    assertEquals(1, firstLangCtx.initializeContextCount);
    TestHandler handler = new TestHandler("engine");
    try (Context ctx = Context.newBuilder().allowExperimentalOptions(true).logHandler(handler).option("engine.TraceThreadLocalActions", "true").build()) {
        Value res = ctx.eval(Source.create(FIRST, "test"));
        assertEquals("test", res.asString());
        contexts = new ArrayList<>(emittedContexts);
        assertEquals(1, contexts.size());
        assertEquals(1, firstLangCtx.createContextCount);
        assertEquals(1, firstLangCtx.initializeContextCount);
        assertEquals(1, firstLangCtx.patchContextCount);
    }
    Optional<String> message = handler.logs.stream().map((r) -> r.getMessage()).filter((m) -> m.contains("[tl]")).findAny();
    assertTrue(message.isPresent());
}
Also used : Context(org.graalvm.polyglot.Context) TruffleContext(com.oracle.truffle.api.TruffleContext) Arrays(java.util.Arrays) OptionKey(org.graalvm.options.OptionKey) Assert.assertNotSame(org.junit.Assert.assertNotSame) ContextsListener(com.oracle.truffle.api.instrumentation.ContextsListener) Env(com.oracle.truffle.api.TruffleLanguage.Env) TruffleLogger(com.oracle.truffle.api.TruffleLogger) OptionValues(org.graalvm.options.OptionValues) DirectoryStream(java.nio.file.DirectoryStream) OptionCategory(org.graalvm.options.OptionCategory) CompilerDirectives(com.oracle.truffle.api.CompilerDirectives) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) After(org.junit.After) RootNode(com.oracle.truffle.api.nodes.RootNode) Method(java.lang.reflect.Method) Path(java.nio.file.Path) TruffleFile(com.oracle.truffle.api.TruffleFile) Value(org.graalvm.polyglot.Value) Collection(java.util.Collection) StandardOpenOption(java.nio.file.StandardOpenOption) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) VirtualFrame(com.oracle.truffle.api.frame.VirtualFrame) CallTarget(com.oracle.truffle.api.CallTarget) ContextThreadLocal(com.oracle.truffle.api.ContextThreadLocal) LogRecord(java.util.logging.LogRecord) Collectors(java.util.stream.Collectors) InstrumentInfo(com.oracle.truffle.api.InstrumentInfo) ZoneId(java.time.ZoneId) Objects(java.util.Objects) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Assert.assertFalse(org.junit.Assert.assertFalse) AbstractPolyglotImpl(org.graalvm.polyglot.impl.AbstractPolyglotImpl) TestAPIAccessor(com.oracle.truffle.api.test.TestAPIAccessor) ThreadLocalAction(com.oracle.truffle.api.ThreadLocalAction) Optional(java.util.Optional) ThreadsActivationListener(com.oracle.truffle.api.instrumentation.ThreadsActivationListener) Context(org.graalvm.polyglot.Context) Handler(java.util.logging.Handler) OptionStability(org.graalvm.options.OptionStability) ContextLocal(com.oracle.truffle.api.ContextLocal) ByteArrayOutputStream(java.io.ByteArrayOutputStream) BeforeClass(org.junit.BeforeClass) PolyglotException(org.graalvm.polyglot.PolyglotException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) Assert.assertSame(org.junit.Assert.assertSame) HashSet(java.util.HashSet) Pair(org.graalvm.collections.Pair) EventBinding(com.oracle.truffle.api.instrumentation.EventBinding) Source(org.graalvm.polyglot.Source) OptionDescriptor(org.graalvm.options.OptionDescriptor) ThreadsListener(com.oracle.truffle.api.instrumentation.ThreadsListener) LinkedHashSet(java.util.LinkedHashSet) TruffleTestAssumptions(com.oracle.truffle.tck.tests.TruffleTestAssumptions) Before(org.junit.Before) OutputStream(java.io.OutputStream) PrintStream(java.io.PrintStream) Files(java.nio.file.Files) TruffleInstrument(com.oracle.truffle.api.instrumentation.TruffleInstrument) Assert.assertNotNull(org.junit.Assert.assertNotNull) Assert.assertTrue(org.junit.Assert.assertTrue) IOException(java.io.IOException) Test(org.junit.Test) OptionDescriptors(org.graalvm.options.OptionDescriptors) TruffleContext(com.oracle.truffle.api.TruffleContext) Consumer(java.util.function.Consumer) FileSystem(org.graalvm.polyglot.io.FileSystem) Paths(java.nio.file.Paths) PolyglotAccess(org.graalvm.polyglot.PolyglotAccess) Engine(org.graalvm.polyglot.Engine) Assert(org.junit.Assert) TruffleLanguage(com.oracle.truffle.api.TruffleLanguage) LanguageInfo(com.oracle.truffle.api.nodes.LanguageInfo) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) Option(com.oracle.truffle.api.Option) PolyglotAccess(org.graalvm.polyglot.PolyglotAccess) ArrayList(java.util.ArrayList) ThreadLocalAction(com.oracle.truffle.api.ThreadLocalAction) Value(org.graalvm.polyglot.Value) Test(org.junit.Test)

Aggregations

ThreadLocalAction (com.oracle.truffle.api.ThreadLocalAction)19 Test (org.junit.Test)14 AbstractPolyglotTest (com.oracle.truffle.api.test.polyglot.AbstractPolyglotTest)13 TruffleSafepoint (com.oracle.truffle.api.TruffleSafepoint)12 ArrayList (java.util.ArrayList)9 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)9 Future (java.util.concurrent.Future)7 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 CountDownLatch (java.util.concurrent.CountDownLatch)5 TruffleContext (com.oracle.truffle.api.TruffleContext)4 List (java.util.List)4 Semaphore (java.util.concurrent.Semaphore)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)4 Env (com.oracle.truffle.api.TruffleLanguage.Env)3 LanguageContext (com.oracle.truffle.api.test.polyglot.ProxyLanguage.LanguageContext)3 ExecutionException (java.util.concurrent.ExecutionException)3 TruffleBoundary (com.oracle.truffle.api.CompilerDirectives.TruffleBoundary)2 ProxyLanguage (com.oracle.truffle.api.test.polyglot.ProxyLanguage)2 HashSet (java.util.HashSet)2 Context (org.graalvm.polyglot.Context)2