Search in sources :

Example 36 with Env

use of com.oracle.truffle.api.TruffleLanguage.Env in project graal by oracle.

the class MultiThreadedLanguageTest method testAccessTruffleContextFromExclusivePolyglotThread.

@Test
public void testAccessTruffleContextFromExclusivePolyglotThread() throws Throwable {
    // don't allow multi-threading in this test as every context
    // is used exclusively by one thread.
    MultiThreadedLanguage.isThreadAccessAllowed = (req) -> {
        return req.singleThreaded;
    };
    final int iterations = 10;
    final int innerIterations = 10;
    AtomicReference<Throwable> lastError = new AtomicReference<>();
    UncaughtExceptionHandler uncaughtHandler = (run, e) -> lastError.set(e);
    Context polyglotContext = Context.newBuilder().allowCreateThread(true).build();
    ConcurrentHashMap<LanguageContext, String> seenContexts = new ConcurrentHashMap<>();
    eval(polyglotContext, new Function<Env, Object>() {

        @SuppressWarnings("hiding")
        public Object apply(Env env) {
            List<Thread> threads = new ArrayList<>();
            List<TruffleContext> contexts = new ArrayList<>();
            for (int i = 0; i < iterations; i++) {
                TruffleContext context = env.newContextBuilder().build();
                Thread thread = env.createThread(() -> {
                    assertUniqueContext();
                    List<Thread> innerThreads = new ArrayList<>();
                    List<TruffleContext> innerContexts = new ArrayList<>();
                    for (int j = 0; j < innerIterations; j++) {
                        TruffleContext innerContext = env.newContextBuilder().build();
                        Thread innerThread = env.createThread(() -> {
                            assertUniqueContext();
                        }, innerContext);
                        innerThread.setUncaughtExceptionHandler(uncaughtHandler);
                        innerThread.start();
                        innerThreads.add(innerThread);
                        innerContexts.add(innerContext);
                    }
                    for (Thread innerThread : innerThreads) {
                        try {
                            innerThread.join();
                        } catch (InterruptedException e) {
                        }
                    }
                    for (TruffleContext innerContext : innerContexts) {
                        innerContext.close();
                    }
                }, context);
                thread.setUncaughtExceptionHandler(uncaughtHandler);
                thread.start();
                threads.add(thread);
                contexts.add(context);
            }
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                }
            }
            for (TruffleContext context : contexts) {
                context.close();
            }
            return null;
        }

        private LanguageContext assertUniqueContext() {
            LanguageContext languageContext = MultiThreadedLanguage.getContext();
            Assert.assertNotNull(languageContext);
            Assert.assertFalse(seenContexts.containsKey(languageContext));
            seenContexts.put(languageContext, "");
            return languageContext;
        }
    });
    Assert.assertEquals(221, initializeCount.get());
    Assert.assertEquals(initializeCount.get() - 1, disposeCount.get());
    Assert.assertEquals(0, initializeMultiThreadingCount.get());
    // Test that the same context is available in threads when created with Env.getContext()
    MultiThreadedLanguage.isThreadAccessAllowed = (req) -> {
        return true;
    };
    eval(polyglotContext, new Function<Env, Object>() {

        @SuppressWarnings("hiding")
        public Object apply(Env env) {
            List<Thread> threads = new ArrayList<>();
            LanguageContext languageContext = MultiThreadedLanguage.getContext();
            for (int i = 0; i < iterations; i++) {
                Thread thread = env.createThread(() -> {
                    LanguageContext threadContext = MultiThreadedLanguage.getContext();
                    assertSame(languageContext, threadContext);
                    List<Thread> innerThreads = new ArrayList<>();
                    List<TruffleContext> innerContexts = new ArrayList<>();
                    for (int j = 0; j < innerIterations; j++) {
                        Thread innerThread = env.createThread(() -> {
                            LanguageContext innerThreadContext = MultiThreadedLanguage.getContext();
                            assertSame(languageContext, innerThreadContext);
                        }, env.getContext());
                        innerThread.setUncaughtExceptionHandler(uncaughtHandler);
                        innerThread.start();
                        innerThreads.add(innerThread);
                    }
                    for (Thread innerThread : innerThreads) {
                        try {
                            innerThread.join();
                        } catch (InterruptedException e) {
                        }
                    }
                    for (TruffleContext innerContext : innerContexts) {
                        innerContext.close();
                    }
                }, env.getContext());
                thread.setUncaughtExceptionHandler(uncaughtHandler);
                thread.start();
                threads.add(thread);
            }
            for (Thread thread : threads) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                }
            }
            return null;
        }
    });
    if (lastError.get() != null) {
        throw lastError.get();
    }
    polyglotContext.close();
    Assert.assertEquals(331, initializeCount.get());
    Assert.assertEquals(initializeCount.get(), disposeCount.get());
    Assert.assertEquals(1, initializeMultiThreadingCount.get());
}
Also used : ThreadRequest(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.ThreadRequest) UncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) PolyglotException(org.graalvm.polyglot.PolyglotException) Env(com.oracle.truffle.api.TruffleLanguage.Env) TimeoutException(java.util.concurrent.TimeoutException) 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) Assert.assertSame(org.junit.Assert.assertSame) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) After(org.junit.After) Assert.fail(org.junit.Assert.fail) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) Assert.assertNotNull(org.junit.Assert.assertNotNull) Semaphore(java.util.concurrent.Semaphore) Value(org.graalvm.polyglot.Value) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Assert.assertTrue(org.junit.Assert.assertTrue) Set(java.util.Set) Test(org.junit.Test) Executors(java.util.concurrent.Executors) TruffleContext(com.oracle.truffle.api.TruffleContext) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Assert.assertNull(org.junit.Assert.assertNull) Engine(org.graalvm.polyglot.Engine) Entry(java.util.Map.Entry) Context(org.graalvm.polyglot.Context) Assert(org.junit.Assert) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) TruffleContext(com.oracle.truffle.api.TruffleContext) Context(org.graalvm.polyglot.Context) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) TruffleContext(com.oracle.truffle.api.TruffleContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) Env(com.oracle.truffle.api.TruffleLanguage.Env) ArrayList(java.util.ArrayList) List(java.util.List) UncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.junit.Test)

