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());
}
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());
}
Aggregations