1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.  Oracle designates this
7  * particular file as subject to the "Classpath" exception as provided
8  * by Oracle in the LICENSE file that accompanied this code.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  */

24
25 /*
26  * This file is available under and governed by the GNU General Public
27  * License version 2 only, as published by the Free Software Foundation.
28  * However, the following notice accompanied the original version of this
29  * file:
30  *
31  * Written by Doug Lea with assistance from members of JCP JSR-166
32  * Expert Group and released to the public domain, as explained at
33  * http://creativecommons.org/publicdomain/zero/1.0/
34  */

35
36 package java.util.concurrent.atomic;
37
38 import java.lang.reflect.Field;
39 import java.lang.reflect.Modifier;
40 import java.security.AccessController;
41 import java.security.PrivilegedActionException;
42 import java.security.PrivilegedExceptionAction;
43 import java.util.Objects;
44 import java.util.function.LongBinaryOperator;
45 import java.util.function.LongUnaryOperator;
46 import jdk.internal.misc.Unsafe;
47 import jdk.internal.reflect.CallerSensitive;
48 import jdk.internal.reflect.Reflection;
49 import java.lang.invoke.VarHandle;
50
51 /**
52  * A reflection-based utility that enables atomic updates to
53  * designated {@code volatile long} fields of designated classes.
54  * This class is designed for use in atomic data structures in which
55  * several fields of the same node are independently subject to atomic
56  * updates.
57  *
58  * <p>Note that the guarantees of the {@code compareAndSet}
59  * method in this class are weaker than in other atomic classes.
60  * Because this class cannot ensure that all uses of the field
61  * are appropriate for purposes of atomic access, it can
62  * guarantee atomicity only with respect to other invocations of
63  * {@code compareAndSet} and {@code set} on the same updater.
64  *
65  * <p>Object arguments for parameters of type {@code T} that are not
66  * instances of the class passed to {@link #newUpdater} will result in
67  * a {@link ClassCastException} being thrown.
68  *
69  * @since 1.5
70  * @author Doug Lea
71  * @param <T> The type of the object holding the updatable field
72  */

73 public abstract class AtomicLongFieldUpdater<T> {
74     /**
75      * Creates and returns an updater for objects with the given field.
76      * The Class argument is needed to check that reflective types and
77      * generic types match.
78      *
79      * @param tclass the class of the objects holding the field
80      * @param fieldName the name of the field to be updated
81      * @param <U> the type of instances of tclass
82      * @return the updater
83      * @throws IllegalArgumentException if the field is not a
84      * volatile long type
85      * @throws RuntimeException with a nested reflection-based
86      * exception if the class does not hold field or is the wrong type,
87      * or the field is inaccessible to the caller according to Java language
88      * access control
89      */

90     @CallerSensitive
91     public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
92                                                            String fieldName) {
93         Class<?> caller = Reflection.getCallerClass();
94         if (AtomicLong.VM_SUPPORTS_LONG_CAS)
95             return new CASUpdater<U>(tclass, fieldName, caller);
96         else
97             return new LockedUpdater<U>(tclass, fieldName, caller);
98     }
99
100     /**
101      * Protected do-nothing constructor for use by subclasses.
102      */

103     protected AtomicLongFieldUpdater() {
104     }
105
106     /**
107      * Atomically sets the field of the given object managed by this updater
108      * to the given updated value if the current value {@code ==} the
109      * expected value. This method is guaranteed to be atomic with respect to
110      * other calls to {@code compareAndSet} and {@code set}, but not
111      * necessarily with respect to other changes in the field.
112      *
113      * @param obj An object whose field to conditionally set
114      * @param expect the expected value
115      * @param update the new value
116      * @return {@code trueif successful
117      */

118     public abstract boolean compareAndSet(T obj, long expect, long update);
119
120     /**
121      * Atomically sets the field of the given object managed by this updater
122      * to the given updated value if the current value {@code ==} the
123      * expected value. This method is guaranteed to be atomic with respect to
124      * other calls to {@code compareAndSet} and {@code set}, but not
125      * necessarily with respect to other changes in the field.
126      *
127      * <p><a href="package-summary.html#weakCompareAndSet">May fail
128      * spuriously and does not provide ordering guarantees</a>, so is
129      * only rarely an appropriate alternative to {@code compareAndSet}.
130      *
131      * @param obj An object whose field to conditionally set
132      * @param expect the expected value
133      * @param update the new value
134      * @return {@code trueif successful
135      */

136     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
137
138     /**
139      * Sets the field of the given object managed by this updater to the
140      * given updated value. This operation is guaranteed to act as a volatile
141      * store with respect to subsequent invocations of {@code compareAndSet}.
142      *
143      * @param obj An object whose field to set
144      * @param newValue the new value
145      */

146     public abstract void set(T obj, long newValue);
147
148     /**
149      * Eventually sets the field of the given object managed by this
150      * updater to the given updated value.
151      *
152      * @param obj An object whose field to set
153      * @param newValue the new value
154      * @since 1.6
155      */

156     public abstract void lazySet(T obj, long newValue);
157
158     /**
159      * Returns the current value held in the field of the given object
160      * managed by this updater.
161      *
162      * @param obj An object whose field to get
163      * @return the current value
164      */

165     public abstract long get(T obj);
166
167     /**
168      * Atomically sets the field of the given object managed by this updater
169      * to the given value and returns the old value.
170      *
171      * @param obj An object whose field to get and set
172      * @param newValue the new value
173      * @return the previous value
174      */

175     public long getAndSet(T obj, long newValue) {
176         long prev;
177         do {
178             prev = get(obj);
179         } while (!compareAndSet(obj, prev, newValue));
180         return prev;
181     }
182
183     /**
184      * Atomically increments by one the current value of the field of the
185      * given object managed by this updater.
186      *
187      * @param obj An object whose field to get and set
188      * @return the previous value
189      */

190     public long getAndIncrement(T obj) {
191         long prev, next;
192         do {
193             prev = get(obj);
194             next = prev + 1;
195         } while (!compareAndSet(obj, prev, next));
196         return prev;
197     }
198
199     /**
200      * Atomically decrements by one the current value of the field of the
201      * given object managed by this updater.
202      *
203      * @param obj An object whose field to get and set
204      * @return the previous value
205      */

206     public long getAndDecrement(T obj) {
207         long prev, next;
208         do {
209             prev = get(obj);
210             next = prev - 1;
211         } while (!compareAndSet(obj, prev, next));
212         return prev;
213     }
214
215     /**
216      * Atomically adds the given value to the current value of the field of
217      * the given object managed by this updater.
218      *
219      * @param obj An object whose field to get and set
220      * @param delta the value to add
221      * @return the previous value
222      */

223     public long getAndAdd(T obj, long delta) {
224         long prev, next;
225         do {
226             prev = get(obj);
227             next = prev + delta;
228         } while (!compareAndSet(obj, prev, next));
229         return prev;
230     }
231
232     /**
233      * Atomically increments by one the current value of the field of the
234      * given object managed by this updater.
235      *
236      * @param obj An object whose field to get and set
237      * @return the updated value
238      */

239     public long incrementAndGet(T obj) {
240         long prev, next;
241         do {
242             prev = get(obj);
243             next = prev + 1;
244         } while (!compareAndSet(obj, prev, next));
245         return next;
246     }
247
248     /**
249      * Atomically decrements by one the current value of the field of the
250      * given object managed by this updater.
251      *
252      * @param obj An object whose field to get and set
253      * @return the updated value
254      */

255     public long decrementAndGet(T obj) {
256         long prev, next;
257         do {
258             prev = get(obj);
259             next = prev - 1;
260         } while (!compareAndSet(obj, prev, next));
261         return next;
262     }
263
264     /**
265      * Atomically adds the given value to the current value of the field of
266      * the given object managed by this updater.
267      *
268      * @param obj An object whose field to get and set
269      * @param delta the value to add
270      * @return the updated value
271      */

272     public long addAndGet(T obj, long delta) {
273         long prev, next;
274         do {
275             prev = get(obj);
276             next = prev + delta;
277         } while (!compareAndSet(obj, prev, next));
278         return next;
279     }
280
281     /**
282      * Atomically updates (with memory effects as specified by {@link
283      * VarHandle#compareAndSet}) the field of the given object managed
284      * by this updater with the results of applying the given
285      * function, returning the previous value. The function should be
286      * side-effect-free, since it may be re-applied when attempted
287      * updates fail due to contention among threads.
288      *
289      * @param obj An object whose field to get and set
290      * @param updateFunction a side-effect-free function
291      * @return the previous value
292      * @since 1.8
293      */

294     public final long getAndUpdate(T obj, LongUnaryOperator updateFunction) {
295         long prev, next;
296         do {
297             prev = get(obj);
298             next = updateFunction.applyAsLong(prev);
299         } while (!compareAndSet(obj, prev, next));
300         return prev;
301     }
302
303     /**
304      * Atomically updates (with memory effects as specified by {@link
305      * VarHandle#compareAndSet}) the field of the given object managed
306      * by this updater with the results of applying the given
307      * function, returning the updated value. The function should be
308      * side-effect-free, since it may be re-applied when attempted
309      * updates fail due to contention among threads.
310      *
311      * @param obj An object whose field to get and set
312      * @param updateFunction a side-effect-free function
313      * @return the updated value
314      * @since 1.8
315      */

316     public final long updateAndGet(T obj, LongUnaryOperator updateFunction) {
317         long prev, next;
318         do {
319             prev = get(obj);
320             next = updateFunction.applyAsLong(prev);
321         } while (!compareAndSet(obj, prev, next));
322         return next;
323     }
324
325     /**
326      * Atomically updates (with memory effects as specified by {@link
327      * VarHandle#compareAndSet}) the field of the given object managed
328      * by this updater with the results of applying the given function
329      * to the current and given values, returning the previous value.
330      * The function should be side-effect-free, since it may be
331      * re-applied when attempted updates fail due to contention among
332      * threads.  The function is applied with the current value as its
333      * first argument, and the given update as the second argument.
334      *
335      * @param obj An object whose field to get and set
336      * @param x the update value
337      * @param accumulatorFunction a side-effect-free function of two arguments
338      * @return the previous value
339      * @since 1.8
340      */

341     public final long getAndAccumulate(T obj, long x,
342                                        LongBinaryOperator accumulatorFunction) {
343         long prev, next;
344         do {
345             prev = get(obj);
346             next = accumulatorFunction.applyAsLong(prev, x);
347         } while (!compareAndSet(obj, prev, next));
348         return prev;
349     }
350
351     /**
352      * Atomically updates (with memory effects as specified by {@link
353      * VarHandle#compareAndSet}) the field of the given object managed
354      * by this updater with the results of applying the given function
355      * to the current and given values, returning the updated value.
356      * The function should be side-effect-free, since it may be
357      * re-applied when attempted updates fail due to contention among
358      * threads.  The function is applied with the current value as its
359      * first argument, and the given update as the second argument.
360      *
361      * @param obj An object whose field to get and set
362      * @param x the update value
363      * @param accumulatorFunction a side-effect-free function of two arguments
364      * @return the updated value
365      * @since 1.8
366      */

367     public final long accumulateAndGet(T obj, long x,
368                                        LongBinaryOperator accumulatorFunction) {
369         long prev, next;
370         do {
371             prev = get(obj);
372             next = accumulatorFunction.applyAsLong(prev, x);
373         } while (!compareAndSet(obj, prev, next));
374         return next;
375     }
376
377     private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
378         private static final Unsafe U = Unsafe.getUnsafe();
379         private final long offset;
380         /**
381          * if field is protected, the subclass constructing updater, else
382          * the same as tclass
383          */

384         private final Class<?> cclass;
385         /** class holding the field */
386         private final Class<T> tclass;
387
388         CASUpdater(final Class<T> tclass, final String fieldName,
389                    final Class<?> caller) {
390             final Field field;
391             final int modifiers;
392             try {
393                 field = AccessController.doPrivileged(
394                     new PrivilegedExceptionAction<Field>() {
395                         public Field run() throws NoSuchFieldException {
396                             return tclass.getDeclaredField(fieldName);
397                         }
398                     });
399                 modifiers = field.getModifiers();
400                 sun.reflect.misc.ReflectUtil.ensureMemberAccess(
401                     caller, tclass, null, modifiers);
402                 ClassLoader cl = tclass.getClassLoader();
403                 ClassLoader ccl = caller.getClassLoader();
404                 if ((ccl != null) && (ccl != cl) &&
405                     ((cl == null) || !isAncestor(cl, ccl))) {
406                     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
407                 }
408             } catch (PrivilegedActionException pae) {
409                 throw new RuntimeException(pae.getException());
410             } catch (Exception ex) {
411                 throw new RuntimeException(ex);
412             }
413
414             if (field.getType() != long.class)
415                 throw new IllegalArgumentException("Must be long type");
416
417             if (!Modifier.isVolatile(modifiers))
418                 throw new IllegalArgumentException("Must be volatile type");
419
420             // Access to protected field members is restricted to receivers only
421             // of the accessing class, or one of its subclasses, and the
422             // accessing class must in turn be a subclass (or package sibling)
423             // of the protected member's defining class.
424             // If the updater refers to a protected field of a declaring class
425             // outside the current package, the receiver argument will be
426             // narrowed to the type of the accessing class.
427             this.cclass = (Modifier.isProtected(modifiers) &&
428                            tclass.isAssignableFrom(caller) &&
429                            !isSamePackage(tclass, caller))
430                           ? caller : tclass;
431             this.tclass = tclass;
432             this.offset = U.objectFieldOffset(field);
433         }
434
435         /**
436          * Checks that target argument is instance of cclass.  On
437          * failure, throws cause.
438          */

439         private final void accessCheck(T obj) {
440             if (!cclass.isInstance(obj))
441                 throwAccessCheckException(obj);
442         }
443
444         /**
445          * Throws access exception if accessCheck failed due to
446          * protected access, else ClassCastException.
447          */

448         private final void throwAccessCheckException(T obj) {
449             if (cclass == tclass)
450                 throw new ClassCastException();
451             else
452                 throw new RuntimeException(
453                     new IllegalAccessException(
454                         "Class " +
455                         cclass.getName() +
456                         " can not access a protected member of class " +
457                         tclass.getName() +
458                         " using an instance of " +
459                         obj.getClass().getName()));
460         }
461
462         public final boolean compareAndSet(T obj, long expect, long update) {
463             accessCheck(obj);
464             return U.compareAndSetLong(obj, offset, expect, update);
465         }
466
467         public final boolean weakCompareAndSet(T obj, long expect, long update) {
468             accessCheck(obj);
469             return U.compareAndSetLong(obj, offset, expect, update);
470         }
471
472         public final void set(T obj, long newValue) {
473             accessCheck(obj);
474             U.putLongVolatile(obj, offset, newValue);
475         }
476
477         public final void lazySet(T obj, long newValue) {
478             accessCheck(obj);
479             U.putLongRelease(obj, offset, newValue);
480         }
481
482         public final long get(T obj) {
483             accessCheck(obj);
484             return U.getLongVolatile(obj, offset);
485         }
486
487         public final long getAndSet(T obj, long newValue) {
488             accessCheck(obj);
489             return U.getAndSetLong(obj, offset, newValue);
490         }
491
492         public final long getAndAdd(T obj, long delta) {
493             accessCheck(obj);
494             return U.getAndAddLong(obj, offset, delta);
495         }
496
497         public final long getAndIncrement(T obj) {
498             return getAndAdd(obj, 1);
499         }
500
501         public final long getAndDecrement(T obj) {
502             return getAndAdd(obj, -1);
503         }
504
505         public final long incrementAndGet(T obj) {
506             return getAndAdd(obj, 1) + 1;
507         }
508
509         public final long decrementAndGet(T obj) {
510             return getAndAdd(obj, -1) - 1;
511         }
512
513         public final long addAndGet(T obj, long delta) {
514             return getAndAdd(obj, delta) + delta;
515         }
516     }
517
518     private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
519         private static final Unsafe U = Unsafe.getUnsafe();
520         private final long offset;
521         /**
522          * if field is protected, the subclass constructing updater, else
523          * the same as tclass
524          */