Example 37 with Env

use of com.oracle.truffle.api.TruffleLanguage.Env in project graal by oracle.

the class MultiThreadedLanguageTest method testAccessTruffleContextPolyglotThread.

@Test
public void testAccessTruffleContextPolyglotThread() throws Throwable {
    MultiThreadedLanguage.isThreadAccessAllowed = (req) -> {
        return true;
    };
    Engine engine = Engine.create();
    AtomicReference<Throwable> seenError = new AtomicReference<>();
    Context context = Context.newBuilder().allowCreateThread(true).engine(engine).build();
    eval(context, new Function<Env, Object>() {

        public Object apply(Env env) {
            List<Thread> createdThreads = new ArrayList<>();
            ExecutorService service = Executors.newFixedThreadPool(10, (r) -> {
                Thread t = env.createThread(r);
                t.setUncaughtExceptionHandler((thread, e) -> seenError.set(e));
                createdThreads.add(t);
                return t;
            });
            TruffleContext innerContext = env.newContextBuilder().build();
            List<Future<LanguageContext>> futures = new ArrayList<>();
            List<Future<LanguageContext>> innerContextFutures = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                innerContextFutures.add(service.submit(() -> {
                    Object prev = innerContext.enter();
                    try {
                        return MultiThreadedLanguage.getContext();
                    } finally {
                        innerContext.leave(prev);
                    }
                }));
            }
            for (int i = 0; i < 100; i++) {
                futures.add(service.submit(() -> {
                    return MultiThreadedLanguage.getContext();
                }));
            }
            try {
                for (Future<LanguageContext> future : futures) {
                    assertSame(MultiThreadedLanguage.getContext(), future.get());
                }
                LanguageContext innerLanguageContext;
                Object prev = innerContext.enter();
                innerLanguageContext = MultiThreadedLanguage.getContext();
                innerContext.leave(prev);
                for (Future<LanguageContext> future : innerContextFutures) {
                    assertSame(innerLanguageContext, future.get());
                }
                innerContext.close();
            } catch (InterruptedException e1) {
                throw new AssertionError(e1);
            } catch (ExecutionException e1) {
                throw new AssertionError(e1);
            }
            service.shutdown();
            /*
                 * We need to join all threads as unfortunately the executor service does not
                 * guarantee that all threads are immediately shutdown.
                 */
            try {
                for (Thread t : createdThreads) {
                    t.join(1000);
                }
            } catch (InterruptedException e1) {
                throw new AssertionError(e1);
            }
            return MultiThreadedLanguage.getContext();
        }
    });
    if (seenError.get() != null) {
        throw seenError.get();
    }
    engine.close();
}
Also used : TruffleContext(com.oracle.truffle.api.TruffleContext) Context(org.graalvm.polyglot.Context) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) ThreadRequest(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.ThreadRequest) UncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) PolyglotException(org.graalvm.polyglot.PolyglotException) Env(com.oracle.truffle.api.TruffleLanguage.Env) TimeoutException(java.util.concurrent.TimeoutException) 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) Assert.assertSame(org.junit.Assert.assertSame) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) After(org.junit.After) Assert.fail(org.junit.Assert.fail) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) Assert.assertNotNull(org.junit.Assert.assertNotNull) Semaphore(java.util.concurrent.Semaphore) Value(org.graalvm.polyglot.Value) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Assert.assertTrue(org.junit.Assert.assertTrue) Set(java.util.Set) Test(org.junit.Test) Executors(java.util.concurrent.Executors) TruffleContext(com.oracle.truffle.api.TruffleContext) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Assert.assertNull(org.junit.Assert.assertNull) Engine(org.graalvm.polyglot.Engine) Entry(java.util.Map.Entry) Context(org.graalvm.polyglot.Context) Assert(org.junit.Assert) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) TruffleContext(com.oracle.truffle.api.TruffleContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) Env(com.oracle.truffle.api.TruffleLanguage.Env) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) ArrayList(java.util.ArrayList) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) Engine(org.graalvm.polyglot.Engine) Test(org.junit.Test)

