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