RFR: 8305670: Performance regression in LockSupport.unpark with lots of idle threads [v3]
Daniel D. Daugherty
dcubed at openjdk.org
Fri Apr 21 16:09:49 UTC 2023
On Fri, 21 Apr 2023 02:41:41 GMT, David Holmes <dholmes at openjdk.org> wrote:
>> There are ~76 ThreadsListHandle variables in the code base. These are the only ones with comments:
>>
>> src/hotspot/share/runtime/threadSMR.cpp: ThreadsListHandle tlh; // make the current ThreadsList safe for reporting
>> src/hotspot/share/prims/unsafe.cpp: ThreadsListHandle tlh; // Provides memory barrier
>> src/hotspot/share/compiler/compileBroker.cpp: ThreadsListHandle tlh; // name() depends on the TLH.
>> src/hotspot/share/compiler/compileBroker.cpp: ThreadsListHandle tlh; // name() depends on the TLH.
>> src/hotspot/share/compiler/compileBroker.cpp: ThreadsListHandle tlh; // name() depends on the TLH.
>> src/hotspot/share/compiler/compileBroker.cpp: ThreadsListHandle tlh; // name() depends on the TLH.
>>
>>
>> The new "// Provides memory barrier" is the only one that even talks about barriers.
>> I'm inclined to delete the comment given that these current lines of code:
>>
>> if (java_lang_Thread::thread(thread_oop) != nullptr) {
>> // Try to capture the live JavaThread in a ThreadsListHandle:
>> ThreadsListHandle tlh;
>> if (java_lang_Thread::thread(thread_oop) != nullptr) {
>> // The still live JavaThread is protected by the ThreadsListHandle.
>> JavaThread* thr = nullptr;
>>
>> I think the comments added in the previous comment are enough to make this code clear.
>> @robehn and @dholmes-ora - are you both good with this?
>
> I don't mind if the "memory barrier" comment is there or not. I'm more concerned about whether the actual required ordering constraints are in fact enforced. I think `java_lang_Thread::set_thread` may need to have release semantics (and the matching `acquire` is (implicitly) within the TLH construction).
@dholmes-ora - I'm sorry that I forgot to reply to this earlier comment in this thread:
https://github.com/openjdk/jdk/pull/13519#discussion_r1171987653
> but as adding to the threadsList is done under a lock (as is setting eetop)
Adding a new JavaThread* to the main ThreadsList is done under a lock.
The `java_lang_Thread::set_thread()` calls are less clean:
- there's one call from`create_initial_thread()` that doesn't have the Threads_lock, but I also don't think it needs it.
- there's one call from `JavaThread::allocate_threadObj()` which happens during JNI attach that doesn't have the Threads_lock, but I don't think it needs it
- the call from `JavaThread::prepare()` has the Threads_lock
- the call from `JavaThread::start_internal_daemon()` has the Threads_lock
Of course, here's our favorite call from `ensure_join()`:
static void ensure_join(JavaThread* thread) {
// We do not need to grab the Threads_lock, since we are operating on ourself.
<snip>
OrderAccess::release();
java_lang_Thread::set_thread(threadObj(), nullptr);
Obviously someone thought that call to `java_lang_Thread::set_thread()` needed a "release".
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/13519#discussion_r1173945325
More information about the hotspot-runtime-dev
mailing list