[jmm-dev] Enhanced Volatiles
Doug Lea
dl at cs.oswego.edu
Wed Feb 19 05:54:00 PST 2014
Just as an FYI, I submitted the JEP pasted below, that includes
a few small updates reflecting feedback on openjdk lists.
...
Title: Enhanced Volatiles
Author: Doug Lea
Organization: SUNY Oswego
Created: 2014/01/06
Type: Feature
State: Draft
Exposure: Open
Component: core/libs core/lang vm/rt
Scope: JDK
Discussion: core-libs-dev at openjdk.java.net compiler-dev at openjdk.java.net
hotspot-dev at openjdk.java.net
Start: 2014/Q1
Depends: JEP-188
Effort: M
Duration: L
Template: 1.0
Reviewed-by:
Endorsed-by: Brian Goetz
Summary
-------
This JEP results in a means for programmers to invoke the equivalents
of java.util.concurrent.atomic methods on object 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 or ordered 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 FieldUpdaters (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 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. Enforcement of
semantic restrictions (for example attempted usages for "final"
fields) will require compiler support.
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, subject
to the results of JEP-188.
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();
}
This proposal focuses on the control of atomicity and ordering for
single variables. We expect the resulting specifications to be
amenable for extension in natural ways for additional primitive-like
value types, if they are ever defined for Java. However, it is not a
general-purpose transaction mechanism for controlling accesses and
updates to multiple variables. Alternative forms for expressing and
implementing such constructions may be explored in the course of this
JEP, and may be the subject of further JEPs.
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 have 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 jmm-dev
mailing list