summaryrefslogtreecommitdiffstats
path: root/luni/src/main/java/java/util/concurrent/atomic/Fences.java
blob: 7ecf45adf4594f886d24196dd1c2abe5edf613d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
/*
 * 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 java.util.concurrent.atomic;

/**
 * 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>
 *   <p>
 *   <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>
 *   <p>
 *   <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>
 *  <p>
 *  <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>
 *   <p>
 *   <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 enqueing 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
 * @hide
 * @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.
     * @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.
     * @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.
     * @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) {}
        }
    }
}