AtomicLongFieldUpdater.java revision adc854b798c1cfe3bfd4c27d68d5cee38ca617da
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://creativecommons.org/licenses/publicdomain 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic; 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport sun.misc.Unsafe; 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.*; 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A reflection-based utility that enables atomic updates to 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * designated <tt>volatile long</tt> fields of designated classes. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is designed for use in atomic data structures in which 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * several fields of the same node are independently subject to atomic 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * updates. 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> Note that the guarantees of the <tt>compareAndSet</tt> method 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * in this class are weaker than in other atomic classes. Because this 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class cannot ensure that all uses of the field are appropriate for 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * purposes of atomic access, it can guarantee atomicity and volatile 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * semantics only with respect to other invocations of 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>compareAndSet</tt> and <tt>set</tt>. 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <T> The type of the object holding the updatable field 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class AtomicLongFieldUpdater<T> { 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an updater for objects with the given field. The Class 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * argument is needed to check that reflective types and generic 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * types match. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param tclass the class of the objects holding the field 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param fieldName the name of the field to be updated. 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the updater 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException if the field is not a 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * volatile long type. 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws RuntimeException with a nested reflection-based 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exception if the class does not hold field or is the wrong type. 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (AtomicLong.VM_SUPPORTS_LONG_CAS) 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new CASUpdater<U>(tclass, fieldName); 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new LockedUpdater<U>(tclass, fieldName); 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Protected do-nothing constructor for use by subclasses. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AtomicLongFieldUpdater() { 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically set the value of the field of the given object managed 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by this Updater to the given updated value if the current value 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>==</tt> the expected value. This method is guaranteed to be 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * atomic with respect to other calls to <tt>compareAndSet</tt> and 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>set</tt>, but not necessarily with respect to other 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * changes in the field. 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to conditionally set 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if successful. 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassCastException if <tt>obj</tt> is not an instance 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the class possessing the field established in the constructor. 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean compareAndSet(T obj, long expect, long update); 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically set the value of the field of the given object managed 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by this Updater to the given updated value if the current value 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>==</tt> the expected value. This method is guaranteed to be 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * atomic with respect to other calls to <tt>compareAndSet</tt> and 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>set</tt>, but not necessarily with respect to other 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * changes in the field, and may fail spuriously. 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to conditionally set 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return true if successful. 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ClassCastException if <tt>obj</tt> is not an instance 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the class possessing the field established in the constructor. 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract boolean weakCompareAndSet(T obj, long expect, long update); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the field of the given object managed by this updater. This 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * operation is guaranteed to act as a volatile store with respect 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to subsequent invocations of <tt>compareAndSet</tt>. 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to set 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract void set(T obj, long newValue); 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Get the current value held in the field by the given object. 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the current value 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract long get(T obj); 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set to the given value and return the old value. 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getAndSet(T obj, long newValue) { 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, newValue)) 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return current; 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically increment by one the current value. 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value; 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getAndIncrement(T obj) { 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long next = current + 1; 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, next)) 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return current; 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically decrement by one the current value. 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value; 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getAndDecrement(T obj) { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long next = current - 1; 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, next)) 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return current; 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically add the given value to current value. 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param delta the value to add 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getAndAdd(T obj, long delta) { 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long next = current + delta; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, next)) 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return current; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically increment by one the current value. 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the updated value; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long incrementAndGet(T obj) { 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long next = current + 1; 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, next)) 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return next; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically decrement by one the current value. 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the updated value; 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long decrementAndGet(T obj) { 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long next = current - 1; 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, next)) 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return next; 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Atomically add the given value to current value. 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj An object whose field to get and set 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param delta the value to add 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the updated value; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long addAndGet(T obj, long delta) { 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long current = get(obj); 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long next = current + delta; 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (compareAndSet(obj, current, next)) 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return next; 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Unsafe unsafe = UnsafeAccess.THE_ONE; 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final long offset; 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Class<T> tclass; 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project CASUpdater(Class<T> tclass, String fieldName) { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Field field = null; 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project field = tclass.getDeclaredField(fieldName); 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch(Exception ex) { 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new RuntimeException(ex); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class fieldt = field.getType(); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (fieldt != long.class) 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Must be long type"); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!Modifier.isVolatile(field.getModifiers())) 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Must be volatile type"); 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tclass = tclass; 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = unsafe.objectFieldOffset(field); 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean compareAndSet(T obj, long expect, long update) { 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unsafe.compareAndSwapLong(obj, offset, expect, update); 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean weakCompareAndSet(T obj, long expect, long update) { 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unsafe.compareAndSwapLong(obj, offset, expect, update); 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void set(T obj, long newValue) { 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unsafe.putLongVolatile(obj, offset, newValue); 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long get(T obj) { 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unsafe.getLongVolatile(obj, offset); 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> { 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // BEGIN android-changed 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Unsafe unsafe = UnsafeAccess.THE_ONE; 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // END android-changed 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final long offset; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Class<T> tclass; 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project LockedUpdater(Class<T> tclass, String fieldName) { 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Field field = null; 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project field = tclass.getDeclaredField(fieldName); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch(Exception ex) { 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new RuntimeException(ex); 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class fieldt = field.getType(); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (fieldt != long.class) 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Must be long type"); 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!Modifier.isVolatile(field.getModifiers())) 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException("Must be volatile type"); 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.tclass = tclass; 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project offset = unsafe.objectFieldOffset(field); 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean compareAndSet(T obj, long expect, long update) { 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(this) { 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long v = unsafe.getLong(obj, offset); 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (v != expect) 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unsafe.putLong(obj, offset, update); 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean weakCompareAndSet(T obj, long expect, long update) { 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return compareAndSet(obj, expect, update); 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void set(T obj, long newValue) { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(this) { 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unsafe.putLong(obj, offset, newValue); 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long get(T obj) { 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!tclass.isInstance(obj)) 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ClassCastException(); 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized(this) { 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return unsafe.getLong(obj, offset); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 322