RFR: 8267079: Support async handshakes that can be executed by a remote thread [v2]
Robbin Ehn
rehn at openjdk.java.net
Fri May 21 06:29:27 UTC 2021
On Fri, 21 May 2021 02:55:00 GMT, Man Cao <manc at openjdk.org> wrote:
> Re Robin's comment:
>
> > This line is just confusing, the requesting thread only enters a safepoint if it's a JavaThread.
> > ...
> > Not sure if this epoch sync is run by a thread part of SuspendibleThreadSet or not, but:
>
> Yes it is confusing. Let me clarify the problem.
>
> The epoch sync is requested by either a G1 refinement thread, which is a part of SuspendibleThreadSet; or a Java thread from its post-write barrier's slow path, which is a JRT_LEAF function that forbids any operation that can safepoint. G1 by design supports concurrent refinement from a Java thread's post-write barrier, if there's too many cards to refine, see G1DirtyCardQueueSet::handle_completed_buffer().
>
> I could get the epoch sync working using synchronous handshake when requesting thread == G1 refinement thread, by leaving SuspendibleThreadSet and redirtying some pending cards before calling Handshake::execute(). However, it does not work for the requesting thread == Java thread case, due to the JRT_LEAF constraint. This is the reason for proposing to use Handshake::enqueue() and support executing them from non-self threads.
>
> > If it is; it is just prolonging the time to safepoint, which is a free epoch, thus finishing the epoch just wastes CPU.
>
> Good point. I'll make sure any waiting in the epoch sync protocol also checks for pending safepoint and yields.
>
> Anyway, I think the arm-the-poll-only approach is superior and it does not need to issue any handshake. I will look into that instead.
If someone keeps suspending ad resuming a thread the thread might always have the poll armed and always have a handshake.
Just looking if queue is empty or not, or poll is armed or not can have pathological cases.
If you add an epoch counter into Thread::gc_data_offset you could update it by putting a line next cross-mod-fence:
`
void SafepointMechanism::process_if_requested_slow(JavaThread *thread) {
...
OrderAccess::cross_modify_fence();
Universe::heap()->barrier_complete(thread); // store global epoch to GCThreadLocalData
}
`
But as David said, you basically trying to handshake without a handshake :)
(should try to put the counter inside the handshake instead)
-------------
PR: https://git.openjdk.java.net/jdk/pull/4005
More information about the hotspot-dev
mailing list