Details
-
Enhancement
-
Resolution: Fixed
-
P3
-
12
-
b18
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8232261 | 11.0.6-oracle | Thomas Stuefe | P3 | Resolved | Fixed | b01 |
JDK-8218056 | 11.0.3 | Thomas Stuefe | P3 | Resolved | Fixed | master |
Description
Thread._stack_base/_stack_size are initialized in the Thread child classes' implementation of Thread.run(), typically right at the beginning. Still this is too late since by that time the new Thread has already been added to the Threads list.
Code iterating that list by e.g. Threads::do_threads() may see the Thread object without stack information. Also, accessing Thread::stack_size() will assert in that case.
Prior discussion: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2018-October/030516.html
--
Details:
During initialization of newborn (created by VM) threads, things happen in the following sequence (on Linux and BSD):
(parent thread)
JVM_StartThread
calls new JavaThread
calls os::create_thread()
- calls pthread_create.
- Child thread starts.
- parent thread waits on Child thread coming up (Handshake part 1)
- child waits. parent continues.
calls JavaThread::prepare()
calls Threads::add and adds newly created thread to thread list (A)
calls Thread::start(Thread)
calls os::start_thread()
- wakes up child thread
- child thread continues to run. Child thread calls <ChildThreadClass>::run(). That function has to be overwritten by every child class.
- Inside <ChildThreadClass>::run(), Thread::record_stack_base_and_size() is called which sets Thread::stack_base and Thread::stack_stize. (B)
On Solaris, Windows and AIX the situations is a bit different:
(parent thread)
JVM_StartThread
calls new JavaThread
calls os::create_thread()
- calls pthread_create.
- Child thread does *not* start but is suspended for now.
- parent continues.
calls JavaThread::prepare()
calls Threads::add and adds newly created thread to thread list (A)
calls Thread::start(Thread)
calls os::start_thread()
- unsuspends the child thread. Child thread starts running for the first time.
- Child thread calls <ChildThreadClass>::run(). That function has to be overwritten by every child class.
- Inside <ChildThreadClass>::run(), Thread::record_stack_base_and_size() is called which sets Thread::stack_base and Thread::stack_stize. (B)
Between (A) and (B) the newly created thread is visible when iterating the Threads list, and has no stack dimensions set.
-------------
Solution: move the initialization of Thread::stack_base/stack_size up, before the Thread is added to the Threads list. This is possible on Linux+BSD, but it is not possible on Windows+Solaris+AIX.
We only can get the stack dimensions from within the newly created thread. On Linux+BSD, we have a time window where the newly created child thread runs and is not yet visible from the outside (before the handshake with the parent thread). This time window does not exist on Windows+Solaris+AIX. Even if we move the initialization of Thread::stack_base/stack_size up to the start of thread_native_entry, this is still too late since by that time the thread is already visible via Threads list.
Code iterating that list by e.g. Threads::do_threads() may see the Thread object without stack information. Also, accessing Thread::stack_size() will assert in that case.
Prior discussion: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2018-October/030516.html
--
Details:
During initialization of newborn (created by VM) threads, things happen in the following sequence (on Linux and BSD):
(parent thread)
JVM_StartThread
calls new JavaThread
calls os::create_thread()
- calls pthread_create.
- Child thread starts.
- parent thread waits on Child thread coming up (Handshake part 1)
- child waits. parent continues.
calls JavaThread::prepare()
calls Threads::add and adds newly created thread to thread list (A)
calls Thread::start(Thread)
calls os::start_thread()
- wakes up child thread
- child thread continues to run. Child thread calls <ChildThreadClass>::run(). That function has to be overwritten by every child class.
- Inside <ChildThreadClass>::run(), Thread::record_stack_base_and_size() is called which sets Thread::stack_base and Thread::stack_stize. (B)
On Solaris, Windows and AIX the situations is a bit different:
(parent thread)
JVM_StartThread
calls new JavaThread
calls os::create_thread()
- calls pthread_create.
- Child thread does *not* start but is suspended for now.
- parent continues.
calls JavaThread::prepare()
calls Threads::add and adds newly created thread to thread list (A)
calls Thread::start(Thread)
calls os::start_thread()
- unsuspends the child thread. Child thread starts running for the first time.
- Child thread calls <ChildThreadClass>::run(). That function has to be overwritten by every child class.
- Inside <ChildThreadClass>::run(), Thread::record_stack_base_and_size() is called which sets Thread::stack_base and Thread::stack_stize. (B)
Between (A) and (B) the newly created thread is visible when iterating the Threads list, and has no stack dimensions set.
-------------
Solution: move the initialization of Thread::stack_base/stack_size up, before the Thread is added to the Threads list. This is possible on Linux+BSD, but it is not possible on Windows+Solaris+AIX.
We only can get the stack dimensions from within the newly created thread. On Linux+BSD, we have a time window where the newly created child thread runs and is not yet visible from the outside (before the handshake with the parent thread). This time window does not exist on Windows+Solaris+AIX. Even if we move the initialization of Thread::stack_base/stack_size up to the start of thread_native_entry, this is still too late since by that time the thread is already visible via Threads list.
Attachments
Issue Links
- backported by
-
JDK-8218056 Thread._stack_base/_stack_size initialized too late for new threads
-
- Resolved
-
-
JDK-8232261 Thread._stack_base/_stack_size initialized too late for new threads
-
- Resolved
-