-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8257831: Suspend with handshakes #3191
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
Conversation
|
👋 Welcome back rehn! A progress list of the required criteria for merging this PR into |
87fed73 to
c47f925
Compare
|
/label remove hotspot |
|
@robehn |
|
/label add hotspot-runtime |
|
@robehn |
|
@robehn The |
Webrevs
|
|
Hi Robbin, |
Hi @reinrich, I think that is because that PR was only in draft state. Good! :) Thanks, Robbin |
Ah, alright, makes sense :) Thanks, Richard. |
dcubed-ojdk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an elegant evolution of the suspend/resume mechanism.
It is so nice to see all the suspend-equivalent stuff go away!
|
@robehn this pull request can not be integrated into git checkout SuspendInHandshake
git fetch https://git.openjdk.java.net/jdk master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
reinrich
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Robbin,
this is a great simplification. Excellent work! :)
Thanks, Richard.
dholmes-ora
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Robbin,
This is a great piece of work with a lot of code simplifications. Unfortunately some new complexities that need to be hidden by appropriate abstractions. Lots of comments, queries and suggestions below.
Thanks,
David
test/hotspot/jtreg/serviceability/jvmti/SuspendWithCurrentThread/SuspendWithCurrentThread.java
Show resolved
Hide resolved
|
@robehn This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 18 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
|
Hi David,
I hope I made things more clear.
Yes, good. Fixed what I could in this commit, also fixed merged conflict. Thanks, Robbin
|
dcubed-ojdk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor nit from a review of incremental v10.
Still thumbs up.
| JavaThread* thread_current = thr->as_Java_thread(); | ||
| assert(thread_current == Thread::current(), "Must be self executed."); | ||
| thread_current->handshake_state()->do_self_suspend(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit - When you know it is the "current" thread, @dholmes-ora has been
using just current and not current_thread or thread_current.
|
Thanks for all input, done done !? :) Re-running test. |
pchilano
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Latest version LGTM!
Thanks,
Patricio
dholmes-ora
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
| JavaThread* target = thr->as_Java_thread(); | ||
| target->handshake_state()->do_self_suspend(); | ||
| JavaThread* current = thr->as_Java_thread(); | ||
| assert(current == Thread::current(), "Must be self executed."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly overkill given do_self_suspend() has a similar assertion.
Thanks |
Thanks |
|
I'll push tomorrow morning and fill RFE to fix the manual transitions in OM/rawmonitor. Thanks for all the feedback! |
dcubed-ojdk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed the v11 and v12 incrementals.
Still a thumbs up.
Thank you! |
reinrich
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've followed the discussion and the increments. Still looks very good to me 👍
Thank you! |
dholmes-ora
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving again for good measure. :)
Thank you! |
|
/integrate |
|
@robehn Since your change was applied there have been 20 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit 86bd44f. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
A suspend request is done by handshaking thread target thread(s). When executing the handshake operation we know the target mutator thread is in a dormant state (as in safepoint safe state). We have a guarantee that it will check it's poll before leaving the dormant state. To stop the thread from leaving the the dormant state we install a second asynchronous handshake to be executed by the targeted thread. The asynchronous handshake will wait on a monitor while the thread is suspended. The target thread cannot not leave the dormant state without a resume request.
Per thread suspend requests are naturally serialized by the per thread HandshakeState lock (we can only execute one handshake at a time per thread).
Instead of having a separate lock we use this to our advantage and use HandshakeState lock for serializing access to the suspend flag and for wait/notify.
Suspend:
Requesting thread -> synchronous handshake -> target thread
Inside synchronus handshake (HandshakeState lock is locked while
executing any handshake):
- Set suspended flag
- Install asynchronous handshake
Target thread -> tries to leave dormant state -> Executes handshakes
Target only executes asynchronous handshake:
- While suspended
- Go to blocked
- Wait on HandshakeState lock
Resume:
Resuming thread:
- Lock HandshakeState lock
- Clear suspended flag
- Notify HandshakeState lock
- Unlock HandshakeState lock
The "suspend requested" flag is an optimization, without it a dormant thread could be suspended and resumed many times and each would add a new asynchronous handshake. Suspend requested flag means there is already an asynchronous suspend handshake in queue which can be re-used, only the suspend flag needs to be set.
Some code can be simplified or done in a smarter way but I refrained from doing such changes instead tried to keep existing code as is as far as possible. This concerns especially raw monitors.
Regarding the changed test, the documentation says:
"If the calling thread is specified in the request_list array, this function will not return until some other thread resumes it."
But the code:
LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
err = jvmti->SuspendThreadList(threads_count, threads, results);
...
// Allow the Main thread to inspect the result of tested threads suspension
agent_unlock(jni);
The thread will never return from SuspendThreadList until resumed, so it cannot unlock with agent_unlock().
Thus main thread is stuck forever on:
// Block until the suspender thread competes the tested threads suspension
agent_lock(jni);
And never checks and resumes the threads. So I removed that lock instead just sleep and check until all thread have the expected suspended state.
This version already contains updates after pre-review comments from @dcubed-ojdk, @pchilano, @coleenp.
(Pre-review comments here:
#2625)
Testing t1-t8, nsk_jdi/nsk_jvmti/jdk_jdi/tck, KS24, RunThese and
combinations like running with -XX:ZCollectionInterval=0.01 -
XX:ZFragmentationLimit=0.
Running above some of above concurrently (load ~240), slow debug,
etc...
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/3191/head:pull/3191$ git checkout pull/3191Update a local copy of the PR:
$ git checkout pull/3191$ git pull https://git.openjdk.java.net/jdk pull/3191/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 3191View PR using the GUI difftool:
$ git pr show -t 3191Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/3191.diff