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 dalvik.system.VMStack; // Android-added
39 import java.lang.reflect.Field;
40 import java.lang.reflect.Modifier;
41 import java.security.AccessController;
42 import java.security.PrivilegedActionException;
43 import java.security.PrivilegedExceptionAction;
44 import java.util.function.LongBinaryOperator;
45 import java.util.function.LongUnaryOperator;
46 import sun.reflect.CallerSensitive;
47 import sun.reflect.Reflection;
48 
49 /**
50  * A reflection-based utility that enables atomic updates to
51  * designated {@code volatile long} fields of designated classes.
52  * This class is designed for use in atomic data structures in which
53  * several fields of the same node are independently subject to atomic
54  * updates.
55  *
56  * <p>Note that the guarantees of the {@code compareAndSet}
57  * method in this class are weaker than in other atomic classes.
58  * Because this class cannot ensure that all uses of the field
59  * are appropriate for purposes of atomic access, it can
60  * guarantee atomicity only with respect to other invocations of
61  * {@code compareAndSet} and {@code set} on the same updater.
62  *
63  * @since 1.5
64  * @author Doug Lea
65  * @param <T> The type of the object holding the updatable field
66  */
67 public abstract class AtomicLongFieldUpdater<T> {
68     /**
69      * Creates and returns an updater for objects with the given field.
70      * The Class argument is needed to check that reflective types and
71      * generic types match.
72      *
73      * @param tclass the class of the objects holding the field
74      * @param fieldName the name of the field to be updated
75      * @param <U> the type of instances of tclass
76      * @return the updater
77      * @throws IllegalArgumentException if the field is not a
78      * volatile long type
79      * @throws RuntimeException with a nested reflection-based
80      * exception if the class does not hold field or is the wrong type,
81      * or the field is inaccessible to the caller according to Java language
82      * access control
83      */
84     @CallerSensitive
newUpdater(Class<U> tclass, String fieldName)85     public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
86                                                            String fieldName) {
87       Class<?> caller = VMStack.getStackClass1(); // Android-changed
88         if (AtomicLong.VM_SUPPORTS_LONG_CAS)
89             return new CASUpdater<U>(tclass, fieldName, caller);
90         else
91             return new LockedUpdater<U>(tclass, fieldName, caller);
92     }
93 
94     /**
95      * Protected do-nothing constructor for use by subclasses.
96      */
AtomicLongFieldUpdater()97     protected AtomicLongFieldUpdater() {
98     }
99 
100     /**
101      * Atomically sets the field of the given object managed by this updater
102      * to the given updated value if the current value {@code ==} the
103      * expected value. This method is guaranteed to be atomic with respect to
104      * other calls to {@code compareAndSet} and {@code set}, but not
105      * necessarily with respect to other changes in the field.
106      *
107      * @param obj An object whose field to conditionally set
108      * @param expect the expected value
109      * @param update the new value
110      * @return {@code true} if successful
111      * @throws ClassCastException if {@code obj} is not an instance
112      * of the class possessing the field established in the constructor
113      */
compareAndSet(T obj, long expect, long update)114     public abstract boolean compareAndSet(T obj, long expect, long update);
115 
116     /**
117      * Atomically sets the field of the given object managed by this updater
118      * to the given updated value if the current value {@code ==} the
119      * expected value. This method is guaranteed to be atomic with respect to
120      * other calls to {@code compareAndSet} and {@code set}, but not
121      * necessarily with respect to other changes in the field.
122      *
123      * <p><a href="package-summary.html#weakCompareAndSet">May fail
124      * spuriously and does not provide ordering guarantees</a>, so is
125      * only rarely an appropriate alternative to {@code compareAndSet}.
126      *
127      * @param obj An object whose field to conditionally set
128      * @param expect the expected value
129      * @param update the new value
130      * @return {@code true} if successful
131      * @throws ClassCastException if {@code obj} is not an instance
132      * of the class possessing the field established in the constructor
133      */
weakCompareAndSet(T obj, long expect, long update)134     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
135 
136     /**
137      * Sets the field of the given object managed by this updater to the
138      * given updated value. This operation is guaranteed to act as a volatile
139      * store with respect to subsequent invocations of {@code compareAndSet}.
140      *
141      * @param obj An object whose field to set
142      * @param newValue the new value
143      */
set(T obj, long newValue)144     public abstract void set(T obj, long newValue);
145 
146     /**
147      * Eventually sets the field of the given object managed by this
148      * updater to the given updated value.
149      *
150      * @param obj An object whose field to set
151      * @param newValue the new value
152      * @since 1.6
153      */
lazySet(T obj, long newValue)154     public abstract void lazySet(T obj, long newValue);
155 
156     /**
157      * Gets the current value held in the field of the given object managed
158      * by this updater.
159      *
160      * @param obj An object whose field to get
161      * @return the current value
162      */
get(T obj)163     public abstract long get(T obj);
164 
165     /**
166      * Atomically sets the field of the given object managed by this updater
167      * to the given value and returns the old value.
168      *
169      * @param obj An object whose field to get and set
170      * @param newValue the new value
171      * @return the previous value
172      */
getAndSet(T obj, long newValue)173     public long getAndSet(T obj, long newValue) {
174         long prev;
175         do {
176             prev = get(obj);
177         } while (!compareAndSet(obj, prev, newValue));
178         return prev;
179     }
180 
181     /**
182      * Atomically increments by one the current value of the field of the
183      * given object managed by this updater.
184      *
185      * @param obj An object whose field to get and set
186      * @return the previous value
187      */
getAndIncrement(T obj)188     public long getAndIncrement(T obj) {
189         long prev, next;
190         do {
191             prev = get(obj);
192             next = prev + 1;
193         } while (!compareAndSet(obj, prev, next));
194         return prev;
195     }
196 
197     /**
198      * Atomically decrements by one the current value of the field of the
199      * given object managed by this updater.
200      *
201      * @param obj An object whose field to get and set
202      * @return the previous value
203      */
getAndDecrement(T obj)204     public long getAndDecrement(T obj) {
205         long prev, next;
206         do {
207             prev = get(obj);
208             next = prev - 1;
209         } while (!compareAndSet(obj, prev, next));
210         return prev;
211     }
212 
213     /**
214      * Atomically adds the given value to the current value of the field of
215      * the given object managed by this updater.
216      *
217      * @param obj An object whose field to get and set
218      * @param delta the value to add
219      * @return the previous value
220      */
getAndAdd(T obj, long delta)221     public long getAndAdd(T obj, long delta) {
222         long prev, next;
223         do {
224             prev = get(obj);
225             next = prev + delta;
226         } while (!compareAndSet(obj, prev, next));
227         return prev;
228     }
229 
230     /**
231      * Atomically increments by one the current value of the field of the
232      * given object managed by this updater.
233      *
234      * @param obj An object whose field to get and set
235      * @return the updated value
236      */
incrementAndGet(T obj)237     public long incrementAndGet(T obj) {
238         long prev, next;
239         do {
240             prev = get(obj);
241             next = prev + 1;
242         } while (!compareAndSet(obj, prev, next));
243         return next;
244     }
245 
246     /**
247      * Atomically decrements by one the current value of the field of the
248      * given object managed by this updater.
249      *
250      * @param obj An object whose field to get and set
251      * @return the updated value
252      */
decrementAndGet(T obj)253     public long decrementAndGet(T obj) {
254         long prev, next;
255         do {
256             prev = get(obj);
257             next = prev - 1;
258         } while (!compareAndSet(obj, prev, next));
259         return next;
260     }
261 
262     /**
263      * Atomically adds the given value to the current value of the field of
264      * the given object managed by this updater.
265      *
266      * @param obj An object whose field to get and set
267      * @param delta the value to add
268      * @return the updated value
269      */
addAndGet(T obj, long delta)270     public long addAndGet(T obj, long delta) {
271         long prev, next;
272         do {
273             prev = get(obj);
274             next = prev + delta;
275         } while (!compareAndSet(obj, prev, next));
276         return next;
277     }
278 
279     /**
280      * Atomically updates the field of the given object managed by this updater
281      * with the results of applying the given function, returning the previous
282      * value. The function should be side-effect-free, since it may be
283      * re-applied when attempted updates fail due to contention among threads.
284      *
285      * @param obj An object whose field to get and set
286      * @param updateFunction a side-effect-free function
287      * @return the previous value
288      * @since 1.8
289      */
getAndUpdate(T obj, LongUnaryOperator updateFunction)290     public final long getAndUpdate(T obj, LongUnaryOperator updateFunction) {
291         long prev, next;
292         do {
293             prev = get(obj);
294             next = updateFunction.applyAsLong(prev);
295         } while (!compareAndSet(obj, prev, next));
296         return prev;
297     }
298 
299     /**
300      * Atomically updates the field of the given object managed by this updater
301      * with the results of applying the given function, returning the updated
302      * value. The function should be side-effect-free, since it may be
303      * re-applied when attempted updates fail due to contention among threads.
304      *
305      * @param obj An object whose field to get and set
306      * @param updateFunction a side-effect-free function
307      * @return the updated value
308      * @since 1.8
309      */
updateAndGet(T obj, LongUnaryOperator updateFunction)310     public final long updateAndGet(T obj, LongUnaryOperator updateFunction) {
311         long prev, next;
312         do {
313             prev = get(obj);
314             next = updateFunction.applyAsLong(prev);
315         } while (!compareAndSet(obj, prev, next));
316         return next;
317     }
318 
319     /**
320      * Atomically updates the field of the given object managed by this
321      * updater with the results of applying the given function to the
322      * current and given values, returning the previous value. The
323      * function should be side-effect-free, since it may be re-applied
324      * when attempted updates fail due to contention among threads.  The
325      * function is applied with the current value as its first argument,
326      * and the given update as the second argument.
327      *
328      * @param obj An object whose field to get and set
329      * @param x the update value
330      * @param accumulatorFunction a side-effect-free function of two arguments
331      * @return the previous value
332      * @since 1.8
333      */
getAndAccumulate(T obj, long x, LongBinaryOperator accumulatorFunction)334     public final long getAndAccumulate(T obj, long x,
335                                        LongBinaryOperator accumulatorFunction) {
336         long prev, next;
337         do {
338             prev = get(obj);
339             next = accumulatorFunction.applyAsLong(prev, x);
340         } while (!compareAndSet(obj, prev, next));
341         return prev;
342     }
343 
344     /**
345      * Atomically updates the field of the given object managed by this
346      * updater with the results of applying the given function to the
347      * current and given values, returning the updated value. The
348      * function should be side-effect-free, since it may be re-applied
349      * when attempted updates fail due to contention among threads.  The
350      * function is applied with the current value as its first argument,
351      * and the given update as the second argument.
352      *
353      * @param obj An object whose field to get and set
354      * @param x the update value
355      * @param accumulatorFunction a side-effect-free function of two arguments
356      * @return the updated value
357      * @since 1.8
358      */
accumulateAndGet(T obj, long x, LongBinaryOperator accumulatorFunction)359     public final long accumulateAndGet(T obj, long x,
360                                        LongBinaryOperator accumulatorFunction) {
361         long prev, next;
362         do {
363             prev = get(obj);
364             next = accumulatorFunction.applyAsLong(prev, x);
365         } while (!compareAndSet(obj, prev, next));
366         return next;
367     }
368 
369     private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
370         private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
371         private final long offset;
372         /**
373          * if field is protected, the subclass constructing updater, else
374          * the same as tclass
375          */
376         private final Class<?> cclass;
377         /** class holding the field */
378         private final Class<T> tclass;
379 
CASUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller)380         CASUpdater(final Class<T> tclass, final String fieldName,
381                    final Class<?> caller) {
382             final Field field;
383             final int modifiers;
384             try {
385                 field = tclass.getDeclaredField(fieldName); // Android-changed
386                 modifiers = field.getModifiers();
387                 // BEGIN Android-removed
388                 // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
389                 //     caller, tclass, null, modifiers);
390                 // ClassLoader cl = tclass.getClassLoader();
391                 // ClassLoader ccl = caller.getClassLoader();
392                 // if ((ccl != null) && (ccl != cl) &&
393                 //     ((cl == null) || !isAncestor(cl, ccl))) {
394                 //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
395                 // }
396                 // END Android-removed
397             // BEGIN Android-removed
398             // } catch (PrivilegedActionException pae) {
399             //     throw new RuntimeException(pae.getException());
400             // END Android-removed
401             } catch (Exception ex) {
402                 throw new RuntimeException(ex);
403             }
404 
405             if (field.getType() != long.class)
406                 throw new IllegalArgumentException("Must be long type");
407 
408             if (!Modifier.isVolatile(modifiers))
409                 throw new IllegalArgumentException("Must be volatile type");
410 
411             this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
412             this.tclass = tclass;
413             this.offset = U.objectFieldOffset(field);
414         }
415 
416         /**
417          * Checks that target argument is instance of cclass.  On
418          * failure, throws cause.
419          */
accessCheck(T obj)420         private final void accessCheck(T obj) {
421             if (!cclass.isInstance(obj))
422                 throwAccessCheckException(obj);
423         }
424 
425         /**
426          * Throws access exception if accessCheck failed due to
427          * protected access, else ClassCastException.
428          */
throwAccessCheckException(T obj)429         private final void throwAccessCheckException(T obj) {
430             if (cclass == tclass)
431                 throw new ClassCastException();
432             else
433                 throw new RuntimeException(
434                     new IllegalAccessException(
435                         "Class " +
436                         cclass.getName() +
437                         " can not access a protected member of class " +
438                         tclass.getName() +
439                         " using an instance of " +
440                         obj.getClass().getName()));
441         }
442 
compareAndSet(T obj, long expect, long update)443         public final boolean compareAndSet(T obj, long expect, long update) {
444             accessCheck(obj);
445             return U.compareAndSwapLong(obj, offset, expect, update);
446         }
447 
weakCompareAndSet(T obj, long expect, long update)448         public final boolean weakCompareAndSet(T obj, long expect, long update) {
449             accessCheck(obj);
450             return U.compareAndSwapLong(obj, offset, expect, update);
451         }
452 
set(T obj, long newValue)453         public final void set(T obj, long newValue) {
454             accessCheck(obj);
455             U.putLongVolatile(obj, offset, newValue);
456         }
457 
lazySet(T obj, long newValue)458         public final void lazySet(T obj, long newValue) {
459             accessCheck(obj);
460             U.putOrderedLong(obj, offset, newValue);
461         }
462 
get(T obj)463         public final long get(T obj) {
464             accessCheck(obj);
465             return U.getLongVolatile(obj, offset);
466         }
467 
getAndSet(T obj, long newValue)468         public final long getAndSet(T obj, long newValue) {
469             accessCheck(obj);
470             return U.getAndSetLong(obj, offset, newValue);
471         }
472 
getAndAdd(T obj, long delta)473         public final long getAndAdd(T obj, long delta) {
474             accessCheck(obj);
475             return U.getAndAddLong(obj, offset, delta);
476         }
477 
getAndIncrement(T obj)478         public final long getAndIncrement(T obj) {
479             return getAndAdd(obj, 1);
480         }
481 
getAndDecrement(T obj)482         public final long getAndDecrement(T obj) {
483             return getAndAdd(obj, -1);
484         }
485 
incrementAndGet(T obj)486         public final long incrementAndGet(T obj) {
487             return getAndAdd(obj, 1) + 1;
488         }
489 
decrementAndGet(T obj)490         public final long decrementAndGet(T obj) {
491             return getAndAdd(obj, -1) - 1;
492         }
493 
addAndGet(T obj, long delta)494         public final long addAndGet(T obj, long delta) {
495             return getAndAdd(obj, delta) + delta;
496         }
497     }
498 
499     private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
500         private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
501         private final long offset;
502         /**
503          * if field is protected, the subclass constructing updater, else
504          * the same as tclass
505          */
506         private final Class<?> cclass;
507         /** class holding the field */
508         private final Class<T> tclass;
509 
LockedUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller)510         LockedUpdater(final Class<T> tclass, final String fieldName,
511                       final Class<?> caller) {
512             Field field = null;
513             int modifiers = 0;
514             try {
515                 field = tclass.getDeclaredField(fieldName); // Android-changed
516                 modifiers = field.getModifiers();
517                 // BEGIN Android-removed
518                 // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
519                 //     caller, tclass, null, modifiers);
520                 // ClassLoader cl = tclass.getClassLoader();
521                 // ClassLoader ccl = caller.getClassLoader();
522                 // if ((ccl != null) && (ccl != cl) &&
523                 //     ((cl == null) || !isAncestor(cl, ccl))) {
524                 //     sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
525                 // }
526                 // END Android-removed
527             // BEGIN Android-removed
528             // } catch (PrivilegedActionException pae) {
529             //     throw new RuntimeException(pae.getException());
530             // END Android-removed
531             } catch (Exception ex) {
532                 throw new RuntimeException(ex);
533             }
534 
535             if (field.getType() != long.class)
536                 throw new IllegalArgumentException("Must be long type");
537 
538             if (!Modifier.isVolatile(modifiers))
539                 throw new IllegalArgumentException("Must be volatile type");
540 
541             this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
542             this.tclass = tclass;
543             this.offset = U.objectFieldOffset(field);
544         }
545 
546         /**
547          * Checks that target argument is instance of cclass.  On
548          * failure, throws cause.
549          */
accessCheck(T obj)550         private final void accessCheck(T obj) {
551             if (!cclass.isInstance(obj))
552                 throw accessCheckException(obj);
553         }
554 
555         /**
556          * Returns access exception if accessCheck failed due to
557          * protected access, else ClassCastException.
558          */
accessCheckException(T obj)559         private final RuntimeException accessCheckException(T obj) {
560             if (cclass == tclass)
561                 return new ClassCastException();
562             else
563                 return new RuntimeException(
564                     new IllegalAccessException(
565                         "Class " +
566                         cclass.getName() +
567                         " can not access a protected member of class " +
568                         tclass.getName() +
569                         " using an instance of " +
570                         obj.getClass().getName()));
571         }
572 
compareAndSet(T obj, long expect, long update)573         public final boolean compareAndSet(T obj, long expect, long update) {
574             accessCheck(obj);
575             synchronized (this) {
576                 long v = U.getLong(obj, offset);
577                 if (v != expect)
578                     return false;
579                 U.putLong(obj, offset, update);
580                 return true;
581             }
582         }
583 
weakCompareAndSet(T obj, long expect, long update)584         public final boolean weakCompareAndSet(T obj, long expect, long update) {
585             return compareAndSet(obj, expect, update);
586         }
587 
set(T obj, long newValue)588         public final void set(T obj, long newValue) {
589             accessCheck(obj);
590             synchronized (this) {
591                 U.putLong(obj, offset, newValue);
592             }
593         }
594 
lazySet(T obj, long newValue)595         public final void lazySet(T obj, long newValue) {
596             set(obj, newValue);
597         }
598 
get(T obj)599         public final long get(T obj) {
600             accessCheck(obj);
601             synchronized (this) {
602                 return U.getLong(obj, offset);
603             }
604         }
605     }
606 
607     // BEGIN Android-removed
608     // /**
609     //  * Returns true if the second classloader can be found in the first
610     //  * classloader's delegation chain.
611     //  * Equivalent to the inaccessible: first.isAncestor(second).
612     //  */
613     // static boolean isAncestor(ClassLoader first, ClassLoader second) {
614     //     ClassLoader acl = first;
615     //     do {
616     //         acl = acl.getParent();
617     //         if (second == acl) {
618     //             return true;
619     //         }
620     //     } while (acl != null);
621     //     return false;
622     // }
623     // END Android-removed
624 }
625