OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [external/] [jsr166/] [java/] [util/] [concurrent/] [atomic/] [AtomicIntegerFieldUpdater.java] - Blame information for rev 768

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.