Skip to content

Commit

Permalink
cleanup current thread get and set. Add some documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rakachan committed Feb 23, 2022
1 parent bddb1b1 commit e7ff2ad
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -854,18 +854,12 @@ public StaticObject getGuestThreadFromHost(Thread host) {
return threadRegistry.getGuestThreadFromHost(host);
}

public void registerCurrentThread() {
Thread t = Thread.currentThread();
getLanguage().getThreadLocalStateFor(t).setCurrentThread(getGuestThreadFromHost(t));
public void registerCurrentThread(StaticObject guestThread) {
getLanguage().getThreadLocalState().setCurrentThread(guestThread);
}

public StaticObject getCurrentThread() {
StaticObject result = getLanguage().getThreadLocalState().getCurrentThread();
if (result != null) {
return result;
}
// Thread not yet started
return getGuestThreadFromHost(Thread.currentThread());
return getLanguage().getThreadLocalState().getCurrentThread(this);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,39 @@
*/
package com.oracle.truffle.espresso.runtime;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.espresso.impl.ClassRegistry;
import com.oracle.truffle.espresso.meta.Meta;
import com.oracle.truffle.espresso.vm.VM;

public class EspressoThreadLocalState {
private EspressoException pendingJniException;
private final ClassRegistry.TypeStack typeStack;
private final VM.PrivilegedStack privilegedStack;

/**
* This is declared as a compilation final for whenever Truffle is able to constant-fold
* accesses to ContextThreadLocals (Which might be the case when running single-threaded, for
* example).
* <p>
* Consistency is guaranteed because a call to {@link #setCurrentThread(StaticObject)} must have
* been performed before execution of guest code on the current thread. Guest threads are
* coupled with host threads on 4 occasions within Espresso:
* <ul>
* <li>Main thread creation.</li>
* <li>Guest code creation of threads. The coupling is performed before execution of the guest
* {@link Thread#run()} (see {@code GuestRunnable})</li>
* <li>Attaching through JNI
* {@link VM#AttachCurrentThread(TruffleObject, TruffleObject, TruffleObject)}.</li>
* <li>Attaching through Truffle
* {@code EspressoLanguage#initializeThread(EspressoContext, Thread)}.</li>
* </ul>
* For these two last cases, coupling is performed right as the supporting guest thread is
* allocated (see
* {@link com.oracle.truffle.espresso.threads.EspressoThreadRegistry#createGuestThreadFromHost(Thread, Meta, VM, String, StaticObject)}).
*/
@CompilationFinal //
private StaticObject currentThread;

Expand Down Expand Up @@ -61,12 +86,25 @@ public void clearPendingException() {
}

public void setCurrentThread(StaticObject t) {
assert currentThread == null;
assert currentThread == null || currentThread == t;
assert t != null && StaticObject.notNull(t);
assert t.getKlass().getContext().getThreadAccess().getHost(t) == Thread.currentThread() : "Current thread fast access set by non-current thread";
currentThread = t;
}

public StaticObject getCurrentThread() {
return currentThread;
public StaticObject getCurrentThread(EspressoContext context) {
StaticObject result = currentThread;
if (result == null) {
// Failsafe, should not happen.
CompilerDirectives.transferToInterpreterAndInvalidate();
context.getLogger().warning("Uninitialized fast current thread lookup for " + Thread.currentThread());
result = context.getGuestThreadFromHost(Thread.currentThread());
if (result != null) {
setCurrentThread(result);
}
return result;
}
return result;
}

public ClassRegistry.TypeStack getTypeStack() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private void registerMainThread(Thread thread, StaticObject self) {
guestMainThread = self;
}
activeThreads.add(self);
context.registerCurrentThread();
context.registerCurrentThread(self);
}

public final AtomicLong createdThreadCount = new AtomicLong();
Expand Down Expand Up @@ -150,6 +150,9 @@ public long applyAsLong(long oldPeak) {
}
}
pushThread(Math.toIntExact(host.getId()), guest);
if (host == Thread.currentThread()) {
context.registerCurrentThread(guest);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ final class GuestRunnable implements Runnable {
@Override
public void run() {
try {
context.registerCurrentThread();
context.registerCurrentThread(thread);
context.getVM().attachThread(Thread.currentThread());
try {
// Execute the payload
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public boolean isGuestInterrupted(Thread t, StaticObject guest) {

@Override
protected StaticObject getCurrentGuestThread() {
return context.getLanguage().getThreadLocalState().getCurrentThread();
return context.getCurrentThread();
}

private StaticObject getThreadFromHost(Thread t) {
Expand Down

0 comments on commit e7ff2ad

Please sign in to comment.