Draft JEP on enhanced volatiles (original) (raw)

Doug Lea dl at cs.oswego.edu
Fri Feb 7 10:37:01 PST 2014


[To core-libs-dev; separately cross-posted to hotspot-dev and compiler-dev.]

Now that the JMM update project is live (see http://openjdk.java.net/projects/jmm/), it would be helpful to get some preliminary feedback on one of its sure-to-be-needed counterparts: finally supporting a reasonable way to express atomic and/or ordered access operations beyond volatile-read/write. Some of you might know that the lack of these has often been discusses as a source of frustration and problems. One reason for nopt dealing with it sooner is the lack of a basis for even specifying such things, to be fixed with JMM update. But we also need some way for people to express them. The only good means for doing so appear to require a small amount of syntax support. Most people who have seen it seem to agree that the ".volatile" proposal below is the approach most likely to succeed. (We've considered a lot of others.) I'm hoping that members of libs, hotspot, and compiler groups can give it a sanity check before submitting (hopefully in a week or so). Thanks!

Draft JEP proposal Title: Enhanced Volatiles Author: Doug Lea [...other metadata elided for now...]

Summary

This JEP results in a means for programmers to invoke the equivalents of java.util.concurrent.atomic methods on volatile fields.

Motivation

As concurrent and parallel programming in Java continue to expand, programmers are increasingly frustrated by not being able to use Java constructions for arranging atomic operations for the fields of individual classes; for example atomically incrementing a "count" field. Until now the only ways to achieve these effects were to use a stand-alone AtomicInteger (adding both space overhead and additional concurrency issues to manage indirection) or, in some situations, to use atomic FieldUpdates (often encountering more overhead than the operation itself), or to use JVM Unsafe intrinsics. Because intrinsics are preferable on performance grounds, their use has been increasingly common, to the detriment of safety and portability. Without this JEP, these problems are expected to become worse as atomic APIs expand to cover additional access consistency policies (aligned with the recent C++11 memory model) as part of Java Memory Model revisions.

Description

The target solution requires a syntax enhancement, a few library enhancements, and compiler support.

We model the extended operations on volatile integers via an interface VolatileInt, that also captures the functionality of AtomicInteger (which will also be updated to reflect Java Memory Model revisions as part of this JEP). A tentative version is below. Similar interfaces are needed for other primitive and reference types.

We then enable access to corresponding methods for (typically volatile) fields using the ".volatile" prefix. For example:

 class Usage {
     volatile int count;
     int incrementCount() {
         return count.volatile.incrementAndGet();
     }
 }

The ".volatile" syntax is slightly unusual, but we are confident that it is syntactically unambiguous and semantically specifiable. New syntax is required to avoid ambiguities with existing usages, especially for volatile references -- invocations of methods on the reference versus the referent would be indistinguishable. The ".volatile" prefix introduces a scope for operations on these "L-values", not their retrieved contents. However, just using the prefix itself without a method invocation (as in "count.volatile;") would be meaningless and illegal. We also expect to allow volatile operations on array elements in addition to fields.

The main task is to translate these calls into corresponding JVM intrinsics. The most likely option is for the source compiler to use method handles. This and other techniques are known to suffice, but are subject to further exploration. Minor enhancements to intrinsics and a few additional JDK library methods may also be needed.

Here is a tentative VolatileInt interface. Those for other types are similar. The final released versions will surely differ in small ways.

 interface VolatileInt {
     int get();
     int getRelaxed();
     int getAcquire();
     int getSequential();

     void set(int x);
     void setRelaxed(int x);
     void setRelease(int x);
     void setSequential(int x);

     int getAndSet(int x);
     boolean compareAndSet(int e, int x);
     boolean compareAndSetAcquire(int e, int x);
     boolean compareAndSetRelease(int e, int x);
     boolean weakCompareAndSet(int e, int x);
     boolean weakCompareAndSetAcquire(int e, int x);
     boolean weakCompareAndSetRelease(int e, int x);

     int getAndAdd(int x);
     int addAndGet(int x);
     int getAndIncrement();
     int incrementAndGet();
     int getAndDecrement();
     int decrementAndGet();
 }

Alternatives

We considered instead introducing new forms of "value type" that support volatile operations. However, this would be inconsistent with properties of other types, and would also require more effort for programmers to use. We also considered expanding reliance on java.util.concurrent.atomic FieldUpdaters, but their dynamic overhead and usage limitations make them unsuitable. Several other alternatives (including those based on field references) have been raised and dismissed as unworkable on syntactic, efficiency, and/or usability grounds over the many years that these issues has been discussed.

Risks and Assumptions

We are confident of feasibility. However, we expect that it will require more experimentation to arrive at compilation techniques that result in efficient enough implementation for routine use in the performance-critical contexts where these constructs are most often needed. The use of method handles may be impacted by and may impact JVM method handle support.

Impact

A large number of usages in java.util.concurrent (and a few elsewhere in JDK) could be simplified and updated to use this support.



More information about the hotspot-dev mailing list