Skip to content

Commit 7a2cc21

Browse files
committed
Move some methods related to virtual threads to JavaThreads.
1 parent 1c94365 commit 7a2cc21

File tree

7 files changed

+54
-47
lines changed

7 files changed

+54
-47
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import org.graalvm.nativeimage.Platforms;
2929

3030
import com.oracle.svm.core.Uninterruptible;
31-
import com.oracle.svm.core.thread.PlatformThreads;
31+
import com.oracle.svm.core.thread.JavaThreads;
3232

3333
/**
3434
* This file contains the VM-level events that Native Image supports on all JDK versions. The event
@@ -96,7 +96,7 @@ public String getName() {
9696
@Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true)
9797
public boolean shouldEmit() {
9898
assert !hasDuration;
99-
return shouldEmit0() && !JfrThreadLocal.isThreadExcluded(PlatformThreads.getCurrentThreadOrNull());
99+
return shouldEmit0() && !JfrThreadLocal.isThreadExcluded(JavaThreads.getCurrentThreadOrNull());
100100
}
101101

102102
@Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true)
@@ -108,7 +108,7 @@ public boolean shouldEmit(Thread thread) {
108108
@Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true)
109109
public boolean shouldEmit(long durationTicks) {
110110
assert hasDuration;
111-
return shouldEmit0() && durationTicks >= SubstrateJVM.get().getThresholdTicks(this) && !JfrThreadLocal.isThreadExcluded(PlatformThreads.getCurrentThreadOrNull());
111+
return shouldEmit0() && durationTicks >= SubstrateJVM.get().getThresholdTicks(this) && !JfrThreadLocal.isThreadExcluded(JavaThreads.getCurrentThreadOrNull());
112112
}
113113

114114
@Uninterruptible(reason = "Prevent races with VM operations that start/stop recording.", callerMustBe = true)

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ private static void flushToGlobalMemoryAndRetireBuffer(JfrBuffer buffer) {
229229
* moment, only the current thread may be excluded/included. See GR-44616.
230230
*/
231231
public static void setExcluded(Thread thread, boolean excluded) {
232-
if (thread == null || thread != PlatformThreads.getCurrentThreadOrNull()) {
232+
if (thread == null || thread != JavaThreads.getCurrentThreadOrNull()) {
233233
return;
234234
}
235235
IsolateThread currentIsolateThread = CurrentIsolate.getCurrentThread();
@@ -247,7 +247,7 @@ public static void setExcluded(Thread thread, boolean excluded) {
247247
* thread, see {@link PlatformThreads#ensureCurrentAssigned(String, ThreadGroup, boolean)} where
248248
* a {@link Thread} object must be created before it can be assigned to the current thread. This
249249
* may happen during shutdown in {@link JavaMainWrapper}. Therefore, this method must account
250-
* for the case where {@link PlatformThreads#getCurrentThreadOrNull()} returns null.
250+
* for the case where {@link JavaThreads#getCurrentThreadOrNull()} returns null.
251251
*/
252252
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
253253
public static boolean isThreadExcluded(Thread thread) {
@@ -286,7 +286,7 @@ public Target_jdk_jfr_internal_event_EventWriter newEventWriter() {
286286
throw new OutOfMemoryError("OOME for thread local buffer");
287287
}
288288

289-
Target_jdk_jfr_internal_event_EventWriter result = JfrEventWriterAccess.newEventWriter(buffer, isThreadExcluded(PlatformThreads.getCurrentThreadOrNull()));
289+
Target_jdk_jfr_internal_event_EventWriter result = JfrEventWriterAccess.newEventWriter(buffer, isThreadExcluded(JavaThreads.getCurrentThreadOrNull()));
290290
javaEventWriter.set(result);
291291
return result;
292292
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void registerRunningThreads() {
8888
if (thread != null) {
8989
registerThread(thread);
9090
// Re-register vthreads that are already mounted.
91-
Thread vthread = PlatformThreads.getVThread(thread);
91+
Thread vthread = PlatformThreads.getMountedVirtualThread(thread);
9292
if (vthread != null) {
9393
registerThread(vthread);
9494
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
import com.oracle.svm.core.jdk.StackTraceUtils;
4848
import com.oracle.svm.core.snippets.KnownIntrinsics;
4949
import com.oracle.svm.core.stack.StackFrameVisitor;
50+
import com.oracle.svm.core.threadlocal.FastThreadLocal;
51+
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
52+
import com.oracle.svm.core.threadlocal.FastThreadLocalLong;
5053
import com.oracle.svm.util.ReflectionUtil;
5154

5255
/**
@@ -68,6 +71,17 @@
6871
* and choose the appropriate action.
6972
*/
7073
public final class JavaThreads {
74+
/**
75+
* The {@linkplain JavaThreads#getThreadId thread id} of the {@link Thread#currentThread()},
76+
* which can be a {@linkplain Target_java_lang_Thread#vthread virtual thread} or a
77+
* {@linkplain PlatformThreads#currentThread platform thread}.
78+
*
79+
* As the value of the thread local can change over the thread lifetime (see carrier threads),
80+
* it should only be accessed by the owning thread (via {@link FastThreadLocalLong#get()} and
81+
* {@link FastThreadLocalLong#set(long)}).
82+
*/
83+
static final FastThreadLocalLong currentVThreadId = FastThreadLocalFactory.createLong("JavaThreads.currentVThreadId").setMaxOffset(FastThreadLocal.BYTE_OFFSET);
84+
7185
/** For Thread.nextThreadID(). */
7286
static final AtomicLong threadSeqNumber = new AtomicLong();
7387
/** For Thread.nextThreadNum(). */
@@ -382,7 +396,7 @@ static void blockedOn(Target_sun_nio_ch_Interruptible b) {
382396
*/
383397
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
384398
public static long getCurrentThreadId() {
385-
long id = PlatformThreads.currentVThreadId.get();
399+
long id = currentVThreadId.get();
386400
if (GraalDirectives.inIntrinsic()) {
387401
ReplacementsUtil.dynamicAssert(id != 0 && id == getThreadId(Thread.currentThread()), "ids must match");
388402
} else {
@@ -400,8 +414,27 @@ public static long getCurrentThreadId() {
400414
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
401415
public static long getCurrentThreadIdOrZero() {
402416
if (CurrentIsolate.getCurrentThread().isNonNull()) {
403-
return PlatformThreads.currentVThreadId.get();
417+
return currentVThreadId.get();
404418
}
405419
return 0L;
406420
}
421+
422+
@Uninterruptible(reason = "Ensure consistency of vthread and cached vthread id.")
423+
static void setCurrentThread(Thread carrier, Thread thread) {
424+
assert carrier == PlatformThreads.currentThread.get();
425+
assert thread == carrier || isVirtual(thread);
426+
toTarget(carrier).vthread = (thread != carrier) ? thread : null;
427+
currentVThreadId.set(getThreadId(thread));
428+
}
429+
430+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
431+
public static Thread getCurrentThreadOrNull() {
432+
Thread thread = PlatformThreads.currentThread.get();
433+
if (thread == null) {
434+
return null;
435+
}
436+
437+
Target_java_lang_Thread tjlt = SubstrateUtil.cast(thread, Target_java_lang_Thread.class);
438+
return (tjlt.vthread != null) ? tjlt.vthread : thread;
439+
}
407440
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/PlatformThreads.java

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898
import com.oracle.svm.core.thread.VMThreads.StatusSupport;
9999
import com.oracle.svm.core.threadlocal.FastThreadLocal;
100100
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
101-
import com.oracle.svm.core.threadlocal.FastThreadLocalLong;
102101
import com.oracle.svm.core.threadlocal.FastThreadLocalObject;
103102
import com.oracle.svm.core.util.TimeUtils;
104103
import com.oracle.svm.core.util.VMError;
@@ -126,17 +125,6 @@ public static PlatformThreads singleton() {
126125
/** The platform {@link java.lang.Thread} for the {@link IsolateThread}. */
127126
static final FastThreadLocalObject<Thread> currentThread = FastThreadLocalFactory.createObject(Thread.class, "PlatformThreads.currentThread").setMaxOffset(FastThreadLocal.BYTE_OFFSET);
128127

129-
/**
130-
* The {@linkplain JavaThreads#getThreadId thread id} of the {@link Thread#currentThread()},
131-
* which can be a {@linkplain Target_java_lang_Thread#vthread virtual thread} or the
132-
* {@linkplain #currentThread platform thread itself}.
133-
*
134-
* As the value of the thread local can change over the thread lifetime (see carrier threads),
135-
* it should only be accessed by the owning thread (via {@link FastThreadLocalLong#get()} and
136-
* {@link FastThreadLocalLong#set(long)}).
137-
*/
138-
static final FastThreadLocalLong currentVThreadId = FastThreadLocalFactory.createLong("PlatformThreads.currentVThreadId").setMaxOffset(FastThreadLocal.BYTE_OFFSET);
139-
140128
/**
141129
* The number of running non-daemon threads. The initial value accounts for the main thread,
142130
* which is implicitly running when the isolate is created.
@@ -450,36 +438,22 @@ static void assignCurrent(Thread thread, boolean manuallyStarted) {
450438
@Uninterruptible(reason = "Ensure consistency of vthread and cached vthread id.")
451439
private static void assignCurrent0(Thread thread) {
452440
VMError.guarantee(currentThread.get() == null, "overwriting existing java.lang.Thread");
453-
currentVThreadId.set(JavaThreads.getThreadId(thread));
441+
JavaThreads.currentVThreadId.set(JavaThreads.getThreadId(thread));
454442
currentThread.set(thread);
455443

456444
assert toTarget(thread).isolateThread.isNull();
457445
toTarget(thread).isolateThread = CurrentIsolate.getCurrentThread();
458446
ThreadListenerSupport.get().beforeThreadStart(CurrentIsolate.getCurrentThread(), thread);
459447
}
460448

461-
@Uninterruptible(reason = "Ensure consistency of vthread and cached vthread id.")
462-
static void setCurrentThread(Thread carrier, Thread thread) {
463-
assert carrier == currentThread.get();
464-
assert thread == carrier || isVirtual(thread);
465-
toTarget(carrier).vthread = (thread != carrier) ? thread : null;
466-
currentVThreadId.set(JavaThreads.getThreadId(thread));
467-
}
468-
469-
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
470-
public static Thread getCurrentThreadOrNull() {
471-
Thread thread = PlatformThreads.currentThread.get();
472-
if (thread == null) {
473-
return null;
474-
}
475-
476-
Target_java_lang_Thread tjlt = SubstrateUtil.cast(thread, Target_java_lang_Thread.class);
477-
return (tjlt.vthread != null) ? tjlt.vthread : thread;
478-
}
479-
480-
/** Returns the mounted virtual thread if one exists, otherwise null. */
449+
/**
450+
* Returns the virtual thread that is mounted on the given platform thread, or {@code null} if
451+
* no virtual thread is mounted.
452+
*/
481453
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
482-
public static Thread getVThread(Thread thread) {
454+
public static Thread getMountedVirtualThread(Thread thread) {
455+
assert thread == currentThread.get() || VMOperation.isInProgressAtSafepoint();
456+
assert !isVirtual(thread);
483457
return toTarget(thread).vthread;
484458
}
485459

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static Thread currentCarrierThread() {
197197
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
198198
@Substitute
199199
static Thread currentThread() {
200-
Thread thread = PlatformThreads.getCurrentThreadOrNull();
200+
Thread thread = JavaThreads.getCurrentThreadOrNull();
201201
if (GraalDirectives.inIntrinsic()) {
202202
ReplacementsUtil.dynamicAssert(thread != null, "Thread has not been set yet");
203203
} else {
@@ -209,7 +209,7 @@ static Thread currentThread() {
209209
@SuppressWarnings("static-method")
210210
@Substitute
211211
void setCurrentThread(Thread thread) {
212-
PlatformThreads.setCurrentThread(JavaThreads.fromTarget(this), thread);
212+
JavaThreads.setCurrentThread(JavaThreads.fromTarget(this), thread);
213213
}
214214

215215
@Substitute

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_VirtualThread.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ static Object acquireInterruptLockMaybeSwitch(Target_java_lang_VirtualThread sel
307307
* thread might never get unparked, in which case both threads are stuck.
308308
*/
309309
Thread carrier = self.carrierThread;
310-
PlatformThreads.setCurrentThread(carrier, carrier);
310+
JavaThreads.setCurrentThread(carrier, carrier);
311311
token = self;
312312
}
313313
Object lock = asTarget(self).interruptLock;
@@ -323,7 +323,7 @@ static void releaseInterruptLockMaybeSwitchBack(Target_java_lang_VirtualThread s
323323
assert token == self;
324324
Thread carrier = asVTarget(token).carrierThread;
325325
assert Thread.currentThread() == carrier;
326-
PlatformThreads.setCurrentThread(carrier, asThread(token));
326+
JavaThreads.setCurrentThread(carrier, asThread(token));
327327
}
328328
}
329329

0 commit comments

Comments
 (0)