Draft JEP on enhanced volatiles

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