jdk9 VarHandle and Fence methods

Vitaly Davidovich vitalyd at gmail.com
Sat Aug 22 18:24:15 UTC 2015


+1.  StoreLoad is probably not that interesting on its own since that's a
cpu fence even on TSO but LoadStore could be nice as it can be a CPU nop on
some archs.  But yeah, for completeness, it'd be good to have all 4 combos
available.

sent from my phone
On Aug 22, 2015 1:54 PM, "Gil Tene" <gil at azulsystems.com> wrote:

> Its' great to see storeStoreFence() and loadLoadFence() in the Fences
> class.
>
> For completeness, I would really like to see loadStoreFence() and
> storeLoadFence() there as well. I realize that they are implicitly
> available via the combination fences (acquire, release, and full), but it
> is "strange" to have just the first two without providing the complete set.
> There are certainly cases where all you need is a StoreLoad or a LoadStore,
> and forcing the other unneeded fences in combination reduces potential
> compiler optimizations on that code.
>
> — Gil.
>
> > On Aug 21, 2015, at 7:24 AM, Doug Lea <dl at cs.oswego.edu> wrote:
> >
> >
> > For those of you who haven't been following this on the jmm-dev list
> > or follow-ups on concurrency-interest:
> >
> > We are NOT planning a full JMM memory model update for jdk9 -- there
> > are still unresolved issues in revising the formal core model.
> > However, jdk9 will include APIs for VarHandles (a scaled-down version of
> > the "enhanced volatiles" JEP), that together with some other
> > support replaces the need to use of Unsafe to obtain these
> > effects and does so compatibly with C/C++11 atomics. To do this, we
> > must, until the next full JMM update, provide specs that are
> > clear to readers (at least those familiar with the underlying
> > concepts) but not formally tied to a base model, (Which limits
> > how much we can say in them.)
> >
> > The tentative methods are pasted below and also at
> >  http://gee.cs.oswego.edu/dl/wwwtmp/Fodder.java
> > The javadocs currently do not include any examples helping to
> > explain why you would ever want to use any of these methods.
> >
> > The actual VarHandle class will look a bit different because
> > it will rely on specializations of polymorphic signatures.
> > (Current versions can be found in the openjdk mercurial
> > "jdk9/sandbox" repo.) And the "Fences" method may end up
> > in a different java.lang.* utility class. We'd also retrofit
> > j.u.c.atomic.Atomic* classes to use compatible methods/names.
> >
> > Comments welcome.
> >
> > ...
> >
> > /**
> > * Stand-in for spec purposes of jdk9 java.lang.invoke.VarHandle
> > */
> > abstract class NotReallyVarHandle<T> {
> >    // Load
> >
> >    /**
> >     * Returns the value, with memory semantics of reading a
> >     * non-volatile variable.
> >     *
> >     * @return the value
> >     */
> >    T getRelaxed(Object owner);
> >
> >    /**
> >     * Returns the value, with memory semantics of reading a volatile
> >     * variable.
> >     *
> >     * @return the value
> >     */
> >    T getVolatile(Object owner);
> >
> >    /**
> >     * Returns the value, and ensures that subsequent loads and stores
> >     * are not reordered before this access.
> >     *
> >     * @apiNote Ignoring the many semantic differences from C and
> >     * C++, this method has memory ordering effects compatible with
> >     * memory_order_acquire ordering.
> >     *
> >     * @return the value
> >     */
> >    T getAcquire(Object owner);
> >
> >    /**
> >     * Returns the value, accessed in program order, but with no
> >     * assurance of memory ordering effects with respect to other
> >     * threads.
> >     *
> >     * @return the value
> >     */
> >    T getOpaque(Object owner);
> >
> >    // Store
> >
> >    /**
> >     * Sets the value, with memory semantics of setting a non-volatile
> >     * variable.
> >     *
> >     * @param val the new value
> >     */
> >    void setRelaxed(Object owner, T val);
> >
> >    /**
> >     * Sets the value, with memory semantics of setting a volatile
> >     * variable.
> >     *
> >     * @apiNote Ignoring the many semantic differences from C and
> >     * C++, this method has memory ordering effects compatible with
> >     * memory_order_seq_cst.
> >     *
> >     * @param val the new value
> >     */
> >    void setVolatile(Object owner, T val);
> >
> >    /**
> >     * Sets the value, and ensures that prior loads and stores are not
> >     * reordered after this access.
> >     *
> >     * @apiNote Ignoring the many semantic differences from C and
> >     * C++, this method has memory ordering effects compatible with
> >     * memory_order_release ordering.
> >     *
> >     * @param val the new value
> >     */
> >    void setRelease(Object owner, T val);
> >
> >    /**
> >     * Sets the value, in program order, but with no assurance of
> >     * memory ordering effects with respect to other threads.
> >     *
> >     * @param val the new value
> >     */
> >    void setOpaque(Object owner, T val);
> >
> >    // CAS
> >
> >    /**
> >     * Atomically sets the value to the given updated value with the
> >     * memory semantics of setVolatile if the current value {@code ==}
> >     * the expected value, as accessed with the memory semantics of
> >     * getVolatile.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return {@code true} if successful. False return indicates that
> >     * the actual value was not equal to the expected value.
> >     */
> >    boolean compareAndSet(Object owner, T expected, T val);
> >
> >    // Value-returning compare and exchange
> >
> >    /**
> >     * Atomically sets the value to the given updated value with the
> >     * memory semantics of setVolatile if the current value {@code ==}
> >     * the expected value, as accessed with the memory semantics of
> >     * getVolatile.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return the current value, which will be the same as {@code val} if
> >     * successful.
> >     */
> >    T compareAndExchangeVolatile(Object owner, T expected, T val);
> >
> >    /**
> >     * Atomically sets the value to the given updated value with the
> >     * memory semantics of setRelaxed if the current value {@code ==}
> >     * the expected value, as accessed with the memory semantics of
> >     * getAcquire.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return the current value, which will be the same as {@code val} if
> >     * successful.
> >     */
> >    T compareAndExchangeAcquire(Object owner, T expected, T val);
> >
> >    /**
> >     * Atomically sets the value to the given updated value with the
> >     * memory semantics of setRelease if the current value {@code ==}
> >     * the expected value, as accessed with the memory samantics of
> >     * getRelease.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return the current value, which will be the same as {@code val} if
> >     * successful.
> >     */
> >    T compareAndExchangeRelease(Object owner, T expected, T val);
> >
> >    // Weak (spurious failures allowed)
> >
> >    /**
> >     * Possibly atomically sets the value to the given updated value
> >     * with the semantics of setRelaxed if the current value {@code
> >     * ==} the expected value, as as accessed with the memory
> >     * semantics of getRelaxed.  This operation may fail spuriously
> >     * (typically, due to memory contention) even if the current value
> >     * does match the expected value.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return {@code true} if successful
> >     */
> >    boolean weakCompareAndSetRelaxed(Object owner, T expected, T val);
> >
> >    /**
> >     * Possibly atomically sets the value to the given updated value
> >     * with the memory semantics of setRelaxed if the current value
> >     * {@code ==} the expected value, as as accessed with the memory
> >     * semantics of getAcquire.  This operation may fail spuriously
> >     * (typically, due to memory contention) even if the current value
> >     * does match the expected value.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return {@code true} if successful
> >     */
> >    boolean weakCompareAndSetAcquire(Object owner, T expected, T val);
> >
> >    /**
> >     * Possibly atomically sets the value to the given updated value
> >     * with the memory semantics of setRelease if the current value
> >     * {@code ==} the expected value, as as accessed with the memory
> >     * semantics of getRelaxed.  This operation may fail spuriously
> >     * (typically, due to memory contention) even if the current value
> >     * does match the expected value.
> >     *
> >     * @param expected the expected value
> >     * @param val the new value
> >     * @return {@code true} if successful
> >     */
> >    boolean weakCompareAndSetRelease(Object owner, T expected, T val);
> >
> >    // special RMW
> >
> >    /**
> >     * Atomically sets to the given value with the memory semantics of
> >     * setVolatile and returns the old value.
> >     *
> >     * @param newValue the new value
> >     * @return the previous value
> >     */
> >    T getAndSet(Object owner, T val);
> >
> >    /**
> >     * Atomically adds the given value to the current value with the
> >     * memory semantics of setVolatile.
> >     *
> >     * @param delta the value to add
> >     * @return the previous value
> >     */
> >    T getAndAdd(Object owner, T delta);
> >
> >    /**
> >     * Atomically adds the given value to the current value with the
> >     * memory semantics of setVolatile.
> >     *
> >     * @param delta the value to add
> >     * @return the current value
> >     */
> >    T addAndGet(Object owner, T delta);
> > }
> >
> > /**
> > * 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 arising 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 semantic 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 semantic 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 semantic 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 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 valhalla-dev mailing list