-
Notifications
You must be signed in to change notification settings - Fork 752
JVMTI WaitNotifySuspendedVThreadTest fails with JVMTI_ERROR_THREAD_SUSPENDED #16689
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
Comments
Problem
Solution
|
@dipak-bagadiya #16689 (comment) contains the draft solution. @gacholio Can you please give feedback on the above solution? |
For normal threads, there is only one suspension state, i.e. you can suspend a thread in java and resume it using JVMTI. Also, Perhaps a better solution would be to maintain a suspended flag in the object that is not specific to JVMTI and set/clear it in the java suspend/resume as well. There are also uses of |
Agreed for carrier threads. This does not apply to virtual threads since they cannot be resumed or suspended from Java code. We can rename
The above fix will only be needed for JDK19's java/lang/Thread. In JDK20's java/lang/Thread, |
Revised Suspend, Resume and GetThreadState LogicThe old logic in #16689 (comment) is flawed. The new logic is below. @dipak-bagadiya Let me know if there any questions.
|
@babsingh the carrier thread object is passed to GetThreadState(thread) function |
JVMTI treats a virtual thread and its carrier thread as two separate threads. If JVMTI suspends a virtual thread, then its carrier thread should not be suspended and vice-versa. Similarly, if JVMTI resumes a virtual thread, then its carrier thread should not be resumed and vice-versa. In OpenJ9, currently, a mounted virtual thread and its carrier thread shared the same J9VMThread. The thread state is derived from the J9VMThread. Due to the sharing of the J9VMThread in the mounted state,if a mounted virtual thread is suspended, then the JVMTI functions will also reflect that its carrier thread is suspended. Currently, "isSuspendedByJVMTI" is the hidden field that holds the suspend status for the virtual thread only, now it made available for carrier thread too, i.e. the scope has changed from "java/lang/VirtualThread" to "java/lang/Thread" threads Also, it is renamed to "isSuspendedInternal" as this hidden field is not just specific to JVMTI. The following functions has changed to set/reset and verify "isSuspendedInternal" status for threads:- 1) SUSPEND THREAD:- suspendhelper.cpp:suspendThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_suspendImpl ->In case of suspend the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is set if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a non-zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 2) RESUME THREAD:- jvmtiThread.c:resumeThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_resumeImpl ->In case of resume the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is cleared if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 3) GETSTATE:- jvmtiHelpers.c:getThreadState jvmtiHelpers.c:getVirtualThreadState ->The getThreadState function is changed in such a way that will verify the "isSuspendedInternal" filed to check the thread is suspend or not. The basic concept behind the new changes: [mounted + unmounted] set the "isSuspendedInternal" field [mounted] the halt flag is only modified if the thread object is stored in targetThread->threadObject [unmounted] Delay setting the halt flag until the thread mount. Related: eclipse-openj9#16689 Signed-off-by: Dipak Bagadiya [email protected]
@dipak-bagadiya The fix #16943 has been merged. Please re-enable the test for JDK20: ProblemList_openjdk20-openj9.txt#L540. |
Closing. The test has been re-enabled in adoptium/aqa-tests#4558. |
Re-opening the issue. The FIX is being reverted since it caused side-effects; see #17334 for more details. PR to revert the FIX: #17335 See #16943 (comment) for a potential fix, which might address the side-effects reported in #17334. |
@dipak-bagadiya The next steps are
|
@babsingh Okay, will take the steps you've suggested and thoroughly review the code before testing. |
JVMTI treats a virtual thread and its carrier thread as two separate threads. If JVMTI suspends a virtual thread, then its carrier thread should not be suspended and vice-versa. Similarly, if JVMTI resumes a virtual thread, then its carrier thread should not be resumed and vice-versa. In OpenJ9, currently, a mounted virtual thread and its carrier thread shared the same J9VMThread. The thread state is derived from the J9VMThread. Due to the sharing of the J9VMThread in the mounted state,if a mounted virtual thread is suspended, then the JVMTI functions will also reflect that its carrier thread is suspended. Currently, "isSuspendedByJVMTI" is the hidden field that holds the suspend status for the virtual thread only, now it made available for carrier thread too, i.e. the scope has changed from "java/lang/VirtualThread" to "java/lang/Thread" threads Also, it is renamed to "isSuspendedInternal" as this hidden field is not just specific to JVMTI. The following functions has changed to set/reset and verify "isSuspendedInternal" status for threads:- 1) SUSPEND THREAD:- suspendhelper.cpp:suspendThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_suspendImpl ->In case of suspend the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is set if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a non-zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 2) RESUME THREAD:- jvmtiThread.c:resumeThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_resumeImpl ->In case of resume the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is cleared if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 3) GETSTATE:- jvmtiHelpers.c:getThreadState jvmtiHelpers.c:getVirtualThreadState ->The getThreadState function is changed in such a way that will verify the "isSuspendedInternal" filed to check the thread is suspend or not. The basic concept behind the new changes: [mounted + unmounted] set the "isSuspendedInternal" field [mounted] the halt flag is only modified if the thread object is stored in targetThread->threadObject [unmounted] Delay setting the halt flag until the thread mount. Related: eclipse-openj9#16689 Signed-off-by: Dipak Bagadiya [email protected]
Closing. |
JVMTI treats a virtual thread and its carrier thread as two separate threads. If JVMTI suspends a virtual thread, then its carrier thread should not be suspended and vice-versa. Similarly, if JVMTI resumes a virtual thread, then its carrier thread should not be resumed and vice-versa. In OpenJ9, currently, a mounted virtual thread and its carrier thread shared the same J9VMThread. The thread state is derived from the J9VMThread. Due to the sharing of the J9VMThread in the mounted state,if a mounted virtual thread is suspended, then the JVMTI functions will also reflect that its carrier thread is suspended. Currently, "isSuspendedByJVMTI" is the hidden field that holds the suspend status for the virtual thread only, now it made available for carrier thread too, i.e. the scope has changed from "java/lang/VirtualThread" to "java/lang/Thread" threads Also, it is renamed to "isSuspendedInternal" as this hidden field is not just specific to JVMTI. The following functions has changed to set/reset and verify "isSuspendedInternal" status for threads:- 1) SUSPEND THREAD:- suspendhelper.cpp:suspendThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_suspendImpl ->In case of suspend the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is set if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a non-zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 2) RESUME THREAD:- jvmtiThread.c:resumeThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_resumeImpl ->In case of resume the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is cleared if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 3) GETSTATE:- jvmtiHelpers.c:getThreadState jvmtiHelpers.c:getVirtualThreadState ->The getThreadState function is changed in such a way that will verify the "isSuspendedInternal" filed to check the thread is suspend or not. The basic concept behind the new changes: [mounted + unmounted] set the "isSuspendedInternal" field [mounted] the halt flag is only modified if the thread object is stored in targetThread->threadObject [unmounted] Delay setting the halt flag until the thread mount. Related: eclipse-openj9#16689 Signed-off-by: Dipak Bagadiya [email protected]
JVMTI treats a virtual thread and its carrier thread as two separate threads. If JVMTI suspends a virtual thread, then its carrier thread should not be suspended and vice-versa. Similarly, if JVMTI resumes a virtual thread, then its carrier thread should not be resumed and vice-versa. In OpenJ9, currently, a mounted virtual thread and its carrier thread shared the same J9VMThread. The thread state is derived from the J9VMThread. Due to the sharing of the J9VMThread in the mounted state,if a mounted virtual thread is suspended, then the JVMTI functions will also reflect that its carrier thread is suspended. Currently, "isSuspendedByJVMTI" is the hidden field that holds the suspend status for the virtual thread only, now it made available for carrier thread too, i.e. the scope has changed from "java/lang/VirtualThread" to "java/lang/Thread" threads Also, it is renamed to "isSuspendedInternal" as this hidden field is not just specific to JVMTI. The following functions has changed to set/reset and verify "isSuspendedInternal" status for threads:- 1) SUSPEND THREAD:- suspendhelper.cpp:suspendThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_suspendImpl ->In case of suspend the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is set if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a non-zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 2) RESUME THREAD:- jvmtiThread.c:resumeThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_resumeImpl ->In case of resume the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is cleared if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 3) GETSTATE:- jvmtiHelpers.c:getThreadState jvmtiHelpers.c:getVirtualThreadState ->The getThreadState function is changed in such a way that will verify the "isSuspendedInternal" filed to check the thread is suspend or not. The basic concept behind the new changes: [mounted + unmounted] set the "isSuspendedInternal" field [mounted] the halt flag is only modified if the thread object is stored in targetThread->threadObject [unmounted] Delay setting the halt flag until the thread mount. Related: eclipse-openj9#16689 Signed-off-by: Dipak Bagadiya [email protected]
JVMTI treats a virtual thread and its carrier thread as two separate threads. If JVMTI suspends a virtual thread, then its carrier thread should not be suspended and vice-versa. Similarly, if JVMTI resumes a virtual thread, then its carrier thread should not be resumed and vice-versa. In OpenJ9, currently, a mounted virtual thread and its carrier thread shared the same J9VMThread. The thread state is derived from the J9VMThread. Due to the sharing of the J9VMThread in the mounted state,if a mounted virtual thread is suspended, then the JVMTI functions will also reflect that its carrier thread is suspended. Currently, "isSuspendedByJVMTI" is the hidden field that holds the suspend status for the virtual thread only, now it made available for carrier thread too, i.e. the scope has changed from "java/lang/VirtualThread" to "java/lang/Thread" threads Also, it is renamed to "isSuspendedInternal" as this hidden field is not just specific to JVMTI. The following functions has changed to set/reset and verify "isSuspendedInternal" status for threads:- 1) SUSPEND THREAD:- suspendhelper.cpp:suspendThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_suspendImpl ->In case of suspend the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is set if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a non-zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 2) RESUME THREAD:- jvmtiThread.c:resumeThread: jvmtiThread.c:jvmtiSuspendResumeCallBack thread.cpp:Java_java_lang_Thread_resumeImpl ->In case of resume the halt flag (J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND) is cleared if the thread is mounted, i.e. threadObject == targetThread->threadObject in J9VMThread's publicFlags also the hidden field "isSuspendedInternal" set to a zero value for the thread instance in all cases regardless of thread being mounted or unmounted. ->If any of the public flags are already set, then the relevant failure message is assigned. 3) GETSTATE:- jvmtiHelpers.c:getThreadState jvmtiHelpers.c:getVirtualThreadState ->The getThreadState function is changed in such a way that will verify the "isSuspendedInternal" filed to check the thread is suspend or not. The basic concept behind the new changes: [mounted + unmounted] set the "isSuspendedInternal" field [mounted] the halt flag is only modified if the thread object is stored in targetThread->threadObject [unmounted] Delay setting the halt flag until the thread mount. Related: eclipse-openj9#16689 Signed-off-by: Dipak Bagadiya [email protected]
Issue
The
check_jvmti_status
function returns an error,JVMTI_ERROR_THREAD_SUSPENDED
, while the main thread attempts to suspend the virtual and carrier threads.Test CMD
Test Output
The text was updated successfully, but these errors were encountered: