[cvs] / jsr166 / src / jsr166e / Fences.java Repository:
ViewVC logotype

View of /jsr166/src/jsr166e/Fences.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (download) (annotate)
Fri Nov 18 20:36:28 2016 UTC (10 months, 4 weeks ago) by dl
Branch: MAIN
CVS Tags: HEAD
Move never-released Fences
/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

package jsr166e;

/**
 * <b>This file exists for documentation reference but is not part of
 * any planned release.</b>
 *
 * <p>A set of methods providing fine-grained control over happens-before
 * and synchronization order relations among reads and/or writes.  The
 * methods of this class are designed for use in uncommon situations
 * where declaring variables {@code volatile} or {@code final}, using
 * instances of atomic classes, using {@code synchronized} blocks or
 * methods, or using other synchronization facilities are not possible
 * or do not provide the desired control.
 *
 * <p><b>Memory Ordering.</b> There are three methods for controlling
 * ordering relations among memory accesses (i.e., reads and
 * writes). Method {@code orderWrites} is typically used to enforce
 * order between two writes, and {@code orderAccesses} between a write
 * and a read.  Method {@code orderReads} is used to enforce order
 * between two reads with respect to other {@code orderWrites} and/or
 * {@code orderAccesses} invocations.  The formally specified
 * properties of these methods described below provide
 * platform-independent guarantees that are honored by all levels of a
 * platform (compilers, systems, processors).  The use of these
 * methods may result in the suppression of otherwise valid compiler
 * transformations and optimizations that could visibly violate the
 * specified orderings, and may or may not entail the use of
 * processor-level "memory barrier" instructions.
 *
 * <p>Each ordering method accepts a {@code ref} argument, and
 * controls ordering among accesses with respect to this reference.
 * Invocations must be placed <em>between</em> accesses performed in
 * expression evaluations and assignment statements to control the
 * orderings of prior versus subsequent accesses appearing in program
 * order. These methods also return their arguments to simplify
 * correct usage in these contexts.
 *
 * <p>Usages of ordering methods almost always take one of the forms
 * illustrated in the examples below.  These idioms arrange some of
 * the ordering properties associated with {@code volatile} and
 * related language-based constructions, but without other
 * compile-time and runtime benefits that make language-based
 * constructions far better choices when they are applicable.  Usages
 * should be restricted to the control of strictly internal
 * implementation matters inside a class or package, and must either
 * avoid or document any consequent violations of ordering or safety
 * properties expected by users of a class employing them.
 *
 * <p><b>Reachability.</b> Method {@code reachabilityFence}
 * establishes an ordering for strong reachability (as defined in the
 * {@link java.lang.ref} package specification) with respect to
 * garbage collection.  Method {@code reachabilityFence} differs from
 * the others in that it controls relations that are otherwise only
 * implicit in a program -- the reachability conditions triggering
 * garbage collection.  As illustrated in the sample usages below,
 * this method is applicable only when reclamation may have visible
 * effects, which is possible for objects with finalizers (see Section
 * 12.6 of the Java Language Specification) that are implemented in
 * ways that rely on ordering control for correctness.
 *
 * <p><b>Sample Usages</b>
 *
 * <p><b>Safe publication.</b> With care, method {@code orderWrites}
 * may be used to obtain the memory safety effects of {@code final}
 * for a field that cannot be declared as {@code final}, because its
 * primary initialization cannot be performed in a constructor, in
 * turn because it is used in a framework requiring that all classes
 * have a no-argument constructor; as in:
 *
 * <pre> {@code
 * class WidgetHolder {
 *   private Widget widget;
 *   public WidgetHolder() {}
 *   public static WidgetHolder newWidgetHolder(Params params) {
 *     WidgetHolder h = new WidgetHolder();
 *     h.widget = new Widget(params);
 *     return Fences.orderWrites(h);
 *   }
 * }}</pre>
 *
 * Here, the invocation of {@code orderWrites} ensures that the
 * effects of the widget assignment are ordered before those of any
 * (unknown) subsequent stores of {@code h} in other variables that
 * make {@code h} available for use by other objects.  Initialization
 * sequences using {@code orderWrites} require more care than those
 * involving {@code final} fields.  When {@code final} is not used,
 * compilers cannot help you to ensure that the field is set correctly
 * across all usages.  You must fully initialize objects
 * <em>before</em> the {@code orderWrites} invocation that makes
 * references to them safe to assign to accessible variables. Further,
 * initialization sequences must not internally "leak" the reference
 * by using it as an argument to a callback method or adding it to a
 * static data structure.  If less constrained usages were required,
 * it may be possible to cope using more extensive sets of fences, or
 * as a normally better choice, using synchronization (locking).
 * Conversely, if it were possible to do so, the best option would be
 * to rewrite class {@code WidgetHolder} to use {@code final}.
 *
 * <p>An alternative approach is to place similar mechanics in the
 * (sole) method that makes such objects available for use by others.
 * Here is a stripped-down example illustrating the essentials. In
 * practice, among other changes, you would use access methods instead
 * of a public field.
 *
 * <pre> {@code
 * class AnotherWidgetHolder {
 *   public Widget widget;
 *   void publish(Widget w) {
 *     this.widget = Fences.orderWrites(w);
 *   }
 *   // ...
 * }}</pre>
 *
 * In this case, the {@code orderWrites} invocation occurs before the
 * store making the object available. Correctness again relies on
 * ensuring that there are no leaks prior to invoking this method, and
 * that it really is the <em>only</em> means of accessing the
 * published object.  This approach is not often applicable --
 * normally you would publish objects using a thread-safe collection
 * that itself guarantees the expected ordering relations. However, it
 * may come into play in the construction of such classes themselves.
 *
 * <p><b>Safely updating fields.</b> Outside of the initialization
 * idioms illustrated above, Fence methods ordering writes must be
 * paired with those ordering reads. To illustrate, suppose class
 * {@code c} contains an accessible variable {@code data} that should
 * have been declared as {@code volatile} but wasn't:
 *
 * <pre> {@code
 * class C {
 *   Object data;  // need volatile access but not volatile
 *   // ...
 * }
 *
 * class App {
 *   Object getData(C c) {
 *     return Fences.orderReads(c).data;
 *   }
 *
 *   void setData(C c) {
 *     Object newValue = ...;
 *     c.data = Fences.orderWrites(newValue);
 *     Fences.orderAccesses(c);
 *   }
 *   // ...
 * }}</pre>
 *
 * Method {@code getData} provides an emulation of {@code volatile}
 * reads of (non-long/double) fields by ensuring that the read of
 * {@code c} obtained as an argument is ordered before subsequent
 * reads using this reference, and then performs the read of its
 * field. Method {@code setData} provides an emulation of volatile
 * writes, ensuring that all other relevant writes have completed,
 * then performing the assignment, and then ensuring that the write is
 * ordered before any other access.  These techniques may apply even
 * when fields are not directly accessible, in which case calls to
 * fence methods would surround calls to methods such as {@code
 * c.getData()}.  However, these techniques cannot be applied to
 * {@code long} or {@code double} fields because reads and writes of
 * fields of these types are not guaranteed to be
 * atomic. Additionally, correctness may require that all accesses of
 * such data use these kinds of wrapper methods, which you would need
 * to manually ensure.
 *
 * <p>More generally, Fence methods can be used in this way to achieve
 * the safety properties of {@code volatile}. However their use does
 * not necessarily guarantee the full sequential consistency
 * properties specified in the Java Language Specification chapter 17
 * for programs using {@code volatile}. In particular, emulation using
 * Fence methods is not guaranteed to maintain the property that
 * {@code volatile} operations performed by different threads are
 * observed in the same order by all observer threads.
 *
 * <p><b>Acquire/Release management of threadsafe objects</b>. It may
 * be possible to use weaker conventions for volatile-like variables
 * when they are used to keep track of objects that fully manage their
 * own thread-safety and synchronization.  Here, an acquiring read
 * operation remains the same as a volatile-read, but a releasing
 * write differs by virtue of not itself ensuring an ordering of its
 * write with subsequent reads, because the required effects are
 * already ensured by the referenced objects.
 * For example:
 *
 * <pre> {@code
 * class Item {
 *   synchronized f(); // ALL methods are synchronized
 *   // ...
 * }
 *
 * class ItemHolder {
 *   private Item item;
 *   Item acquireItem() {
 *     return Fences.orderReads(item);
 *   }
 *
 *   void releaseItem(Item x) {
 *     item = Fences.orderWrites(x);
 *   }
 *
 *   // ...
 * }}</pre>
 *
 * Because this construction avoids use of {@code orderAccesses},
 * which is typically more costly than the other fence methods, it may
 * result in better performance than using {@code volatile} or its
 * emulation. However, as is the case with most applications of fence
 * methods, correctness relies on the usage context -- here, the
 * thread safety of {@code Item}, as well as the lack of need for full
 * volatile semantics inside this class itself. However, the second
 * concern means that it can be difficult to extend the {@code
 * ItemHolder} class in this example to be more useful.
 *
 * <p><b>Avoiding premature finalization.</b> Finalization may occur
 * whenever a Java Virtual Machine detects that no reference to an
 * object will ever be stored in the heap: A garbage collector may
 * reclaim an object even if the fields of that object are still in
 * use, so long as the object has otherwise become unreachable. This
 * may have surprising and undesirable effects in cases such as the
 * following example in which the bookkeeping associated with a class
 * is managed through array indices. Here, method {@code action}
 * uses a {@code reachabilityFence} to ensure that the Resource
 * object is not reclaimed before bookkeeping on an associated
 * ExternalResource has been performed; in particular here, to ensure
 * that the array slot holding the ExternalResource is not nulled out
 * in method {@link Object#finalize}, which may otherwise run
 * concurrently.
 *
 * <pre> {@code
 * class Resource {
 *   private static ExternalResource[] externalResourceArray = ...
 *
 *   int myIndex;
 *   Resource(...) {
 *     myIndex = ...
 *     externalResourceArray[myIndex] = ...;
 *     ...
 *   }
 *   protected void finalize() {
 *     externalResourceArray[myIndex] = null;
 *     ...
 *   }
 *   public void action() {
 *     try {
 *       // ...
 *       int i = myIndex;
 *       Resource.update(externalResourceArray[i]);
 *     } finally {
 *       Fences.reachabilityFence(this);
 *     }
 *   }
 *   private static void update(ExternalResource ext) {
 *     ext.status = ...;
 *   }
 * }}</pre>
 *
 * Here, the call to {@code reachabilityFence} is nonintuitively
 * placed <em>after</em> the call to {@code update}, to ensure that
 * the array slot is not nulled out by {@link Object#finalize} before
 * the update, even if the call to {@code action} was the last use of
 * this object. This might be the case if for example a usage in a
 * user program had the form {@code new Resource().action();} which
 * retains no other reference to this Resource.  While probably
 * overkill here, {@code reachabilityFence} is placed in a {@code
 * finally} block to ensure that it is invoked across all paths in the
 * method.  In a method with more complex control paths, you might
 * need further precautions to ensure that {@code reachabilityFence}
 * is encountered along all of them.
 *
 * <p>It is sometimes possible to better encapsulate use of
 * {@code reachabilityFence}. Continuing the above example, if it
 * were OK for the call to method update to proceed even if the
 * finalizer had already executed (nulling out slot), then you could
 * localize use of {@code reachabilityFence}:
 *
 * <pre> {@code
 * public void action2() {
 *   // ...
 *   Resource.update(getExternalResource());
 * }
 * private ExternalResource getExternalResource() {
 *   ExternalResource ext = externalResourceArray[myIndex];
 *   Fences.reachabilityFence(this);
 *   return ext;
 * }}</pre>
 *
 * <p>Method {@code reachabilityFence} is not required in
 * constructions that themselves ensure reachability. For example,
 * because objects that are locked cannot in general be reclaimed, it
 * would suffice if all accesses of the object, in all methods of
 * class Resource (including {@code finalize}) were enclosed in {@code
 * synchronized (this)} blocks. (Further, such blocks must not include
 * infinite loops, or themselves be unreachable, which fall into the
 * corner case exceptions to the "in general" disclaimer.) However,
 * method {@code reachabilityFence} remains a better option in cases
 * where this approach is not as efficient, desirable, or possible;
 * for example because it would encounter deadlock.
 *
 * <p><b>Formal Properties.</b>
 *
 * <p>Using the terminology of The Java Language Specification chapter
 * 17, the rules governing the semantics of the methods of this class
 * are as follows:
 *
 * <p>The following is still under construction.
 *
 * <dl>
 *
 *   <dt><b>[Definitions]</b>
 *   <dd>
 *   <ul>
 *
 *     <li>Define <em>sequenced(a, b)</em> to be true if <em>a</em>
 *     occurs before <em>b</em> in <em>program order</em>.
 *
 *     <li>Define <em>accesses(a, p)</em> to be true if
 *     <em>a</em> is a read or write of a field (or if an array, an
 *     element) of the object referenced by <em>p</em>.
 *
 *     <li>Define <em>deeplyAccesses(a, p)</em> to be true if either
 *     <em>accesses(a, p)</em> or <em>deeplyAccesses(a, q)</em> where
 *     <em>q</em> is the value seen by some read <em>r</em>
 *     such that <em>accesses(r, p)</em>.
 *
 *   </ul>
 *   <dt><b>[Matching]</b>
 *   <dd>Given:
 *
 *   <ul>
 *
 *     <li><em>p</em>, a reference to an object
 *
 *     <li><em>wf</em>, an invocation of {@code orderWrites(p)} or
 *       {@code orderAccesses(p)}
 *
 *     <li><em>w</em>, a write of value <em>p</em>
 *
 *     <li><em>rf</em>, an invocation of {@code orderReads(p)} or
 *     {@code orderAccesses(p)}
 *
 *     <li><em>r</em>, a read returning value <em>p</em>
 *
 *   </ul>
 *   If:
 *   <ul>
 *     <li>sequenced(wf, w)
 *     <li>read <em>r</em> sees write <em>w</em>
 *     <li>sequenced(r, rf)
 *   </ul>
 *   Then:
 *   <ul>
 *
 *     <li><em>wf happens-before rf</em>
 *
 *     <li><em>wf</em> precedes <em>rf</em> in the
 *          <em>synchronization order</em>
 *
 *     <li>If (<em>r1</em>, <em>w1</em>) and (<em>r2</em>,
 *     <em>w2</em>) are two pairs of reads and writes, both
 *     respectively satisfying the above conditions for <em>p</em>,
 *     and sequenced(r1, r2) then it is not the case that <em>w2
 *     happens-before w1</em>.
 *
 *   </ul>
 *   <dt><b>[Initial Reads]</b>
 *   <dd>Given:
 *
 *   <ul>
 *
 *     <li><em>p</em>, a reference to an object
 *
 *     <li><em>a</em>, an access where deeplyAccesses(a, p)
 *
 *     <li><em>wf</em>, an invocation of {@code orderWrites(p)} or
 *       {@code orderAccesses(p)}
 *
 *     <li><em>w</em>, a write of value <em>p</em>
 *
 *     <li><em>r</em>, a read returning value <em>p</em>
 *
 *     <li><em>b</em>, an access where accesses(b, p)
 *
 *   </ul>
 *   If:
 *   <ul>
 *     <li>sequenced(a, wf);
 *     <li>sequenced(wf, w)
 *     <li>read <em>r</em> sees write <em>w</em>, and
 *         <em>r</em> is the first read by some thread
 *         <em>t</em> that sees value <em>p</em>
 *     <li>sequenced(r, b)
 *   </ul>
 *   Then:
 *   <ul>
 *     <li>the effects of <em>b</em> are constrained
 *          by the relation <em>a happens-before b</em>.
 *   </ul>
 *  <dt><b>[orderAccesses]</b>
 *  <dd>Given:
 *
 *   <ul>
 *     <li><em>p</em>, a reference to an object
 *     <li><em>f</em>, an invocation of {@code orderAccesses(p)}
 *   </ul>
 *   If:
 *   <ul>
 *     <li>sequenced(f, w)
 *   </ul>
 *
 *    Then:
 *
 *   <ul>
 *
 *     <li><em>f</em> is an element of the <em>synchronization order</em>.
 *
 *   </ul>
 *   <dt><b>[Reachability]</b>
 *   <dd>Given:
 *
 *   <ul>
 *
 *     <li><em>p</em>, a reference to an object
 *
 *     <li><em>f</em>, an invocation of {@code reachabilityFence(p)}
 *
 *     <li><em>a</em>, an access where accesses(a, p)
 *
 *     <li><em>b</em>, an action (by a garbage collector) taking
 *     the form of an invocation of {@code
 *     p.finalize()} or of enqueuing any {@link
 *     java.lang.ref.Reference} constructed with argument <em>p</em>
 *
 *   </ul>
 *
 *   If:
 *   <ul>
 *     <li>sequenced(a, f)
 *   </ul>
 *
 *    Then:
 *
 *   <ul>
 *
 *     <li><em>a happens-before b</em>.
 *
 *   </ul>
 *
 * </dl>
 *
 * @since 1.7
 * @author Doug Lea
 */
