[jdk11u-dev] RFR: 8214097: Rework thread initialization and teardown logic
SUN Guoyun
duke at openjdk.org
Tue Dec 19 12:07:50 UTC 2023
On Tue, 19 Dec 2023 10:56:32 GMT, Severin Gehwolf <sgehwolf at openjdk.org> wrote:
> @sunny868 Why are you backporting this patch to OpenJDK 11u? It's an intrusive patch that changes thread initialization which isn't suitable for backport at this stage in the lifecycle of JDK 11. There must be a **very** good reason to even consider it.
runtime/InternalApi/ThreadCpuTimesDeadlock.java can trigger exception occasionally. I traced the cause:
<pre>
// src/hotspot/os/linux/os_linux.cpp
// be called by com.sun.jmx.mbeanserver.JmxMBeanServer
6171 static jlong fast_cpu_time(Thread *thread) {
6172 clockid_t clockid;
6173 int rc = os::Linux::pthread_getcpuclockid(thread->osthread()->pthread_id(),
6174 &clockid); // thread->osthread() maybe NULL or pthread_id() is 0.
6175 if (rc == 0) {
6176 return os::Linux::fast_thread_cpu_time(clockid);
6177 } else {
6178 // It's possible to encounter a terminated native thread that failed
6179 // to detach itself from the VM - which should result in ESRCH.
6180 assert_status(rc == ESRCH, rc, "pthread_getcpuclockid failed");
6181 return -1;
6182 }
6183 }
</pre>
Here. Line 6173 `thread->osthread()` is a possibility of being nullptr because the non-java-thread was placed on the `_the_list` too early.
<pre>
// share/runtime/thread.cpp
1309 NonJavaThread::NonJavaThread() : Thread(), _next(NULL) {
1310 // Add this thread to _the_list.
1311 MutexLockerEx lock(NonJavaThreadsList_lock, Mutex::_no_safepoint_check_flag);
1312 _next = _the_list._head;
1313 OrderAccess::release_store(&_the_list._head, this); // Do early. It should be done after thread state is RUNNED
1314 }
</pre>
I see this patch do `add thread to _the_list` in `NonJavaThread::pre_run()`, which can make sure the non-java-thread has finished `set_osthread` and `osthread->set_pthread_id` on `os::create_thread`. The correct order is
<pre>
os::create_thread(Thread* thread ...) {
thread->set_osthread(osthread);
pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
osthread->set_pthread_id(tid);
wait until osthread state equal INITIALIZED.
}
thread_native_entry(Thread *thread) {
osthread->set_state(INITIALIZED);
wait until os::start_thread() // set thread state RUNNED
thread->call_run(); // call NonJavaThread::pre_run(), add thread to _the_list
}
</pre>
-------------
PR Comment: https://git.openjdk.org/jdk11u-dev/pull/2411#issuecomment-1862634670
More information about the jdk-updates-dev
mailing list