Skip to content
Snippets Groups Projects
Commit b14f9cc2 authored by Stepan Sindelar's avatar Stepan Sindelar
Browse files

[GR-6629] NFI Context can deal with being accessed from multiple threads.

PullRequest: fastr/1258
parents 1b08727c 89af22dd
No related branches found
No related tags found
No related merge requests found
......@@ -186,13 +186,14 @@ final class TruffleNFI_Context extends RFFIContext {
}
}
private void initCallbacksAddress() {
@TruffleBoundary
private long initCallbacksAddress() {
// get the address of the native thread local
try {
Node bind = Message.createInvoke(1).createNode();
Node executeNode = Message.createExecute(1).createNode();
TruffleObject getCallbacksAddressFunction = (TruffleObject) ForeignAccess.sendInvoke(bind, DLL.findSymbol("Rinternals_getCallbacksAddress", null).asTruffleObject(), "bind", "(): sint64");
callbacksAddress = (long) ForeignAccess.sendExecute(executeNode, getCallbacksAddressFunction);
return (long) ForeignAccess.sendExecute(executeNode, getCallbacksAddressFunction);
} catch (InteropException ex) {
throw RInternalError.shouldNotReachHere(ex);
}
......@@ -222,22 +223,47 @@ final class TruffleNFI_Context extends RFFIContext {
}
private long callbacks;
@CompilationFinal private boolean singleThreadOnly = true;
@CompilationFinal private long callbacksAddressThread;
@CompilationFinal private long callbacksAddress;
private long lastCallbacksAddressThread;
private long lastCallbacksAddress;
private long pushCallbacks() {
if (callbacksAddress == 0) {
CompilerDirectives.transferToInterpreterAndInvalidate();
initCallbacksAddress();
callbacksAddress = initCallbacksAddress();
callbacksAddressThread = Thread.currentThread().getId();
}
long oldCallbacks = UnsafeAdapter.UNSAFE.getLong(callbacksAddress);
assert callbacks != 0L;
assert callbacksAddress != 0L;
UnsafeAdapter.UNSAFE.putLong(callbacksAddress, callbacks);
if (singleThreadOnly && callbacksAddressThread == Thread.currentThread().getId()) {
// Fast path for contexts used only from a single thread
long oldCallbacks = UnsafeAdapter.UNSAFE.getLong(callbacksAddress);
assert callbacksAddress != 0L;
UnsafeAdapter.UNSAFE.putLong(callbacksAddress, callbacks);
return oldCallbacks;
}
// Slow path: cache the address, but reinitialize it if the thread has changed, without
// transfer to interpreter this time.
boolean reinitialize = singleThreadOnly || lastCallbacksAddressThread != Thread.currentThread().getId();
if (singleThreadOnly) {
CompilerDirectives.transferToInterpreterAndInvalidate();
singleThreadOnly = false;
}
if (reinitialize) {
lastCallbacksAddress = initCallbacksAddress();
lastCallbacksAddressThread = Thread.currentThread().getId();
}
long oldCallbacks = UnsafeAdapter.UNSAFE.getLong(lastCallbacksAddress);
assert lastCallbacksAddress != 0L;
assert lastCallbacksAddressThread == Thread.currentThread().getId();
UnsafeAdapter.UNSAFE.putLong(lastCallbacksAddress, callbacks);
return oldCallbacks;
}
private void popCallbacks(long beforeValue) {
assert UnsafeAdapter.UNSAFE.getLong(callbacksAddress) == callbacks : "invalid nesting of native calling contexts";
assert !singleThreadOnly || UnsafeAdapter.UNSAFE.getLong(callbacksAddress) == callbacks : "invalid nesting of native calling contexts";
assert singleThreadOnly || UnsafeAdapter.UNSAFE.getLong(lastCallbacksAddress) == callbacks : "invalid nesting of native calling contexts";
UnsafeAdapter.UNSAFE.putLong(callbacksAddress, beforeValue);
}
......
......@@ -30,11 +30,4 @@ import com.oracle.truffle.r.runtime.data.RFunction;
public abstract class TruffleRLanguage extends TruffleLanguage<RContext> {
public abstract HashMap<String, RFunction> getBuiltinFunctionCache();
@Override
protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
// FastR does not support access to a single context from multiple threads, mainly because
// it has to maintain thread local variables on the native side.
return Thread.currentThread() == thread;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment