[jmm-dev] jdk9 APIs

Jeremy Manson jeremymanson at google.com
Tue Aug 11 18:01:58 UTC 2015


Just curious: which end users are jonesing for a Fences API?  I talk with a
LOT of Java users, and it's *never* come up outside of the kinds of people
on this list.

What's the urgency now?

Jeremy

On Mon, Aug 10, 2015 at 11:22 AM, Doug Lea <dl at cs.oswego.edu> wrote:

> It's been a while...
>
> As everyone has surely noticed, progress on revising the core Java
> Memory Model stalled after discovering that some new ideas are needed
> to deal with out-of-thin-air and related issues in both Java and
> C/C++.  Some people are pursuing promising approaches, but there is
> little chance that a full reformulation will be ready before jdk9 is
> released (about a year from now).
>
> However, despite this, jdk9 will include access and fence APIs that
> need specs. This is non-negotiable, because the current weird way of
> accessing the (mostly existing) underlying JVM functionality via
> sun.misc.Unsafe is going away. (Actually, planned to only partly go
> away in jdk9, but also introducing classes/methods allowing future
> decomission.)
>
> For accesses (mostly) corresponding to C11 atomics with memory_order,
> the alternatives reside in "VarHandles". These are more-or-less
> similar to AtomicXFieldUpdaters, but are designed to support
> generation of much better code (without dynamic/reflective baggage),
> generally as good as handcrafting, at least after warmup. The setup
> for them is unusual -- relying on just-in-time specialization of
> generic wrappers.  This is a scale-down in ambition compared to the
> original "enhanced volatiles" proposal that would have required
> language syntax changes that met opposition.
>
> Plans are to also include a stand-alone Fences class with all-static
> methods. (Deja vu for many of us.) Plus to separately add the
> reachabilityFence/keepAlive method discussed last year as a static
> method most likely in class java.lang.ref.Reference.
>
> There seems to be only a little room for discussion on the exact sets
> of methods in the VarHandle* and Fences classes:
>
> Current versions of VarHandle do NOT include an analog of C11
> "consume" mode. As discussed last year, considering its uncertain fate
> in C/C++, a better tactic might be to support a method of the form
> "getDependently(ref)" (sorta like in the linux kernel) that covers its
> {only? main?} use case. But for now omitted.
>
> For Fences, adding plain StoreStore and LoadLoad fences to the set
> acquireFence, ReleaseFence, and fullFence seems wise.  The main
> arguments against LoadLoad and StoreStore in C11 were usability
> concerns. But they have been found to be useful enough internally to
> JVMs (mainly on ARM) to be semi-supported within hotspot. And we'd
> like to not keep making the same mistake of unnecessarily making
> things ARM/POWER hostile.
>
> But the main issue at hand is how we can provide library specs for the
> APIs without revising the underlying Java Memory Model.
>
> My proposal is that we muddle through.  Doing so seems surprisingly
> workable: Moded accesses and fences allow programmers to rule out some
> behaviors. Specifying them need not spell out underlying rules that
> hold when these methods are not used. And on the other side, they need
> not promise any overall property (as in: it might be the case that
> using a fullFence between every access gives you SC, but we don't need
> to guarantee it.) It is in a sense cheating to convey this in method
> specs by using terms that are not fully backed by a formal underlying
> model. But they still can be made good enough for readers to
> understand intent, and made more rigorous someday. We can and should
> also comfort programmers that, when applicable, the primary effects
> of these methods are compatible with C/C++.  Given all this, the
> specs can be pretty simple. They are done out for Fences below, and
> if OK should not be hard to apply to VarHandle methods.
>
> Other ideas are of course welcome.
>
> Pasted below are preliminary versions. If they don't format
> nicely in your mail reader, get them at
>   http://gee.cs.oswego.edu/dl/wwwtmp/Fodder.java
>
>
>
> /**
>  * A set of methods providing fine-grained control of memory ordering.
>  *
>  * <p>The Java Language Specification permits operations to be
>  * executed in orders different than are apparent in program source
>  * code, subject to constraints mainly stemming from the use of locks
>  * and volatile fields. The methods of this class can also be used to
>  * impose constraints. Their specifications are phrased in terms of
>  * the lack of "reorderings" -- observable ordering effects that might
>  * otherwise occur if the fence were not present.
>  *
>  * @apiNote More precise phrasing of these specifications may
>  * accompany future updates of the Java Language Specification.
>  */
> public class Fences {
>
>     /**
>      * Ensures that loads and stores before the fence will not be
>      * reordered with loads and stores after the fence.
>      *
>      * @apiNote Ignoring the many semantics differences from C and
>      * C++, this method has memory ordering effects compatible with
>      * atomic_thread_fence(memory_order_seq_cst)
>      */
>     public static void fullFence() {}
>
>     /**
>      * Ensures that loads before the fence will not be reordered with
>      * loads and stores after the fence.
>      *
>      * @apiNote Ignoring the many semantics differences from C and
>      * C++, this method has memory ordering effects compatible with
>      * atomic_thread_fence(memory_order_acquire)
>      */
>     public static void acquireFence() {}
>
>     /**
>      * Ensures that loads and stores before the fence will not be
>      * reordered with stores after the fence.
>      *
>      * @apiNote Ignoring the many semantics differences from C and
>      * C++, this method has memory ordering effects compatible with
>      * atomic_thread_fence(memory_order_release)
>      */
>     public static void releaseFence() {}
>
>     /**
>      * Ensures that loads before the fence will not be reordered with
>      * loads after the fence.
>      */
>     public static void loadLoadFence() {}
>
>     /**
>      * Ensures that stores before the fence will not be reordered with
>      * stores after the fence.
>      */
>     public static void storeStoreFence() {}
>
>
> }
>
> class sample VHUsages {
>     int aField;
>     static Varhandle AFIELD = ...;
>     void usage1() {
>         int aFieldValue = AFIELD.getVolatile(this);
>     }
> }
>
> /**
>  * Stand-in for spec purposes of jdk9 java.lang.invoke.VarHandle
>  */
> abstract class NotReallyVarHandle<T> {
>     // Load
>
>     T getRelaxed(Object owner);
>     T getAcquire(Object owner);
>     T getVolatile(Object owner);
>     // tbd: Consume analog
>
>     // Store
>
>     void setRelaxed(Object owner, T val);
>     void setRelease(Object owner, T val);
>     void setVolatile(Object owner, T val);
>
>     // CAS
>
>     boolean compareAndSet(Object owner, T cmp, T val);
>     boolean compareAndSetAcquire(Object owner, T cmp, T val);
>     boolean compareAndSetRelease(Object owner, T cmp, T val);
>
>     boolean weakCompareAndSet(Object owner, T cmp, T val);
>     boolean weakCompareAndSetAcquire(Object owner, T cmp, T val);
>     boolean weakCompareAndSetRelease(Object owner, T cmp, T val);
>
>     // special RMW
>
>     T getAndSet(Object owner, T val);
>     T getAndAdd(Object owner, T delta);
>     T addAndGet(Object owner, T delta);
> }
>
> class java.lang.ref.Reference {
>     // add:
>
>     /**
>      * Ensures that the object referenced by the given reference
>      * remains <em>strongly reachable</em> (as defined in the {@link
>      * java.lang.ref} package documentation), regardless of any prior
>      * actions of the program that might otherwise cause the object to
>      * become unreachable; thus, the referenced object is not
>      * reclaimable by garbage collection at least until after the
>      * invocation of this method. Invocation of this method does not
>      * itself initiate garbage collection or finalization.
>      *
>      * @param ref the reference. If null, this method has no effect.
>      */
>     public static void reachabilityFence(Object ref) {}
>
> }
>


More information about the jmm-dev mailing list