Example 38 with Env

use of com.oracle.truffle.api.TruffleLanguage.Env in project graal by oracle.

the class MultiThreadedLanguageTest method testMultiThreading.

@Test
public void testMultiThreading() throws InterruptedException, ExecutionException {
    AtomicReference<ThreadRequest> lastIsAllowedRequest = new AtomicReference<>(null);
    MultiThreadedLanguage.isThreadAccessAllowed = (req) -> {
        lastIsAllowedRequest.set(req);
        return true;
    };
    final int threadCount = 10;
    final int outerLoop = 10;
    final int innerLoop = 100;
    ExecutorService executor = createExecutor(threadCount);
    for (int outerIter = 0; outerIter < outerLoop; outerIter++) {
        resetData();
        Context context = Context.create(MultiThreadedLanguage.ID);
        assertEquals(0, initializeCount.get());
        assertNull(lastInitializeRequest.get());
        List<Completable<Value>> results = new ArrayList<>();
        for (int iteration = 0; iteration < innerLoop; iteration++) {
            CountDownLatch latch = iteration == 0 ? new CountDownLatch(threadCount) : null;
            Value value = eval(context, (env) -> new Object());
            for (int i = 0; i < threadCount; i++) {
                results.add(evalAndWait(executor, context, iteration == 0, latch, (ev) -> MultiThreadedLanguage.getContext()));
            }
            assertUnsupportedOrNoError(value, Value::execute);
            assertUnsupportedOrNoError(value, Value::isBoolean);
            assertUnsupportedOrNoError(value, Value::isHostObject);
            assertUnsupportedOrNoError(value, Value::isNativePointer);
            assertUnsupportedOrNoError(value, Value::isNull);
            assertUnsupportedOrNoError(value, Value::isNumber);
            assertUnsupportedOrNoError(value, Value::isString);
            assertUnsupportedOrNoError(value, Value::fitsInByte);
            assertUnsupportedOrNoError(value, Value::fitsInDouble);
            assertUnsupportedOrNoError(value, Value::fitsInFloat);
            assertUnsupportedOrNoError(value, Value::fitsInInt);
            assertUnsupportedOrNoError(value, Value::fitsInLong);
            assertUnsupportedOrNoError(value, Value::asBoolean);
            assertUnsupportedOrNoError(value, Value::asByte);
            assertUnsupportedOrNoError(value, Value::asDouble);
            assertUnsupportedOrNoError(value, Value::asFloat);
            assertUnsupportedOrNoError(value, Value::asHostObject);
            assertUnsupportedOrNoError(value, Value::asInt);
            assertUnsupportedOrNoError(value, Value::asLong);
            assertUnsupportedOrNoError(value, Value::asNativePointer);
            assertUnsupportedOrNoError(value, Value::asString);
            assertUnsupportedOrNoError(value, Value::getArraySize);
            assertUnsupportedOrNoError(value, Value::getMemberKeys);
            assertUnsupportedOrNoError(value, Value::getMetaObject);
            assertUnsupportedOrNoError(value, (v) -> v.getMember(""));
            assertUnsupportedOrNoError(value, (v) -> v.putMember("", null));
            assertUnsupportedOrNoError(value, (v) -> v.hasMember(""));
            assertUnsupportedOrNoError(value, (v) -> v.canExecute());
            assertUnsupportedOrNoError(value, (v) -> v.getArraySize());
            assertUnsupportedOrNoError(value, (v) -> v.getArrayElement(0));
            assertUnsupportedOrNoError(value, (v) -> v.setArrayElement(0, null));
            // we need to wait for them once to ensure every thread is initialized
            if (iteration == 0) {
                latch.await();
                for (Completable<Value> future : results) {
                    future.complete();
                }
            }
        }
        for (Completable<Value> future : results) {
            Object languageContext = future.get().asHostObject();
            assertSame(MultiThreadedLanguage.langContext, languageContext);
        }
        assertEquals(threadCount + 1, initializeCount.get());
        assertEquals(1, initializeMultiThreadingCount.get());
        assertEquals(false, lastIsAllowedRequest.get().singleThreaded);
        context.close();
        // main thread gets initialized after close as well
        assertEquals(false, lastIsAllowedRequest.get().singleThreaded);
        assertEquals(1, initializeMultiThreadingCount.get());
        assertEquals(threadCount + 1, initializeCount.get());
        assertEquals(threadCount + 1, disposeCount.get());
    }
    assertTrue(executor.shutdownNow().isEmpty());
}
Also used : ThreadRequest(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.ThreadRequest) TruffleContext(com.oracle.truffle.api.TruffleContext) Context(org.graalvm.polyglot.Context) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) ThreadRequest(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.ThreadRequest) UncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) PolyglotException(org.graalvm.polyglot.PolyglotException) Env(com.oracle.truffle.api.TruffleLanguage.Env) TimeoutException(java.util.concurrent.TimeoutException) 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) Assert.assertSame(org.junit.Assert.assertSame) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) After(org.junit.After) Assert.fail(org.junit.Assert.fail) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) Assert.assertNotNull(org.junit.Assert.assertNotNull) Semaphore(java.util.concurrent.Semaphore) Value(org.graalvm.polyglot.Value) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Assert.assertTrue(org.junit.Assert.assertTrue) Set(java.util.Set) Test(org.junit.Test) Executors(java.util.concurrent.Executors) TruffleContext(com.oracle.truffle.api.TruffleContext) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Assert.assertNull(org.junit.Assert.assertNull) Engine(org.graalvm.polyglot.Engine) Entry(java.util.Map.Entry) Context(org.graalvm.polyglot.Context) Assert(org.junit.Assert) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) LanguageContext(com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext) ArrayList(java.util.ArrayList) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ExecutorService(java.util.concurrent.ExecutorService) Value(org.graalvm.polyglot.Value) Test(org.junit.Test)