public class Fences {
    private Fences() {} // Non-instantiable

    /**
     * The methods of this class are intended to be intrinisified by a
     * JVM. However, we provide correct but inefficient Java-level
     * code that simply reads and writes a static volatile
     * variable. Without JVM support, the consistency effects are
     * stronger than necessary, and the memory contention effects can
     * be a serious performance issue.
     */
    private static volatile int theVolatile;

    /**
     * Informally: Ensures that a read of the given reference prior to
     * the invocation of this method occurs before a subsequent use of
     * the given reference with the effect of reading or writing a
     * field (or if an array, element) of the referenced object.  The
     * use of this method is sensible only when paired with other
     * invocations of {@link #orderWrites} and/or {@link
     * #orderAccesses} for the given reference. For details, see the
     * class documentation for this class.
     *
     * @param ref the reference. If null, this method has no effect.
     * @param <T> the type of the reference
     * @return the given ref, to simplify usage
     */
    public static <T> T orderReads(T ref) {
        int ignore = theVolatile;
        return ref;
    }

    /**
     * Informally: Ensures that a use of the given reference with the
     * effect of reading or writing a field (or if an array, element)
     * of the referenced object, prior to the invocation of this
     * method occur before a subsequent write of the reference. For
     * details, see the class documentation for this class.
     *
     * @param ref the reference. If null, this method has no effect.
     * @param <T> the type of the reference
     * @return the given ref, to simplify usage
     */
    public static <T> T orderWrites(T ref) {
        theVolatile = 0;
        return ref;
    }

    /**
     * Informally: Ensures that accesses (reads or writes) using the
     * given reference prior to the invocation of this method occur
     * before subsequent accesses.  For details, see the class
     * documentation for this class.
     *
     * @param ref the reference. If null, this method has no effect.
     * @param <T> the type of the reference
     * @return the given ref, to simplify usage
     */
    public static <T> T orderAccesses(T ref) {
        theVolatile = 0;
        return ref;
    }

    /**
     * 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.
     *
     * <p>See the class-level documentation for further explanation
     * and usage examples.
     *
     * @param ref the reference. If null, this method has no effect.
     */
    public static void reachabilityFence(Object ref) {
        if (ref != null) {
            synchronized (ref) {}
        }
    }
}

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8