Skip to content

Commit

Permalink
Resolving conflicts in PolyglotContextImpl.java
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaroslav Tulach committed Sep 25, 2024
1 parent f7c4e7d commit a810ee8
Showing 1 changed file with 120 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,8 @@ Object[] enterThreadChanged(boolean enterReverted, boolean pollSafepoint, boolea
Object[] prev = null;
Thread current = Thread.currentThread();
try {
for (;;) {
try {
boolean deactivateSafepoints = mustSucceed;
boolean localPollSafepoint = pollSafepoint && !mustSucceed;
try {
Expand All @@ -840,7 +842,7 @@ Object[] enterThreadChanged(boolean enterReverted, boolean pollSafepoint, boolea
synchronized (this) {
PolyglotThreadInfo threadInfo = getCurrentThreadInfo();

if (enterReverted && threadInfo.getEnteredCount() == 0) {
if (enterReverted && threadInfo.getEnteredCount() == 0) {
threadLocalActions.notifyThreadActivation(threadInfo, false);
if ((state.isCancelling() || state.isExiting() || state == State.CLOSED_CANCELLED || state == State.CLOSED_EXITED) && !threadInfo.isActive()) {
notifyThreadClosed(threadInfo);
Expand All @@ -851,136 +853,142 @@ Object[] enterThreadChanged(boolean enterReverted, boolean pollSafepoint, boolea
threadInfo.interruptSent = false;
}
notifyAll();
}
}
if (deactivateSafepoints && threadInfo != PolyglotThreadInfo.NULL) {
threadLocalActions.notifyThreadActivation(threadInfo, false);
}

assert threadInfo != null;
if (!leaveAndEnter) {
checkClosedOrDisposing(mustSucceed);
if (threadInfo.isInLeaveAndEnter()) {
throw PolyglotEngineException.illegalState("Context cannot be entered inside leaveAndEnter.");
}
}
}
}
if (deactivateSafepoints && threadInfo != PolyglotThreadInfo.NULL) {
threadLocalActions.notifyThreadActivation(threadInfo, false);
}

threadInfo = threads.get(current);
if (threadInfo == null) {
threadInfo = createThreadInfo(current, polyglotThreadFirstEnter);
needsInitialization = true;
}
if (singleThreaded) {
/*
* If this is the only thread, then setting the cached thread info to NULL
* is no performance problem. If there is other thread that is just about to
* enter, we are making sure that it initializes multi-threading if this
* thread doesn't do it.
*/
setCachedThreadInfo(PolyglotThreadInfo.NULL);
}
boolean transitionToMultiThreading = isSingleThreaded() && hasActiveOtherThread(true, false);
assert threadInfo != null;
if (!leaveAndEnter) {
checkClosedOrDisposing(mustSucceed);
if (threadInfo.isInLeaveAndEnter()) {
throw PolyglotEngineException.illegalState("Context cannot be entered inside leaveAndEnter.");
}
}

if (transitionToMultiThreading) {
// recheck all thread accesses
checkAllThreadAccesses(Thread.currentThread(), false);
}
threadInfo = threads.get(current);
if (threadInfo == null) {
threadInfo = createThreadInfo(current, polyglotThreadFirstEnter);
needsInitialization = true;
}
if (singleThreaded) {
/*
* If this is the only thread, then setting the cached thread info
* to NULL is no performance problem. If there is other thread that
* is just about to enter, we are making sure that it initializes
* multi-threading if this thread doesn't do it.
*/
setCachedThreadInfo(PolyglotThreadInfo.NULL);
}
boolean transitionToMultiThreading = isSingleThreaded() && hasActiveOtherThread(true, false);

if (transitionToMultiThreading) {
/*
* We need to do this early (before initializeMultiThreading) as entering or
* local initialization depends on single thread per context.
*/
engine.singleThreadPerContext.invalidate();
singleThreaded = false;
}
if (transitionToMultiThreading) {
// recheck all thread accesses
checkAllThreadAccesses(Thread.currentThread(), false);
}

if (needsInitialization) {
threads.put(current, threadInfo);
}
if (transitionToMultiThreading) {
/*
* We need to do this early (before initializeMultiThreading) as
* entering or local initialization depends on single thread per
* context.
*/
engine.singleThreadPerContext.invalidate();
singleThreaded = false;
}

if (needsInitialization) {
/*
* Do not enter the thread before initializing thread locals. Creation of
* thread locals might fail.
*/
initializeThreadLocals(threadInfo);
}
if (needsInitialization) {
threads.put(current, threadInfo);
}

prev = threadInfo.enterInternal();
if (leaveAndEnter) {
threadInfo.setLeaveAndEnterInterrupter(null);
notifyAll();
}
if (needsInitialization) {
this.threadLocalActions.notifyEnterCreatedThread();
}
if (closingThread != Thread.currentThread()) {
try {
threadInfo.notifyEnter(engine, this);
} catch (Throwable t) {
threadInfo.leaveInternal(prev);
throw t;
}
}
enteredThread = threadInfo;
if (needsInitialization) {
/*
* Do not enter the thread before initializing thread locals.
* Creation of thread locals might fail.
*/
initializeThreadLocals(threadInfo);
}

// new thread became active so we need to check potential active thread local
// actions and process them.
Set<ThreadLocalAction> activatedActions = null;
if (enteredThread.getEnteredCount() == 1 && !deactivateSafepoints) {
activatedActions = threadLocalActions.notifyThreadActivation(threadInfo, true);
}
prev = threadInfo.enterInternal();
if (leaveAndEnter) {
threadInfo.setLeaveAndEnterInterrupter(null);
notifyAll();
}
if (needsInitialization) {
this.threadLocalActions.notifyEnterCreatedThread();
}
if (closingThread != Thread.currentThread()) {
try {
threadInfo.notifyEnter(engine, this);
} catch (Throwable t) {
threadInfo.leaveInternal(prev);
throw t;
}
}
enteredThread = threadInfo;

// new thread became active so we need to check potential active thread
// local
// actions and process them.
Set<ThreadLocalAction> activatedActions = null;
if (enteredThread.getEnteredCount() == 1 && !deactivateSafepoints) {
activatedActions = threadLocalActions.notifyThreadActivation(threadInfo, true);
}

if (transitionToMultiThreading) {
// we need to verify that all languages give access
// to all threads in multi-threaded mode.
transitionToMultiThreaded(mustSucceed);
}
if (transitionToMultiThreading) {
// we need to verify that all languages give access
// to all threads in multi-threaded mode.
transitionToMultiThreaded(mustSucceed);
}

if (needsInitialization) {
initializeNewThread(enteredThread, mustSucceed);
}
if (needsInitialization) {
initializeNewThread(enteredThread, mustSucceed);
}

if (enteredThread.getEnteredCount() == 1 && !pauseHandles.isEmpty()) {
for (Iterator<ContextPauseHandle> pauseHandleIterator = pauseHandles.iterator(); pauseHandleIterator.hasNext();) {
ContextPauseHandle pauseHandle = pauseHandleIterator.next();
if (!pauseHandle.pauseThreadLocalAction.isPause() || pauseHandle.isCancelled()) {
pauseHandleIterator.remove();
} else {
if (activatedActions == null || !activatedActions.contains(pauseHandle.pauseThreadLocalAction)) {
threadLocalActions.submit(new Thread[]{Thread.currentThread()}, PolyglotEngineImpl.ENGINE_ID, pauseHandle.pauseThreadLocalAction,
new HandshakeConfig(true, true, false, false));
if (enteredThread.getEnteredCount() == 1 && !pauseHandles.isEmpty()) {
for (Iterator<ContextPauseHandle> pauseHandleIterator = pauseHandles.iterator(); pauseHandleIterator.hasNext();) {
ContextPauseHandle pauseHandle = pauseHandleIterator.next();
if (!pauseHandle.pauseThreadLocalAction.isPause() || pauseHandle.isCancelled()) {
pauseHandleIterator.remove();
} else {
if (activatedActions == null || !activatedActions.contains(pauseHandle.pauseThreadLocalAction)) {
threadLocalActions.submit(new Thread[]{Thread.currentThread()}, PolyglotEngineImpl.ENGINE_ID, pauseHandle.pauseThreadLocalAction,
new HandshakeConfig(true, true, false, false));
}
}
}
}
}
}

// never cache last thread on close or when closingThread
setCachedThreadInfo(threadInfo);

if (needsInitialization && !threadInfo.isPolyglotThread()) {
deadThreads = collectDeadThreads();
}
}
if (needsInitialization && !threadInfo.isPolyglotThread()) {
deadThreads = collectDeadThreads();
}
}

if (deadThreads != null) {
finalizeAndDisposeThreads(deadThreads);
}
if (deadThreads != null) {
finalizeAndDisposeThreads(deadThreads);
}

if (needsInitialization) {
EngineAccessor.INSTRUMENT.notifyThreadStarted(engine, creatorTruffleContext, current);
}
if (needsInitialization) {
EngineAccessor.INSTRUMENT.notifyThreadStarted(engine, creatorTruffleContext, current);
}

return prev;
} finally {
/*
* We need to always poll the safepoint here in case we already submitted a thread
* local action for this thread. Not polling here would make dependencies of that
* event wait forever.
*/
if (localPollSafepoint && enteredThread != null) {
TruffleSafepoint.pollHere(this.uncachedLocation);
return prev;
} finally {
/*
* We need to always poll the safepoint here in case we already submitted a
* thread local action for this thread. Not polling here would make
* dependencies of that event wait forever.
*/
if (localPollSafepoint && enteredThread != null) {
TruffleSafepoint.pollHere(this.uncachedLocation);
}
}
} catch (PolyglotThreadAccessException ex) {
ex.rethrow(this);
}
}
} catch (Throwable t) {
Expand Down

0 comments on commit a810ee8

Please sign in to comment.