Example 39 with Env

use of com.oracle.truffle.api.TruffleLanguage.Env in project graal by oracle.

the class LanguageSPITest method testParseOtherLanguage.

@Test
public void testParseOtherLanguage() {
    Context context = Context.newBuilder().build();
    eval(context, new Function<Env, Object>() {

        public Object apply(Env t) {
            assertCorrectTarget(t.parse(Source.newBuilder("").language(ContextAPITestLanguage.ID).name("").build()));
            assertCorrectTarget(t.parse(Source.newBuilder("").mimeType(ContextAPITestLanguage.MIME).name("").build()));
            // this is here for compatibility because mime types and language ids were allowed
            // in between.
            assertCorrectTarget(t.parse(Source.newBuilder("").mimeType(ContextAPITestLanguage.ID).name("").build()));
            return null;
        }

        private void assertCorrectTarget(CallTarget target) {
            Assert.assertEquals(ContextAPITestLanguage.ID, ((RootCallTarget) target).getRootNode().getLanguageInfo().getId());
        }
    });
    context.close();
}
Also used : Context(org.graalvm.polyglot.Context) LanguageContext(com.oracle.truffle.api.test.polyglot.LanguageSPITestLanguage.LanguageContext) TruffleContext(com.oracle.truffle.api.TruffleContext) CallTarget(com.oracle.truffle.api.CallTarget) RootCallTarget(com.oracle.truffle.api.RootCallTarget) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) Env(com.oracle.truffle.api.TruffleLanguage.Env) RootCallTarget(com.oracle.truffle.api.RootCallTarget) Test(org.junit.Test)

