AtomicLongFieldUpdater.java revision a807b4d808d2591894daf13aab179b2e9c46a2f5
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
4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic;
87365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson
98eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport dalvik.system.VMStack; // android-added
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport sun.misc.Unsafe;
118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.lang.reflect.*;
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A reflection-based utility that enables atomic updates to
15bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * designated {@code volatile long} fields of designated classes.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class is designed for use in atomic data structures in which
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * several fields of the same node are independently subject to atomic
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * updates.
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
20bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Note that the guarantees of the {@code compareAndSet}
21bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * method in this class are weaker than in other atomic classes.
22bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Because this class cannot ensure that all uses of the field
23bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * are appropriate for purposes of atomic access, it can
24bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * guarantee atomicity only with respect to other invocations of
25bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code compareAndSet} and {@code set} on the same updater.
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <T> The type of the object holding the updatable field
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonpublic abstract class  AtomicLongFieldUpdater<T> {
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
33bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates and returns an updater for objects with the given field.
34bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The Class argument is needed to check that reflective types and
35bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * generic types match.
36bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tclass the class of the objects holding the field
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param fieldName the name of the field to be updated.
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the updater
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException if the field is not a
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * volatile long type.
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws RuntimeException with a nested reflection-based
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exception if the class does not hold field or is the wrong type.
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (AtomicLong.VM_SUPPORTS_LONG_CAS)
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new CASUpdater<U>(tclass, fieldName);
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new LockedUpdater<U>(tclass, fieldName);
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Protected do-nothing constructor for use by subclasses.
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected AtomicLongFieldUpdater() {
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
59bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the field of the given object managed by this updater
60bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to the given updated value if the current value {@code ==} the
61bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * expected value. This method is guaranteed to be atomic with respect to
62bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * other calls to {@code compareAndSet} and {@code set}, but not
63bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * necessarily with respect to other changes in the field.
64bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to conditionally set
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return true if successful.
69bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if {@code obj} is not an instance
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of the class possessing the field established in the constructor.
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract boolean compareAndSet(T obj, long expect, long update);
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
75bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the field of the given object managed by this updater
76bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to the given updated value if the current value {@code ==} the
77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * expected value. This method is guaranteed to be atomic with respect to
78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * other calls to {@code compareAndSet} and {@code set}, but not
79bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * necessarily with respect to other changes in the field.
80bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
81bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
82bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and does not provide ordering guarantees, so is only rarely an
83bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * appropriate alternative to {@code compareAndSet}.
84bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to conditionally set
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return true if successful.
89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if {@code obj} is not an instance
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of the class possessing the field established in the constructor.
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract boolean weakCompareAndSet(T obj, long expect, long update);
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Sets the field of the given object managed by this updater to the
96bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given updated value. This operation is guaranteed to act as a volatile
97bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * store with respect to subsequent invocations of {@code compareAndSet}.
98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to set
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract void set(T obj, long newValue);
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Eventually sets the field of the given object managed by this
1066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * updater to the given updated value.
1076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param obj An object whose field to set
1096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param newValue the new value
1106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
1116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public abstract void lazySet(T obj, long newValue);
1136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
115bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Gets the current value held in the field of the given object managed
116bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * by this updater.
117bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract long get(T obj);
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
124bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the field of the given object managed by this updater
125bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to the given value and returns the old value.
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the previous value
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndSet(T obj, long newValue) {
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, newValue))
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
140bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically increments by one the current value of the field of the
141bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
142bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
144bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the previous value
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndIncrement(T obj) {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + 1;
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically decrements by one the current value of the field of the
157bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
160bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the previous value
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndDecrement(T obj) {
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current - 1;
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
172bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically adds the given value to the current value of the field of
173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the given object managed by this updater.
174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param delta the value to add
177bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the previous value
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getAndAdd(T obj, long delta) {
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + delta;
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return current;
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
189bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically increments by one the current value of the field of the
190bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
191bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
193bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the updated value
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long incrementAndGet(T obj) {
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + 1;
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return next;
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
205bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically decrements by one the current value of the field of the
206bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given object managed by this updater.
207bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the updated value
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long decrementAndGet(T obj) {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current - 1;
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return next;
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
221bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically adds the given value to the current value of the field of
222bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the given object managed by this updater.
223bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj An object whose field to get and set
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param delta the value to add
226bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the updated value
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long addAndGet(T obj, long delta) {
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (;;) {
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long current = get(obj);
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long next = current + delta;
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(obj, current, next))
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return next;
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
238a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private static final Unsafe unsafe = Unsafe.getUnsafe();
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final long offset;
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Class<T> tclass;
241a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private final Class<?> cclass;
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        CASUpdater(Class<T> tclass, String fieldName) {
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Field field = null;
245a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> caller = null;
246bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int modifiers = 0;
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                field = tclass.getDeclaredField(fieldName);
2496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                caller = VMStack.getStackClass2(); // android-changed
250bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                modifiers = field.getModifiers();
2516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // BEGIN android-removed
2526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
2536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                //     caller, tclass, null, modifiers);
2546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
2556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // END android-removed
256bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } catch (Exception ex) {
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new RuntimeException(ex);
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
259bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
260a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> fieldt = field.getType();
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (fieldt != long.class)
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be long type");
263bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
264bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (!Modifier.isVolatile(modifiers))
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be volatile type");
266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
267bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.cclass = (Modifier.isProtected(modifiers) &&
268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                           caller != tclass) ? caller : null;
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.tclass = tclass;
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset = unsafe.objectFieldOffset(field);
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
273bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void fullCheck(T obj) {
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!tclass.isInstance(obj))
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new ClassCastException();
276bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass != null)
277bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                ensureProtectedAccess(obj);
278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
279bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public boolean compareAndSet(T obj, long expect, long update) {
281bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return unsafe.compareAndSwapLong(obj, offset, expect, update);
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean weakCompareAndSet(T obj, long expect, long update) {
286bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return unsafe.compareAndSwapLong(obj, offset, expect, update);
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void set(T obj, long newValue) {
291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            unsafe.putLongVolatile(obj, offset, newValue);
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public void lazySet(T obj, long newValue) {
2966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            unsafe.putOrderedLong(obj, offset, newValue);
2986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
2996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public long get(T obj) {
301bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return unsafe.getLongVolatile(obj, offset);
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
304bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
305bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void ensureProtectedAccess(T obj) {
306bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass.isInstance(obj)) {
307bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return;
308bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
3098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new RuntimeException(
310bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                new IllegalAccessException("Class " +
311bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    cclass.getName() +
312bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " can not access a protected member of class " +
313bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    tclass.getName() +
314bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " using an instance of " +
315bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    obj.getClass().getName()
316bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                )
317bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            );
318bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
323a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private static final Unsafe unsafe = Unsafe.getUnsafe();
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final long offset;
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        private final Class<T> tclass;
326a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        private final Class<?> cclass;
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        LockedUpdater(Class<T> tclass, String fieldName) {
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Field field = null;
330a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> caller = null;
331bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int modifiers = 0;
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                field = tclass.getDeclaredField(fieldName);
3346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                caller = VMStack.getStackClass2(); // android-changed
335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                modifiers = field.getModifiers();
3366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // BEGIN android-removed
3376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
3386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                //     caller, tclass, null, modifiers);
3396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
3406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                // END android-removed
341bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } catch (Exception ex) {
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new RuntimeException(ex);
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
344bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
345a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            Class<?> fieldt = field.getType();
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (fieldt != long.class)
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be long type");
348bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
349bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (!Modifier.isVolatile(modifiers))
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new IllegalArgumentException("Must be volatile type");
351bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
352bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.cclass = (Modifier.isProtected(modifiers) &&
353bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                           caller != tclass) ? caller : null;
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.tclass = tclass;
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            offset = unsafe.objectFieldOffset(field);
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
358bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void fullCheck(T obj) {
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!tclass.isInstance(obj))
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new ClassCastException();
361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass != null)
362bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                ensureProtectedAccess(obj);
363bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
364bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public boolean compareAndSet(T obj, long expect, long update) {
366bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
3678eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            synchronized (this) {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                long v = unsafe.getLong(obj, offset);
369bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (v != expect)
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                unsafe.putLong(obj, offset, update);
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean weakCompareAndSet(T obj, long expect, long update) {
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return compareAndSet(obj, expect, update);
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void set(T obj, long newValue) {
381bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
3828eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            synchronized (this) {
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                unsafe.putLong(obj, offset, newValue);
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public void lazySet(T obj, long newValue) {
388bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            set(obj, newValue);
389bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
390bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public long get(T obj) {
392bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
3938eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            synchronized (this) {
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return unsafe.getLong(obj, offset);
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
397bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
398bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private void ensureProtectedAccess(T obj) {
399bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (cclass.isInstance(obj)) {
400bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return;
401bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
4028eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new RuntimeException(
403bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                new IllegalAccessException("Class " +
404bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    cclass.getName() +
405bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " can not access a protected member of class " +
406bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    tclass.getName() +
407bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    " using an instance of " +
408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    obj.getClass().getName()
409bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                )
410bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            );
411bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
414