Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtual Thread Support #18432

Merged
merged 3 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 2 additions & 8 deletions runtime/j9vm/javanextvmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ extern "C" {

#if JAVA_SPEC_VERSION >= 19
extern J9JavaVM *BFUjavaVM;

/* These come from jvm.c */
extern IDATA (*f_monitorEnter)(omrthread_monitor_t monitor);
extern IDATA (*f_monitorExit)(omrthread_monitor_t monitor);
extern IDATA (*f_monitorWait)(omrthread_monitor_t monitor);
extern IDATA (*f_monitorNotifyAll)(omrthread_monitor_t monitor);
#endif /* JAVA_SPEC_VERSION >= 19 */

/* Define for debug
Expand Down Expand Up @@ -280,10 +274,10 @@ enterVThreadTransitionCritical(J9VMThread *currentThread, jobject thread)

while(!objectAccessBarrier.inlineMixedObjectCompareAndSwapU64(currentThread, threadObj, vm->virtualThreadInspectorCountOffset, 0, (U_64)-1)) {
/* Thread is being inspected or unmounted, wait. */
vmFuncs->internalExitVMToJNI(currentThread);
vmFuncs->internalReleaseVMAccess(currentThread);
VM_AtomicSupport::yieldCPU();
/* After wait, the thread may suspend here. */
vmFuncs->internalEnterVMFromJNI(currentThread);
vmFuncs->internalAcquireVMAccess(currentThread);
threadObj = J9_JNI_UNWRAP_REFERENCE(thread);
}
}
Expand Down
26 changes: 5 additions & 21 deletions runtime/j9vm/jvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,7 @@ typedef IDATA (*MonitorEnter)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorExit)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorInit)(omrthread_monitor_t* handle, UDATA flags, char* name);
typedef IDATA (*MonitorDestroy)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorWait)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorWaitTimed)(omrthread_monitor_t monitor, I_64 millis, IDATA nanos);
typedef IDATA (*MonitorNotify)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorNotifyAll)(omrthread_monitor_t monitor) ;
typedef IDATA (* ThreadLibControl)(const char * key, UDATA value) ;
typedef IDATA (* ThreadLibControl)(const char * key, UDATA value);
typedef IDATA (*SetCategory)(omrthread_t thread, UDATA category, UDATA type);
typedef IDATA (*LibEnableCPUMonitor)(omrthread_t thread);