Example 40 with Env

use of com.oracle.truffle.api.TruffleLanguage.Env in project graal by oracle.

the class LanguageSPITest method testContextCloseInsideFromSameThread.

@Test
public void testContextCloseInsideFromSameThread() {
    langContext = null;
    Context context = Context.newBuilder(LanguageSPITestLanguage.ID).build();
    eval(context, new Function<Env, Object>() {

        public Object apply(Env t) {
            context.close();
            return null;
        }
    });
    context.close();
    assertEquals(1, langContext.disposeCalled);
}
Also used : Context(org.graalvm.polyglot.Context) LanguageContext(com.oracle.truffle.api.test.polyglot.LanguageSPITestLanguage.LanguageContext) TruffleContext(com.oracle.truffle.api.TruffleContext) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) Env(com.oracle.truffle.api.TruffleLanguage.Env) Test(org.junit.Test)

Aggregations

Env (com.oracle.truffle.api.TruffleLanguage.Env)48 Context (org.graalvm.polyglot.Context)41 Test (org.junit.Test)41 TruffleContext (com.oracle.truffle.api.TruffleContext)21 TruffleFile (com.oracle.truffle.api.TruffleFile)20 Path (java.nio.file.Path)19 LanguageContext (com.oracle.truffle.api.test.polyglot.LanguageSPITestLanguage.LanguageContext)16 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)13 IOException (java.io.IOException)12 Function (java.util.function.Function)10 Engine (org.graalvm.polyglot.Engine)10 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)7 PolyglotException (org.graalvm.polyglot.PolyglotException)7 Value (org.graalvm.polyglot.Value)6 LanguageContext (com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext)5 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ExecutionException (java.util.concurrent.ExecutionException)4 ExecutorService (java.util.concurrent.ExecutorService)4