525         private final Class<?> cclass;
526         /** class holding the field */
527         private final Class<T> tclass;
528
529         LockedUpdater(final Class<T> tclass, final String fieldName,
530                       final Class<?> caller) {
531             final Field field;
532             final int modifiers;
533             try {
534                 field = AccessController.doPrivileged(
535                     new PrivilegedExceptionAction<Field>() {
536                         public Field run() throws NoSuchFieldException {
537                             return tclass.getDeclaredField(fieldName);
538                         }
539                     });
540                 modifiers = field.getModifiers();
541                 sun.reflect.misc.ReflectUtil.ensureMemberAccess(
542                     caller, tclass, null, modifiers);
543                 ClassLoader cl = tclass.getClassLoader();
544                 ClassLoader ccl = caller.getClassLoader();
545                 if ((ccl != null) && (ccl != cl) &&
546                     ((cl == null) || !isAncestor(cl, ccl))) {
547                     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
548                 }
549             } catch (PrivilegedActionException pae) {
550                 throw new RuntimeException(pae.getException());
551             } catch (Exception ex) {
552                 throw new RuntimeException(ex);
553             }
554
555             if (field.getType() != long.class)
556                 throw new IllegalArgumentException("Must be long type");
557
558             if (!Modifier.isVolatile(modifiers))
559                 throw new IllegalArgumentException("Must be volatile type");
560
561             // Access to protected field members is restricted to receivers only
562             // of the accessing class, or one of its subclasses, and the
563             // accessing class must in turn be a subclass (or package sibling)
564             // of the protected member's defining class.
565             // If the updater refers to a protected field of a declaring class
566             // outside the current package, the receiver argument will be
567             // narrowed to the type of the accessing class.
568             this.cclass = (Modifier.isProtected(modifiers) &&
569                            tclass.isAssignableFrom(caller) &&
570                            !isSamePackage(tclass, caller))
571                           ? caller : tclass;
572             this.tclass = tclass;
573             this.offset = U.objectFieldOffset(field);
574         }
575
576         /**
577          * Checks that target argument is instance of cclass.  On
578          * failure, throws cause.
579          */

580         private final void accessCheck(T obj) {
581             if (!cclass.isInstance(obj))
582                 throw accessCheckException(obj);
583         }
584
585         /**
586          * Returns access exception if accessCheck failed due to
587          * protected access, else ClassCastException.
588          */

589         private final RuntimeException accessCheckException(T obj) {
590             if (cclass == tclass)
591                 return new ClassCastException();
592             else
593                 return new RuntimeException(
594                     new IllegalAccessException(
595                         "Class " +
596                         cclass.getName() +
597                         " can not access a protected member of class " +
598                         tclass.getName() +
599                         " using an instance of " +
600                         obj.getClass().getName()));
601         }
602
603         public final boolean compareAndSet(T obj, long expect, long update) {
604             accessCheck(obj);
605             synchronized (this) {
606                 long v = U.getLong(obj, offset);
607                 if (v != expect)
608                     return false;
609                 U.putLong(obj, offset, update);
610                 return true;
611             }
612         }
613
614         public final boolean weakCompareAndSet(T obj, long expect, long update) {
615             return compareAndSet(obj, expect, update);
616         }
617
618         public final void set(T obj, long newValue) {
619             accessCheck(obj);
620             synchronized (this) {
621                 U.putLong(obj, offset, newValue);
622             }
623         }
624
625         public final void lazySet(T obj, long newValue) {
626             set(obj, newValue);
627         }
628
629         public final long get(T obj) {
630             accessCheck(obj);
631             synchronized (this) {
632                 return U.getLong(obj, offset);
633             }
634         }
635     }
636
637     /**
638      * Returns true if the second classloader can be found in the first
639      * classloader's delegation chain.
640      * Equivalent to the inaccessible: first.isAncestor(second).
641      */

642     static boolean isAncestor(ClassLoader first, ClassLoader second) {
643         ClassLoader acl = first;
644         do {
645             acl = acl.getParent();
646             if (second == acl) {
647                 return true;
648             }
649         } while (acl != null);
650         return false;
651     }
652
653     /**
654      * Returns true if the two classes have the same class loader and
655      * package qualifier
656      */

657     static boolean isSamePackage(Class<?> class1, Class<?> class2) {
658         return class1.getClassLoader() == class2.getClassLoader()
659                && Objects.equals(class1.getPackageName(), class2.getPackageName());
660     }
661 }
662