JEP 312: Thread-Local Handshakes

OwnerRobbin Ehn
TypeFeature
ScopeJDK
StatusClosed / Delivered
Release10
Componenthotspot / runtime
Discussionhotspot dash dev at openjdk dot java dot net
BlocksJEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
Reviewed byMikael Vidstedt
Endorsed byMikael Vidstedt
Created2017/08/01 13:30
Updated2019/08/21 10:41
Issue8185640

Summary

Introduce a way to execute a callback on threads without performing a global VM safepoint. Make it both possible and cheap to stop individual threads and not just all threads or none.

Non-Goals

It may not be feasible to implement this efficiently on all supported architectures. It is initially not a goal to support all processor architectures and all versions of processor architectures.

Success metrics

Motivation

Being able to stop individual threads has a multitude of applications:

All of these will help the VM achieve lower latency by reducing the number of global safepoints.

Description

A handshake operation is a callback that is executed for each JavaThread while that thread is in a safepoint safe state. The callback is executed either by the thread itself or by the VM thread while keeping the thread in a blocked state. The big difference between safepointing and handshaking is that the per thread operation will be performed on all threads as soon as possible and they will continue to execute as soon as it’s own operation is completed. If a JavaThread is known to be running, then a handshake can be performed with that single JavaThread as well.

In the initial implementation there will be a limitation of at most one handshake operation in flight at a given time. The operation can, however, involve any subset of all JavaThreads. The VM thread will coordinate the handshake operation through a VM operation which will in effect prevent global safepoints from occurring during the handshake operation.

The current safepointing scheme is modified to perform an indirection through a per-thread pointer which will allow a single thread's execution to be forced to trap on the guard page. Essentially, at all times there will be two polling pages: One which is always guarded, and one which is always unguarded. In order to force a thread to yield, the VM updates the per-thread pointer for the corresponding thread to point to the guarded page.

Thread-local handshakes will be implemented initially on x64 and SPARC. Other platforms will fall back to normal safepoints. A new product option, -XX:ThreadLocalHandshakes (default value true), allows users to select normal safepoints on supported platforms.

Alternatives

Multiple alternatives were considered: