[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