Expand Down Expand Up @@ -270,12 +266,8 @@ static ThreadDetach f_threadDetach;
/* Share these with the other *.c in the DLL */
MonitorEnter f_monitorEnter;
MonitorExit f_monitorExit;
MonitorWait f_monitorWait;
MonitorNotifyAll f_monitorNotifyAll;
static MonitorInit f_monitorInit;
static MonitorDestroy f_monitorDestroy;
static MonitorWaitTimed f_monitorWaitTimed;
static MonitorNotify f_monitorNotify;
static PortInitLibrary portInitLibrary;
static PortGetSize portGetSizeFn;
static PortGetVersion portGetVersionFn;
Expand Down Expand Up @@ -1020,15 +1012,11 @@ preloadLibraries(void)
f_monitorExit = (MonitorExit) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_exit");
f_monitorInit = (MonitorInit) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_init_with_name");
f_monitorDestroy = (MonitorDestroy) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_destroy");
f_monitorWait = (MonitorWait) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_wait");
f_monitorWaitTimed = (MonitorWaitTimed) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_wait_timed");
f_monitorNotify = (MonitorNotify) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_notify");
f_monitorNotifyAll = (MonitorNotifyAll) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_notify_all");
f_threadLibControl = (ThreadLibControl) GetProcAddress (threadDLL, (LPCSTR) "omrthread_lib_control");
f_setCategory = (SetCategory) GetProcAddress (threadDLL, (LPCSTR) "omrthread_set_category");
f_libEnableCPUMonitor = (LibEnableCPUMonitor) GetProcAddress (threadDLL, (LPCSTR) "omrthread_lib_enable_cpu_monitor");
if (!f_threadGlobal || !f_threadAttachEx || !f_threadDetach || !f_monitorEnter || !f_monitorExit || !f_monitorInit || !f_monitorDestroy || !f_monitorWaitTimed
|| !f_monitorNotify || !f_monitorNotifyAll || !f_threadLibControl || !f_setCategory || !f_libEnableCPUMonitor || !f_monitorWait
if (!f_threadGlobal || !f_threadAttachEx || !f_threadDetach || !f_monitorEnter || !f_monitorExit || !f_monitorInit
|| !f_monitorDestroy || !f_threadLibControl || !f_setCategory || !f_libEnableCPUMonitor
) {
FreeLibrary(vmDLL);
FreeLibrary(threadDLL);
Expand Down Expand Up @@ -1451,15 +1439,11 @@ preloadLibraries(void)
f_monitorExit = (MonitorExit) dlsym (threadDLL, "omrthread_monitor_exit");
f_monitorInit = (MonitorInit) dlsym (threadDLL, "omrthread_monitor_init_with_name");
f_monitorDestroy = (MonitorDestroy) dlsym (threadDLL, "omrthread_monitor_destroy");
f_monitorWait = (MonitorWait) dlsym (threadDLL, "omrthread_monitor_wait");
f_monitorWaitTimed = (MonitorWaitTimed) dlsym (threadDLL, "omrthread_monitor_wait_timed");
f_monitorNotify = (MonitorNotify) dlsym (threadDLL, "omrthread_monitor_notify");
f_monitorNotifyAll = (MonitorNotifyAll) dlsym (threadDLL, "omrthread_monitor_notify_all");
f_threadLibControl = (ThreadLibControl) dlsym (threadDLL, "omrthread_lib_control");
f_setCategory = (SetCategory) dlsym (threadDLL, "omrthread_set_category");
f_libEnableCPUMonitor = (LibEnableCPUMonitor) dlsym (threadDLL, "omrthread_lib_enable_cpu_monitor");
if (!f_threadGlobal || !f_threadAttachEx || !f_threadDetach || !f_monitorEnter || !f_monitorExit || !f_monitorInit || !f_monitorDestroy || !f_monitorWaitTimed
|| !f_monitorNotify || !f_monitorNotifyAll || !f_threadLibControl || !f_setCategory || !f_libEnableCPUMonitor || !f_monitorWait
if (!f_threadGlobal || !f_threadAttachEx || !f_threadDetach || !f_monitorEnter || !f_monitorExit || !f_monitorInit
|| !f_monitorDestroy || !f_threadLibControl || !f_setCategory || !f_libEnableCPUMonitor
) {
dlclose(vmDLL);
#ifdef J9ZOS390
Expand Down
25 changes: 10 additions & 15 deletions runtime/jvmti/jvmtiStackFrame.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,29 +617,25 @@ jvmtiNotifyFramePop(jvmtiEnv *env,
J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
if (JVMTI_ERROR_NONE == rc) {
#if JAVA_SPEC_VERSION >= 19
BOOLEAN isVThreadSuspended = FALSE;
j9object_t threadObject = (NULL == thread) ? currentThread->threadObject : J9_JNI_UNWRAP_REFERENCE(thread);
if (NULL != targetThread)
#endif /* JAVA_SPEC_VERSION >= 19 */
{
vm->internalVMFunctions->haltThreadForInspection(currentThread, targetThread);
}
#if JAVA_SPEC_VERSION >= 19
if ((NULL != thread) && (NULL == targetThread)) {
/* The assert in getVMThread will assure that this is a virtual thread */
jint vthreadState = J9VMJAVALANGVIRTUALTHREAD_STATE(currentThread, J9_JNI_UNWRAP_REFERENCE(thread));
isVThreadSuspended = OMR_ARE_ANY_BITS_SET(vthreadState, JVMTI_VTHREAD_STATE_SUSPENDED);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

if ((currentThread == targetThread)
/* Error if the thread is not suspended and not the current thread. */
if ((currentThread != targetThread)
#if JAVA_SPEC_VERSION >= 19
|| isVThreadSuspended
&& (0 == J9OBJECT_U32_LOAD(currentThread, threadObject, vm->isSuspendedInternalOffset))
#else /* JAVA_SPEC_VERSION >= 19 */
&& OMR_ARE_NO_BITS_SET(targetThread->publicFlags, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND)
#endif /* JAVA_SPEC_VERSION >= 19 */
|| ((NULL != targetThread) && OMR_ARE_ANY_BITS_SET(targetThread->publicFlags, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND))
) {
) {
rc = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
} else {
J9StackWalkState walkState = {0};
J9VMThread *threadToWalk = targetThread;

#if JAVA_SPEC_VERSION >= 19
J9VMThread stackThread = {0};
J9VMEntryLocalStorage els = {0};
Expand Down Expand Up @@ -669,9 +665,8 @@ jvmtiNotifyFramePop(jvmtiEnv *env,
}
}
}
} else {
rc = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
}

#if JAVA_SPEC_VERSION >= 19
if (NULL != targetThread)
#endif /* JAVA_SPEC_VERSION >= 19 */
Expand Down
4 changes: 2 additions & 2 deletions runtime/vm/ContinuationHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,10 +539,10 @@ acquireVThreadInspector(J9VMThread *currentThread, jobject thread, BOOLEAN spin)
vthreadInspectorCount = J9OBJECT_I64_LOAD(currentThread, threadObj, vm->virtualThreadInspectorCountOffset);
if (vthreadInspectorCount < 0) {
/* Thread is in transition, wait. */
vmFuncs->internalExitVMToJNI(currentThread);
vmFuncs->internalReleaseVMAccess(currentThread);
VM_AtomicSupport::yieldCPU();
/* After wait, the thread may suspend here. */
vmFuncs->internalEnterVMFromJNI(currentThread);
vmFuncs->internalAcquireVMAccess(currentThread);
if (spin) {
goto retry;
} else {
Expand Down