RFR(XL): 8203469: Faster safepoints

David Holmes david.holmes at oracle.com
Mon Feb 11 21:24:45 UTC 2019


On 11/02/2019 7:02 pm, Robbin Ehn wrote:
> Hi David,
> 
> On 2/11/19 2:24 AM, David Holmes wrote:
>> This makes it impossible to use the changeset to search through to 
>> check out how things are being used. In particular in this case there 
>> doesn't seem to be a need for the 
>> SafepointSynchronize::increment_jni_active_count() function because 
>> its only used by the VMThread now from within the other safepoint code.
>>
> 
> We sorted this out in other channel, it's a webrev bug (or miss-feature).

Okay. I applied your patch and regenerated a clean webrev here in case 
anyone else would like to see it:

http://cr.openjdk.java.net/~dholmes/8203469/webrev.v06_2/

I'll take another look through this morning.

David
-----

>> More below ...
>>> But there is a 'better' way.
>>> Before I added the more graceful "_vm_wait->wait();" semaphore in the 
>>> while
>>> (_waiting_to_block > 0) { loop, it was a just a busy spin using the same
>>
>> I think I've lost track of the changes here. Initially we waited on 
>> the _safepoint_lock; then in preview_13 we switched to polling with 
>> backoff. Not sure when _vm_wait->wait was introduced but we're now 
>> returning to polling with backoff. Is that right?
> 
> Yes.
> 
>>
>> Once the VMThread polls until all threads are known to be 
>> safepoint-safe we eliminate a whole category of race conditions with 
>> the thread-state changes that allows us to simplify those thread-state 
>> changes.
> 
> Yes.
> 
>>
>>> back-off as the rolling forward loop. It turns out that we mostly 
>>> never spin
>>> here at all, when all java threads are stop the callbacks is often 
>>> already done.
>>> So the addition of the semaphore have no impact on our benchmarks and 
>>> is mostly
>>> unused. This is because most threads are in java which we need to 
>>> spin-wait
>>> since they can elide into native without doing a callback. My 
>>> proposed re-base
>>> removes the the callbacks completely and let the vm thread do all thread
>>> accounting. All that the stopping threads needs to do is write state and
>>> safepoint id, everything else is handle by the vm thread. We trade 2 
>>> atomics +
>>> a local store per thread against doing 2 stores per thread by the vm 
>>> thread.
>>> This makes it possible for a thread in vm to transition into blocked 
>>> WITHOUT
>>> safepoint poll. Just set thread_blocked and promise to do safepoint 
>>> poll when
>>> leaving that state.
>>
>> Right - but you've only implemented that for the new 
>> ThreadBlockInVMWithDeadlockCheck, though the same argument applies to 
>> the regular TBIVM. We can/should re-examine TBIVM logic, and see if we 
>> can simplify and combine with new ThreadBlockInVMWithDeadlockCheck. 
>> Future RFE.
> 
> Yes!
> 
>>
>> Aside: from a safepoint perspective I really don't see any difference 
>> between going out to "native" and going out to a (potentially) 
>> "blocking" library call. There are both safepoint-safe and should have 
>> the same requirements as you exit and enter the VM.
> 
> Yes.
> 
>>
>>> v06_2
>>> Full:
>>> http://cr.openjdk.java.net/~rehn/8203469/v06_2/full/
>>> Inc against v05:
>>> http://cr.openjdk.java.net/~rehn/8203469/v06_2/inc/
>>> Inc against v06_1:
>>> http://cr.openjdk.java.net/~rehn/8203469/v06_2/rebase_inc/
>>>
>>> v06_2 simplifies and removes ~200 LOC with same performance.
>>> If there is a case with a thread in vm taking long time, it will already
>>> screw-up latency and thus should be fixed regardless of v06_1 vs 
>>> v06_2. So I
>>> see no reason why we should not push v06_2.
>>
>> src/hotspot/share/runtime/interfaceSupport.inline.hpp
>>
>> 317     thread->set_thread_state((JavaThreadState)(_thread_in_vm + 1));
>>
>> Should use _thread_in_vm_trans
>>
>> 326     _thread->set_thread_state((JavaThreadState)(_thread_blocked + 
>> 1));
>>
>> Should use _thread_blocked_trans
> 
> Yes.
> 
>>
>> That said, I'm unclear what role the trans states now play here. 
>> Originally the VMThread had to spin when it saw a trans state because 
>> the final state would determine how the VMThread needed to respond 
>> next. But with the VMThread always spinning I don't see that we 
>> necessarily need the additional complexity. Anyway that too could be 
>> looked at later.
> 
> Yes. Part of the bigger plan is to simplify the states.
> If we ignore the trace_flag (suspend/resume, async exception,..) we 
> could now just have two states, safe and unsafe and you only need to 
> safepoint poll when going to a safe state.
> 
>>
>> I'd like to take one more pass through the full changeset once it has 
>> been generated correctly.
> 
> Thanks, Robbin
> 
>>
>> Thanks,
>> David
>>
>>> Passes stress test and t1-5.
>>>
>>> Thanks, Robbin


More information about the hotspot-dev mailing list