Search in sources :

Example 1 with ThreadRequest

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

the class MultiThreadedLanguageTest method testSingleThreading.

@Test
public void testSingleThreading() throws InterruptedException, ExecutionException {
    Context context = Context.create(MultiThreadedLanguage.ID);
    AtomicReference<ThreadRequest> lastIsAllowedRequest = new AtomicReference<>(null);
    MultiThreadedLanguage.isThreadAccessAllowed = (req) -> {
        lastIsAllowedRequest.set(req);
        return req.singleThreaded;
    };
    ExecutorService executor = createExecutor(1);
    assertEquals(0, initializeCount.get());
    assertNull(lastInitializeRequest.get());
    Value value = eval(context, (env) -> new Object());
    assertEquals(1, initializeCount.get());
    assertEquals(true, lastIsAllowedRequest.get().singleThreaded);
    assertSame(Thread.currentThread(), lastInitializeRequest.get().thread);
    assertSame(Thread.currentThread(), lastIsAllowedRequest.get().thread);
    CountDownLatch latch = new CountDownLatch(1);
    Completable<Value> future = evalAndWait(executor, context, true, latch, (ev) -> MultiThreadedLanguage.getContext());
    latch.await();
    assertEquals(2, initializeCount.get());
    assertEquals(true, lastIsAllowedRequest.get().singleThreaded);
    assertSame(threads.iterator().next(), lastInitializeRequest.get().thread);
    assertSame(threads.iterator().next(), lastIsAllowedRequest.get().thread);
    assertEquals(0, disposeCount.get());
    assertNull(lastDisposeRequest.get());
    try {
        eval(context, (env) -> null);
        fail();
    } catch (IllegalStateException e) {
        assertTrue(e.getMessage(), e.getMessage().contains("Multi threaded access requested by thread "));
    }
    assertMultiThreadedError(value, Value::execute);
    assertMultiThreadedError(value, Value::isBoolean);
    // assertMultiThreadedError(value, Value::isHostObject);
    assertMultiThreadedError(value, Value::isNativePointer);
    assertMultiThreadedError(value, Value::isNull);
    assertMultiThreadedError(value, Value::isNumber);
    assertMultiThreadedError(value, Value::isString);
    assertMultiThreadedError(value, Value::fitsInByte);
    assertMultiThreadedError(value, Value::fitsInDouble);
    assertMultiThreadedError(value, Value::fitsInFloat);
    assertMultiThreadedError(value, Value::fitsInInt);
    assertMultiThreadedError(value, Value::fitsInLong);
    assertMultiThreadedError(value, Value::asBoolean);
    assertMultiThreadedError(value, Value::asByte);
    assertMultiThreadedError(value, Value::asDouble);
    assertMultiThreadedError(value, Value::asFloat);
    // assertMultiThreadedError(value, Value::asHostObject);
    assertMultiThreadedError(value, Value::asInt);
    assertMultiThreadedError(value, Value::asLong);
    assertMultiThreadedError(value, Value::asNativePointer);
    assertMultiThreadedError(value, Value::asString);
    assertMultiThreadedError(value, Value::getArraySize);
    assertMultiThreadedError(value, Value::getMemberKeys);
    assertMultiThreadedError(value, Value::getMetaObject);
    assertMultiThreadedError(value, (v) -> v.getMember(""));
    assertMultiThreadedError(value, (v) -> v.putMember("", null));
    assertMultiThreadedError(value, (v) -> v.hasMember(""));
    assertMultiThreadedError(value, (v) -> v.canExecute());
    assertMultiThreadedError(value, (v) -> v.getArraySize());
    assertMultiThreadedError(value, (v) -> v.getArrayElement(0));
    assertMultiThreadedError(value, (v) -> v.setArrayElement(0, null));
    assertEquals(2, initializeCount.get());
    assertSame(Thread.currentThread(), lastIsAllowedRequest.get().thread);
    assertEquals(false, lastIsAllowedRequest.get().singleThreaded);
    assertEquals(0, disposeCount.get());
    assertNull(lastDisposeRequest.get());
    // cannot close still running
    try {
        context.close();
        fail();
    } catch (IllegalStateException e) {
        assertTrue(e.getMessage(), e.getMessage().contains("The context is currently executing on another thread. Set cancelIfExecuting to true to stop the execution on this thread."));
    }
    assertSame(Thread.currentThread(), lastIsAllowedRequest.get().thread);
    assertEquals(false, lastIsAllowedRequest.get().singleThreaded);
    future.complete();
    assertNotNull(future.get());
    // closing the context must call dispose for the one thread
    // that returned true on initialize.
    context.close();
    assertEquals(2, initializeCount.get());
    assertEquals(2, disposeCount.get());
    assertTrue(lastDisposeRequest.get().thread == Thread.currentThread() || lastDisposeRequest.get().thread == threads.iterator().next());
    // cleanup executor
    assertTrue(executor.shutdownNow().isEmpty());
}
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) ExecutorService(java.util.concurrent.ExecutorService) Value(org.graalvm.polyglot.Value) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 2 with ThreadRequest

use of com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.ThreadRequest 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)

Aggregations

TruffleContext (com.oracle.truffle.api.TruffleContext)2 LanguageContext (com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.LanguageContext)2 ThreadRequest (com.oracle.truffle.api.test.polyglot.MultiThreadedLanguage.ThreadRequest)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 ExecutorService (java.util.concurrent.ExecutorService)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 Context (org.graalvm.polyglot.Context)2 Value (org.graalvm.polyglot.Value)2 Test (org.junit.Test)2 Env (com.oracle.truffle.api.TruffleLanguage.Env)1 UncaughtExceptionHandler (java.lang.Thread.UncaughtExceptionHandler)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Entry (java.util.Map.Entry)1 Set (java.util.Set)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1