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
8268902: Testing for threadObj != NULL is unnecessary in handshake #4512
Conversation
|
We can't remove all the checks for threadObj for NULL since there are places, particularly in JVMTI that use this test for threads that are newly created. |
assert(_handshakee->threadObj() != NULL, | ||
"null threadobj is impossible because we're handshaking while the thread is being created"); | ||
if (_handshakee->is_exiting()) { |
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.
The assert() is racy when it comes before the _handshakee->is_exiting()
check.
It is possible for the target thread (_handshakee
) to set the exiting condition:
src/hotspot/share/runtime/thread.cpp: JavaThread::exit():
set_terminated(_thread_exiting);
and call:
ensure_join(this);
which clears the _threadObj
field while the caller has just
called HandshakeState::suspend_with_handshake()
.
The caller would then fail the assert() when racing with the
exiting thread when what you want it to do is detect the
exiting condition and return false.
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.
Update: After re-reading more of the code, I think I have to change
my comment here. The code above (HandshakeState::suspend_with_handshake()
)
is called from SuspendThreadHandshake::do_thread() which is a synchronous
handshake. The caller requesting the synchronous handshake cannot proceed until
the target thread is handshakeable. When the target thread is in JavaThread::exit()
it is in thread state _thread_in_vm
and that's not a safe/handshakeable state so
the calling thread must wait for the target thread to become handshakeable or for
the exiting condition to be true. No race here is possible.
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.
Yes, the _handshakee thread - or target thread can't do suspend_with_handshake unless it's in a safe state, so the ensure_join() function must have completed or not been called. Also ensure_join() clears the ThreadObj's Thread field but the JavaThread->_threadObj field isn't cleared:
java_lang_Thread::set_thread(threadObj(), NULL);
The _threadObj field isn't cleared until the JavaThread* destructor so this code should not have a reference to JavaThread at this point.
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.
Thumbs up (after revising my comments).
@coleenp This change now passes all automated pre-integration checks. 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 2 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the
|
Thanks for the review, Dan! |
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 Coleen,
What about an attaching thread that hits a handshake when trying to allocate the java.lang.Thread object?
David
Mailing list message from Coleen Phillimore on hotspot-runtime-dev: On 6/21/21 12:28 AM, David Holmes wrote:
The attaching thread can't be handshake because it hasn't been added to Coleen |
Mailing list message from David Holmes on hotspot-runtime-dev: On 22/06/2021 1:41 am, Coleen Phillimore wrote:
I'm not sure what code you are looking at but attach_current_thread does: // This thread will not do a safepoint check, since it has and the thread is now on the threads-list; then it does: thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD); after that. And that code does: instanceHandle thread_oop = ik->allocate_instance_handle(CHECK); java_lang_Thread::set_thread(thread_oop(), this); The thread must be on the threads-list and able to participate in David
|
1 similar comment
Mailing list message from David Holmes on hotspot-runtime-dev: On 22/06/2021 1:41 am, Coleen Phillimore wrote:
I'm not sure what code you are looking at but attach_current_thread does: // This thread will not do a safepoint check, since it has and the thread is now on the threads-list; then it does: thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD); after that. And that code does: instanceHandle thread_oop = ik->allocate_instance_handle(CHECK); java_lang_Thread::set_thread(thread_oop(), this); The thread must be on the threads-list and able to participate in David
|
I am looking at all the threads we create in the vm like the ServiceThread (look for Threads::add()), but not attach_current_thread in jni. You're right, we have to make this thread safepoint here. |
Mailing list message from David Holmes on hotspot-runtime-dev: On 23/06/2021 12:39 am, Coleen Phillimore wrote:
I'm not sure on the "why". Some internal threads (e.g. AttachListener)
Okay guess I'd better look at it again then. :) I can determine which David |
Mailing list message from Coleen Phillimore on hotspot-runtime-dev: On 6/22/21 6:59 PM, David Holmes wrote:
Seems that ServiceTherad, MonitorDeflationThread and JFRRecorderThread There's lots of variations with similar code to create threads.
Please!? Refactoring would be very nice! Thanks,
|
1 similar comment
Mailing list message from Coleen Phillimore on hotspot-runtime-dev: On 6/22/21 6:59 PM, David Holmes wrote:
Seems that ServiceTherad, MonitorDeflationThread and JFRRecorderThread There's lots of variations with similar code to create threads.
Please!? Refactoring would be very nice! Thanks,
|
Things got conflated in this PR. The test is here: bool HandshakeState::suspend_with_handshake() { We get the JavaThread from threadObj then call java_suspend, so it can't be NULL! |
The handshake code tests if the JavaThread->is_exiting or that the threadObj() is null. Ever since JDK-8244997, once the JavaThread is running, the _threadObj won't be null until JavaThread is destroyed. So testing is_exiting is all you need to do.
In gtest, the test JavaThread doesn't create a _threadObj JDK-8215948 so removing this unnecessary test allows writing gtests for handshakes.
Tested with tier1-6.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/4512/head:pull/4512
$ git checkout pull/4512
Update a local copy of the PR:
$ git checkout pull/4512
$ git pull https://git.openjdk.java.net/jdk pull/4512/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 4512
View PR using the GUI difftool:
$ git pr show -t 4512
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/4512.diff