Skip to content

Commit

Permalink
Merge pull request #18432 from babsingh/main3
Browse files Browse the repository at this point in the history
Virtual Thread Support
  • Loading branch information
gacholio committed Nov 9, 2023
2 parents 3126552 + 7c82a95 commit 333880b
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 46 deletions.
10 changes: 2 additions & 8 deletions runtime/j9vm/javanextvmi.cpp
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
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
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
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

0 comments on commit 333880b

Please sign in to comment.