1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Mon Feb 09 20:32:36 2015 +0100
1.3 @@ -0,0 +1,346 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent.atomic;
1.40 +import sun.misc.Unsafe;
1.41 +import java.lang.reflect.*;
1.42 +
1.43 +/**
1.44 + * A reflection-based utility that enables atomic updates to
1.45 + * designated {@code volatile int} fields of designated classes.
1.46 + * This class is designed for use in atomic data structures in which
1.47 + * several fields of the same node are independently subject to atomic
1.48 + * updates.
1.49 + *
1.50 + * <p>Note that the guarantees of the {@code compareAndSet}
1.51 + * method in this class are weaker than in other atomic classes.
1.52 + * Because this class cannot ensure that all uses of the field
1.53 + * are appropriate for purposes of atomic access, it can
1.54 + * guarantee atomicity only with respect to other invocations of
1.55 + * {@code compareAndSet} and {@code set} on the same updater.
1.56 + *
1.57 + * @since 1.5
1.58 + * @author Doug Lea
1.59 + * @param <T> The type of the object holding the updatable field
1.60 + */
1.61 +public abstract class AtomicIntegerFieldUpdater<T> {
1.62 + /**
1.63 + * Creates and returns an updater for objects with the given field.
1.64 + * The Class argument is needed to check that reflective types and
1.65 + * generic types match.
1.66 + *
1.67 + * @param tclass the class of the objects holding the field
1.68 + * @param fieldName the name of the field to be updated
1.69 + * @return the updater
1.70 + * @throws IllegalArgumentException if the field is not a
1.71 + * volatile integer type
1.72 + * @throws RuntimeException with a nested reflection-based
1.73 + * exception if the class does not hold field or is the wrong type
1.74 + */
1.75 + public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
1.76 + return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
1.77 + }
1.78 +
1.79 + /**
1.80 + * Protected do-nothing constructor for use by subclasses.
1.81 + */
1.82 + protected AtomicIntegerFieldUpdater() {
1.83 + }
1.84 +
1.85 + /**
1.86 + * Atomically sets the field of the given object managed by this updater
1.87 + * to the given updated value if the current value {@code ==} the
1.88 + * expected value. This method is guaranteed to be atomic with respect to
1.89 + * other calls to {@code compareAndSet} and {@code set}, but not
1.90 + * necessarily with respect to other changes in the field.
1.91 + *
1.92 + * @param obj An object whose field to conditionally set
1.93 + * @param expect the expected value
1.94 + * @param update the new value
1.95 + * @return true if successful
1.96 + * @throws ClassCastException if {@code obj} is not an instance
1.97 + * of the class possessing the field established in the constructor
1.98 + */
1.99 + public abstract boolean compareAndSet(T obj, int expect, int update);
1.100 +
1.101 + /**
1.102 + * Atomically sets the field of the given object managed by this updater
1.103 + * to the given updated value if the current value {@code ==} the
1.104 + * expected value. This method is guaranteed to be atomic with respect to
1.105 + * other calls to {@code compareAndSet} and {@code set}, but not
1.106 + * necessarily with respect to other changes in the field.
1.107 + *
1.108 + * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
1.109 + * and does not provide ordering guarantees, so is only rarely an
1.110 + * appropriate alternative to {@code compareAndSet}.
1.111 + *
1.112 + * @param obj An object whose field to conditionally set
1.113 + * @param expect the expected value
1.114 + * @param update the new value
1.115 + * @return true if successful
1.116 + * @throws ClassCastException if {@code obj} is not an instance
1.117 + * of the class possessing the field established in the constructor
1.118 + */
1.119 + public abstract boolean weakCompareAndSet(T obj, int expect, int update);
1.120 +
1.121 + /**
1.122 + * Sets the field of the given object managed by this updater to the
1.123 + * given updated value. This operation is guaranteed to act as a volatile
1.124 + * store with respect to subsequent invocations of {@code compareAndSet}.
1.125 + *
1.126 + * @param obj An object whose field to set
1.127 + * @param newValue the new value
1.128 + */
1.129 + public abstract void set(T obj, int newValue);
1.130 +
1.131 + /**
1.132 + * Eventually sets the field of the given object managed by this
1.133 + * updater to the given updated value.
1.134 + *
1.135 + * @param obj An object whose field to set
1.136 + * @param newValue the new value
1.137 + * @since 1.6
1.138 + */
1.139 + public abstract void lazySet(T obj, int newValue);
1.140 +
1.141 +
1.142 + /**
1.143 + * Gets the current value held in the field of the given object managed
1.144 + * by this updater.
1.145 + *
1.146 + * @param obj An object whose field to get
1.147 + * @return the current value
1.148 + */
1.149 + public abstract int get(T obj);
1.150 +
1.151 + /**
1.152 + * Atomically sets the field of the given object managed by this updater
1.153 + * to the given value and returns the old value.
1.154 + *
1.155 + * @param obj An object whose field to get and set
1.156 + * @param newValue the new value
1.157 + * @return the previous value
1.158 + */
1.159 + public int getAndSet(T obj, int newValue) {
1.160 + for (;;) {
1.161 + int current = get(obj);
1.162 + if (compareAndSet(obj, current, newValue))
1.163 + return current;
1.164 + }
1.165 + }
1.166 +
1.167 + /**
1.168 + * Atomically increments by one the current value of the field of the
1.169 + * given object managed by this updater.
1.170 + *
1.171 + * @param obj An object whose field to get and set
1.172 + * @return the previous value
1.173 + */
1.174 + public int getAndIncrement(T obj) {
1.175 + for (;;) {
1.176 + int current = get(obj);
1.177 + int next = current + 1;
1.178 + if (compareAndSet(obj, current, next))
1.179 + return current;
1.180 + }
1.181 + }
1.182 +
1.183 + /**
1.184 + * Atomically decrements by one the current value of the field of the
1.185 + * given object managed by this updater.
1.186 + *
1.187 + * @param obj An object whose field to get and set
1.188 + * @return the previous value
1.189 + */
1.190 + public int getAndDecrement(T obj) {
1.191 + for (;;) {
1.192 + int current = get(obj);
1.193 + int next = current - 1;
1.194 + if (compareAndSet(obj, current, next))
1.195 + return current;
1.196 + }
1.197 + }
1.198 +
1.199 + /**
1.200 + * Atomically adds the given value to the current value of the field of
1.201 + * the given object managed by this updater.
1.202 + *
1.203 + * @param obj An object whose field to get and set
1.204 + * @param delta the value to add
1.205 + * @return the previous value
1.206 + */
1.207 + public int getAndAdd(T obj, int delta) {
1.208 + for (;;) {
1.209 + int current = get(obj);
1.210 + int next = current + delta;
1.211 + if (compareAndSet(obj, current, next))
1.212 + return current;
1.213 + }
1.214 + }
1.215 +
1.216 + /**
1.217 + * Atomically increments by one the current value of the field of the
1.218 + * given object managed by this updater.
1.219 + *
1.220 + * @param obj An object whose field to get and set
1.221 + * @return the updated value
1.222 + */
1.223 + public int incrementAndGet(T obj) {
1.224 + for (;;) {
1.225 + int current = get(obj);
1.226 + int next = current + 1;
1.227 + if (compareAndSet(obj, current, next))
1.228 + return next;
1.229 + }
1.230 + }
1.231 +
1.232 + /**
1.233 + * Atomically decrements by one the current value of the field of the
1.234 + * given object managed by this updater.
1.235 + *
1.236 + * @param obj An object whose field to get and set
1.237 + * @return the updated value
1.238 + */
1.239 + public int decrementAndGet(T obj) {
1.240 + for (;;) {
1.241 + int current = get(obj);
1.242 + int next = current - 1;
1.243 + if (compareAndSet(obj, current, next))
1.244 + return next;
1.245 + }
1.246 + }
1.247 +
1.248 + /**
1.249 + * Atomically adds the given value to the current value of the field of
1.250 + * the given object managed by this updater.
1.251 + *
1.252 + * @param obj An object whose field to get and set
1.253 + * @param delta the value to add
1.254 + * @return the updated value
1.255 + */
1.256 + public int addAndGet(T obj, int delta) {
1.257 + for (;;) {
1.258 + int current = get(obj);
1.259 + int next = current + delta;
1.260 + if (compareAndSet(obj, current, next))
1.261 + return next;
1.262 + }
1.263 + }
1.264 +
1.265 + /**
1.266 + * Standard hotspot implementation using intrinsics
1.267 + */
1.268 + private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
1.269 + private static final Unsafe unsafe = Unsafe.getUnsafe();
1.270 + private final long offset;
1.271 + private final Class<T> tclass;
1.272 + private final Class cclass;
1.273 +
1.274 + AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
1.275 + Field field = null;
1.276 + Class caller = null;
1.277 + int modifiers = 0;
1.278 + try {
1.279 + field = tclass.getDeclaredField(fieldName);
1.280 + caller = sun.reflect.Reflection.getCallerClass(3);
1.281 + modifiers = field.getModifiers();
1.282 + sun.reflect.misc.ReflectUtil.ensureMemberAccess(
1.283 + caller, tclass, null, modifiers);
1.284 + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
1.285 + } catch (Exception ex) {
1.286 + throw new RuntimeException(ex);
1.287 + }
1.288 +
1.289 + Class fieldt = field.getType();
1.290 + if (fieldt != int.class)
1.291 + throw new IllegalArgumentException("Must be integer type");
1.292 +
1.293 + if (!Modifier.isVolatile(modifiers))
1.294 + throw new IllegalArgumentException("Must be volatile type");
1.295 +
1.296 + this.cclass = (Modifier.isProtected(modifiers) &&
1.297 + caller != tclass) ? caller : null;
1.298 + this.tclass = tclass;
1.299 + offset = unsafe.objectFieldOffset(field);
1.300 + }
1.301 +
1.302 + private void fullCheck(T obj) {
1.303 + if (!tclass.isInstance(obj))
1.304 + throw new ClassCastException();
1.305 + if (cclass != null)
1.306 + ensureProtectedAccess(obj);
1.307 + }
1.308 +
1.309 + public boolean compareAndSet(T obj, int expect, int update) {
1.310 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
1.311 + return unsafe.compareAndSwapInt(obj, offset, expect, update);
1.312 + }
1.313 +
1.314 + public boolean weakCompareAndSet(T obj, int expect, int update) {
1.315 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
1.316 + return unsafe.compareAndSwapInt(obj, offset, expect, update);
1.317 + }
1.318 +
1.319 + public void set(T obj, int newValue) {
1.320 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
1.321 + unsafe.putIntVolatile(obj, offset, newValue);
1.322 + }
1.323 +
1.324 + public void lazySet(T obj, int newValue) {
1.325 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
1.326 + unsafe.putOrderedInt(obj, offset, newValue);
1.327 + }
1.328 +
1.329 + public final int get(T obj) {
1.330 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
1.331 + return unsafe.getIntVolatile(obj, offset);
1.332 + }
1.333 +
1.334 + private void ensureProtectedAccess(T obj) {
1.335 + if (cclass.isInstance(obj)) {
1.336 + return;
1.337 + }
1.338 + throw new RuntimeException(
1.339 + new IllegalAccessException("Class " +
1.340 + cclass.getName() +
1.341 + " can not access a protected member of class " +
1.342 + tclass.getName() +
1.343 + " using an instance of " +
1.344 + obj.getClass().getName()
1.345 + )
1.346 + );
1.347 + }
1.348 + }
1.349 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Mon Feb 09 20:32:36 2015 +0100
2.3 @@ -0,0 +1,436 @@
2.4 +/*
2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.6 + *
2.7 + * This code is free software; you can redistribute it and/or modify it
2.8 + * under the terms of the GNU General Public License version 2 only, as
2.9 + * published by the Free Software Foundation. Oracle designates this
2.10 + * particular file as subject to the "Classpath" exception as provided
2.11 + * by Oracle in the LICENSE file that accompanied this code.
2.12 + *
2.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
2.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2.16 + * version 2 for more details (a copy is included in the LICENSE file that
2.17 + * accompanied this code).
2.18 + *
2.19 + * You should have received a copy of the GNU General Public License version
2.20 + * 2 along with this work; if not, write to the Free Software Foundation,
2.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2.22 + *
2.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2.24 + * or visit www.oracle.com if you need additional information or have any
2.25 + * questions.
2.26 + */
2.27 +
2.28 +/*
2.29 + * This file is available under and governed by the GNU General Public
2.30 + * License version 2 only, as published by the Free Software Foundation.
2.31 + * However, the following notice accompanied the original version of this
2.32 + * file:
2.33 + *
2.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
2.35 + * Expert Group and released to the public domain, as explained at
2.36 + * http://creativecommons.org/publicdomain/zero/1.0/
2.37 + */
2.38 +
2.39 +package java.util.concurrent.atomic;
2.40 +import sun.misc.Unsafe;
2.41 +import java.lang.reflect.*;
2.42 +
2.43 +/**
2.44 + * A reflection-based utility that enables atomic updates to
2.45 + * designated {@code volatile long} fields of designated classes.
2.46 + * This class is designed for use in atomic data structures in which
2.47 + * several fields of the same node are independently subject to atomic
2.48 + * updates.
2.49 + *
2.50 + * <p>Note that the guarantees of the {@code compareAndSet}
2.51 + * method in this class are weaker than in other atomic classes.
2.52 + * Because this class cannot ensure that all uses of the field
2.53 + * are appropriate for purposes of atomic access, it can
2.54 + * guarantee atomicity only with respect to other invocations of
2.55 + * {@code compareAndSet} and {@code set} on the same updater.
2.56 + *
2.57 + * @since 1.5
2.58 + * @author Doug Lea
2.59 + * @param <T> The type of the object holding the updatable field
2.60 + */
2.61 +public abstract class AtomicLongFieldUpdater<T> {
2.62 + /**
2.63 + * Creates and returns an updater for objects with the given field.
2.64 + * The Class argument is needed to check that reflective types and
2.65 + * generic types match.
2.66 + *
2.67 + * @param tclass the class of the objects holding the field
2.68 + * @param fieldName the name of the field to be updated.
2.69 + * @return the updater
2.70 + * @throws IllegalArgumentException if the field is not a
2.71 + * volatile long type.
2.72 + * @throws RuntimeException with a nested reflection-based
2.73 + * exception if the class does not hold field or is the wrong type.
2.74 + */
2.75 + public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
2.76 + if (AtomicLong.VM_SUPPORTS_LONG_CAS)
2.77 + return new CASUpdater<U>(tclass, fieldName);
2.78 + else
2.79 + return new LockedUpdater<U>(tclass, fieldName);
2.80 + }
2.81 +
2.82 + /**
2.83 + * Protected do-nothing constructor for use by subclasses.
2.84 + */
2.85 + protected AtomicLongFieldUpdater() {
2.86 + }
2.87 +
2.88 + /**
2.89 + * Atomically sets the field of the given object managed by this updater
2.90 + * to the given updated value if the current value {@code ==} the
2.91 + * expected value. This method is guaranteed to be atomic with respect to
2.92 + * other calls to {@code compareAndSet} and {@code set}, but not
2.93 + * necessarily with respect to other changes in the field.
2.94 + *
2.95 + * @param obj An object whose field to conditionally set
2.96 + * @param expect the expected value
2.97 + * @param update the new value
2.98 + * @return true if successful.
2.99 + * @throws ClassCastException if {@code obj} is not an instance
2.100 + * of the class possessing the field established in the constructor.
2.101 + */
2.102 + public abstract boolean compareAndSet(T obj, long expect, long update);
2.103 +
2.104 + /**
2.105 + * Atomically sets the field of the given object managed by this updater
2.106 + * to the given updated value if the current value {@code ==} the
2.107 + * expected value. This method is guaranteed to be atomic with respect to
2.108 + * other calls to {@code compareAndSet} and {@code set}, but not
2.109 + * necessarily with respect to other changes in the field.
2.110 + *
2.111 + * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
2.112 + * and does not provide ordering guarantees, so is only rarely an
2.113 + * appropriate alternative to {@code compareAndSet}.
2.114 + *
2.115 + * @param obj An object whose field to conditionally set
2.116 + * @param expect the expected value
2.117 + * @param update the new value
2.118 + * @return true if successful.
2.119 + * @throws ClassCastException if {@code obj} is not an instance
2.120 + * of the class possessing the field established in the constructor.
2.121 + */
2.122 + public abstract boolean weakCompareAndSet(T obj, long expect, long update);
2.123 +
2.124 + /**
2.125 + * Sets the field of the given object managed by this updater to the
2.126 + * given updated value. This operation is guaranteed to act as a volatile
2.127 + * store with respect to subsequent invocations of {@code compareAndSet}.
2.128 + *
2.129 + * @param obj An object whose field to set
2.130 + * @param newValue the new value
2.131 + */
2.132 + public abstract void set(T obj, long newValue);
2.133 +
2.134 + /**
2.135 + * Eventually sets the field of the given object managed by this
2.136 + * updater to the given updated value.
2.137 + *
2.138 + * @param obj An object whose field to set
2.139 + * @param newValue the new value
2.140 + * @since 1.6
2.141 + */
2.142 + public abstract void lazySet(T obj, long newValue);
2.143 +
2.144 + /**
2.145 + * Gets the current value held in the field of the given object managed
2.146 + * by this updater.
2.147 + *
2.148 + * @param obj An object whose field to get
2.149 + * @return the current value
2.150 + */
2.151 + public abstract long get(T obj);
2.152 +
2.153 + /**
2.154 + * Atomically sets the field of the given object managed by this updater
2.155 + * to the given value and returns the old value.
2.156 + *
2.157 + * @param obj An object whose field to get and set
2.158 + * @param newValue the new value
2.159 + * @return the previous value
2.160 + */
2.161 + public long getAndSet(T obj, long newValue) {
2.162 + for (;;) {
2.163 + long current = get(obj);
2.164 + if (compareAndSet(obj, current, newValue))
2.165 + return current;
2.166 + }
2.167 + }
2.168 +
2.169 + /**
2.170 + * Atomically increments by one the current value of the field of the
2.171 + * given object managed by this updater.
2.172 + *
2.173 + * @param obj An object whose field to get and set
2.174 + * @return the previous value
2.175 + */
2.176 + public long getAndIncrement(T obj) {
2.177 + for (;;) {
2.178 + long current = get(obj);
2.179 + long next = current + 1;
2.180 + if (compareAndSet(obj, current, next))
2.181 + return current;
2.182 + }
2.183 + }
2.184 +
2.185 + /**
2.186 + * Atomically decrements by one the current value of the field of the
2.187 + * given object managed by this updater.
2.188 + *
2.189 + * @param obj An object whose field to get and set
2.190 + * @return the previous value
2.191 + */
2.192 + public long getAndDecrement(T obj) {
2.193 + for (;;) {
2.194 + long current = get(obj);
2.195 + long next = current - 1;
2.196 + if (compareAndSet(obj, current, next))
2.197 + return current;
2.198 + }
2.199 + }
2.200 +
2.201 + /**
2.202 + * Atomically adds the given value to the current value of the field of
2.203 + * the given object managed by this updater.
2.204 + *
2.205 + * @param obj An object whose field to get and set
2.206 + * @param delta the value to add
2.207 + * @return the previous value
2.208 + */
2.209 + public long getAndAdd(T obj, long delta) {
2.210 + for (;;) {
2.211 + long current = get(obj);
2.212 + long next = current + delta;
2.213 + if (compareAndSet(obj, current, next))
2.214 + return current;
2.215 + }
2.216 + }
2.217 +
2.218 + /**
2.219 + * Atomically increments by one the current value of the field of the
2.220 + * given object managed by this updater.
2.221 + *
2.222 + * @param obj An object whose field to get and set
2.223 + * @return the updated value
2.224 + */
2.225 + public long incrementAndGet(T obj) {
2.226 + for (;;) {
2.227 + long current = get(obj);
2.228 + long next = current + 1;
2.229 + if (compareAndSet(obj, current, next))
2.230 + return next;
2.231 + }
2.232 + }
2.233 +
2.234 + /**
2.235 + * Atomically decrements by one the current value of the field of the
2.236 + * given object managed by this updater.
2.237 + *
2.238 + * @param obj An object whose field to get and set
2.239 + * @return the updated value
2.240 + */
2.241 + public long decrementAndGet(T obj) {
2.242 + for (;;) {
2.243 + long current = get(obj);
2.244 + long next = current - 1;
2.245 + if (compareAndSet(obj, current, next))
2.246 + return next;
2.247 + }
2.248 + }
2.249 +
2.250 + /**
2.251 + * Atomically adds the given value to the current value of the field of
2.252 + * the given object managed by this updater.
2.253 + *
2.254 + * @param obj An object whose field to get and set
2.255 + * @param delta the value to add
2.256 + * @return the updated value
2.257 + */
2.258 + public long addAndGet(T obj, long delta) {
2.259 + for (;;) {
2.260 + long current = get(obj);
2.261 + long next = current + delta;
2.262 + if (compareAndSet(obj, current, next))
2.263 + return next;
2.264 + }
2.265 + }
2.266 +
2.267 + private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
2.268 + private static final Unsafe unsafe = Unsafe.getUnsafe();
2.269 + private final long offset;
2.270 + private final Class<T> tclass;
2.271 + private final Class cclass;
2.272 +
2.273 + CASUpdater(Class<T> tclass, String fieldName) {
2.274 + Field field = null;
2.275 + Class caller = null;
2.276 + int modifiers = 0;
2.277 + try {
2.278 + field = tclass.getDeclaredField(fieldName);
2.279 + caller = sun.reflect.Reflection.getCallerClass(3);
2.280 + modifiers = field.getModifiers();
2.281 + sun.reflect.misc.ReflectUtil.ensureMemberAccess(
2.282 + caller, tclass, null, modifiers);
2.283 + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
2.284 + } catch (Exception ex) {
2.285 + throw new RuntimeException(ex);
2.286 + }
2.287 +
2.288 + Class fieldt = field.getType();
2.289 + if (fieldt != long.class)
2.290 + throw new IllegalArgumentException("Must be long type");
2.291 +
2.292 + if (!Modifier.isVolatile(modifiers))
2.293 + throw new IllegalArgumentException("Must be volatile type");
2.294 +
2.295 + this.cclass = (Modifier.isProtected(modifiers) &&
2.296 + caller != tclass) ? caller : null;
2.297 + this.tclass = tclass;
2.298 + offset = unsafe.objectFieldOffset(field);
2.299 + }
2.300 +
2.301 + private void fullCheck(T obj) {
2.302 + if (!tclass.isInstance(obj))
2.303 + throw new ClassCastException();
2.304 + if (cclass != null)
2.305 + ensureProtectedAccess(obj);
2.306 + }
2.307 +
2.308 + public boolean compareAndSet(T obj, long expect, long update) {
2.309 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.310 + return unsafe.compareAndSwapLong(obj, offset, expect, update);
2.311 + }
2.312 +
2.313 + public boolean weakCompareAndSet(T obj, long expect, long update) {
2.314 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.315 + return unsafe.compareAndSwapLong(obj, offset, expect, update);
2.316 + }
2.317 +
2.318 + public void set(T obj, long newValue) {
2.319 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.320 + unsafe.putLongVolatile(obj, offset, newValue);
2.321 + }
2.322 +
2.323 + public void lazySet(T obj, long newValue) {
2.324 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.325 + unsafe.putOrderedLong(obj, offset, newValue);
2.326 + }
2.327 +
2.328 + public long get(T obj) {
2.329 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.330 + return unsafe.getLongVolatile(obj, offset);
2.331 + }
2.332 +
2.333 + private void ensureProtectedAccess(T obj) {
2.334 + if (cclass.isInstance(obj)) {
2.335 + return;
2.336 + }
2.337 + throw new RuntimeException(
2.338 + new IllegalAccessException("Class " +
2.339 + cclass.getName() +
2.340 + " can not access a protected member of class " +
2.341 + tclass.getName() +
2.342 + " using an instance of " +
2.343 + obj.getClass().getName()
2.344 + )
2.345 + );
2.346 + }
2.347 + }
2.348 +
2.349 +
2.350 + private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
2.351 + private static final Unsafe unsafe = Unsafe.getUnsafe();
2.352 + private final long offset;
2.353 + private final Class<T> tclass;
2.354 + private final Class cclass;
2.355 +
2.356 + LockedUpdater(Class<T> tclass, String fieldName) {
2.357 + Field field = null;
2.358 + Class caller = null;
2.359 + int modifiers = 0;
2.360 + try {
2.361 + field = tclass.getDeclaredField(fieldName);
2.362 + caller = sun.reflect.Reflection.getCallerClass(3);
2.363 + modifiers = field.getModifiers();
2.364 + sun.reflect.misc.ReflectUtil.ensureMemberAccess(
2.365 + caller, tclass, null, modifiers);
2.366 + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
2.367 + } catch (Exception ex) {
2.368 + throw new RuntimeException(ex);
2.369 + }
2.370 +
2.371 + Class fieldt = field.getType();
2.372 + if (fieldt != long.class)
2.373 + throw new IllegalArgumentException("Must be long type");
2.374 +
2.375 + if (!Modifier.isVolatile(modifiers))
2.376 + throw new IllegalArgumentException("Must be volatile type");
2.377 +
2.378 + this.cclass = (Modifier.isProtected(modifiers) &&
2.379 + caller != tclass) ? caller : null;
2.380 + this.tclass = tclass;
2.381 + offset = unsafe.objectFieldOffset(field);
2.382 + }
2.383 +
2.384 + private void fullCheck(T obj) {
2.385 + if (!tclass.isInstance(obj))
2.386 + throw new ClassCastException();
2.387 + if (cclass != null)
2.388 + ensureProtectedAccess(obj);
2.389 + }
2.390 +
2.391 + public boolean compareAndSet(T obj, long expect, long update) {
2.392 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.393 + synchronized (this) {
2.394 + long v = unsafe.getLong(obj, offset);
2.395 + if (v != expect)
2.396 + return false;
2.397 + unsafe.putLong(obj, offset, update);
2.398 + return true;
2.399 + }
2.400 + }
2.401 +
2.402 + public boolean weakCompareAndSet(T obj, long expect, long update) {
2.403 + return compareAndSet(obj, expect, update);
2.404 + }
2.405 +
2.406 + public void set(T obj, long newValue) {
2.407 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.408 + synchronized (this) {
2.409 + unsafe.putLong(obj, offset, newValue);
2.410 + }
2.411 + }
2.412 +
2.413 + public void lazySet(T obj, long newValue) {
2.414 + set(obj, newValue);
2.415 + }
2.416 +
2.417 + public long get(T obj) {
2.418 + if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
2.419 + synchronized (this) {
2.420 + return unsafe.getLong(obj, offset);
2.421 + }
2.422 + }
2.423 +
2.424 + private void ensureProtectedAccess(T obj) {
2.425 + if (cclass.isInstance(obj)) {
2.426 + return;
2.427 + }
2.428 + throw new RuntimeException(
2.429 + new IllegalAccessException("Class " +
2.430 + cclass.getName() +
2.431 + " can not access a protected member of class " +
2.432 + tclass.getName() +
2.433 + " using an instance of " +
2.434 + obj.getClass().getName()
2.435 + )
2.436 + );
2.437 + }
2.438 + }
2.439 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Mon Feb 09 20:32:36 2015 +0100
3.3 @@ -0,0 +1,304 @@
3.4 +/*
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.6 + *
3.7 + * This code is free software; you can redistribute it and/or modify it
3.8 + * under the terms of the GNU General Public License version 2 only, as
3.9 + * published by the Free Software Foundation. Oracle designates this
3.10 + * particular file as subject to the "Classpath" exception as provided
3.11 + * by Oracle in the LICENSE file that accompanied this code.
3.12 + *
3.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.16 + * version 2 for more details (a copy is included in the LICENSE file that
3.17 + * accompanied this code).
3.18 + *
3.19 + * You should have received a copy of the GNU General Public License version
3.20 + * 2 along with this work; if not, write to the Free Software Foundation,
3.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.22 + *
3.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.24 + * or visit www.oracle.com if you need additional information or have any
3.25 + * questions.
3.26 + */
3.27 +
3.28 +/*
3.29 + * This file is available under and governed by the GNU General Public
3.30 + * License version 2 only, as published by the Free Software Foundation.
3.31 + * However, the following notice accompanied the original version of this
3.32 + * file:
3.33 + *
3.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
3.35 + * Expert Group and released to the public domain, as explained at
3.36 + * http://creativecommons.org/publicdomain/zero/1.0/
3.37 + */
3.38 +
3.39 +package java.util.concurrent.atomic;
3.40 +import sun.misc.Unsafe;
3.41 +import java.lang.reflect.*;
3.42 +
3.43 +/**
3.44 + * A reflection-based utility that enables atomic updates to
3.45 + * designated {@code volatile} reference fields of designated
3.46 + * classes. This class is designed for use in atomic data structures
3.47 + * in which several reference fields of the same node are
3.48 + * independently subject to atomic updates. For example, a tree node
3.49 + * might be declared as
3.50 + *
3.51 + * <pre> {@code
3.52 + * class Node {
3.53 + * private volatile Node left, right;
3.54 + *
3.55 + * private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
3.56 + * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
3.57 + * private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
3.58 + * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
3.59 + *
3.60 + * Node getLeft() { return left; }
3.61 + * boolean compareAndSetLeft(Node expect, Node update) {
3.62 + * return leftUpdater.compareAndSet(this, expect, update);
3.63 + * }
3.64 + * // ... and so on
3.65 + * }}</pre>
3.66 + *
3.67 + * <p>Note that the guarantees of the {@code compareAndSet}
3.68 + * method in this class are weaker than in other atomic classes.
3.69 + * Because this class cannot ensure that all uses of the field
3.70 + * are appropriate for purposes of atomic access, it can
3.71 + * guarantee atomicity only with respect to other invocations of
3.72 + * {@code compareAndSet} and {@code set} on the same updater.
3.73 + *
3.74 + * @since 1.5
3.75 + * @author Doug Lea
3.76 + * @param <T> The type of the object holding the updatable field
3.77 + * @param <V> The type of the field
3.78 + */
3.79 +public abstract class AtomicReferenceFieldUpdater<T, V> {
3.80 +
3.81 + /**
3.82 + * Creates and returns an updater for objects with the given field.
3.83 + * The Class arguments are needed to check that reflective types and
3.84 + * generic types match.
3.85 + *
3.86 + * @param tclass the class of the objects holding the field.
3.87 + * @param vclass the class of the field
3.88 + * @param fieldName the name of the field to be updated.
3.89 + * @return the updater
3.90 + * @throws IllegalArgumentException if the field is not a volatile reference type.
3.91 + * @throws RuntimeException with a nested reflection-based
3.92 + * exception if the class does not hold field or is the wrong type.
3.93 + */
3.94 + public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
3.95 + return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
3.96 + vclass,
3.97 + fieldName);
3.98 + }
3.99 +
3.100 + /**
3.101 + * Protected do-nothing constructor for use by subclasses.
3.102 + */
3.103 + protected AtomicReferenceFieldUpdater() {
3.104 + }
3.105 +
3.106 + /**
3.107 + * Atomically sets the field of the given object managed by this updater
3.108 + * to the given updated value if the current value {@code ==} the
3.109 + * expected value. This method is guaranteed to be atomic with respect to
3.110 + * other calls to {@code compareAndSet} and {@code set}, but not
3.111 + * necessarily with respect to other changes in the field.
3.112 + *
3.113 + * @param obj An object whose field to conditionally set
3.114 + * @param expect the expected value
3.115 + * @param update the new value
3.116 + * @return true if successful.
3.117 + */
3.118 + public abstract boolean compareAndSet(T obj, V expect, V update);
3.119 +
3.120 + /**
3.121 + * Atomically sets the field of the given object managed by this updater
3.122 + * to the given updated value if the current value {@code ==} the
3.123 + * expected value. This method is guaranteed to be atomic with respect to
3.124 + * other calls to {@code compareAndSet} and {@code set}, but not
3.125 + * necessarily with respect to other changes in the field.
3.126 + *
3.127 + * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
3.128 + * and does not provide ordering guarantees, so is only rarely an
3.129 + * appropriate alternative to {@code compareAndSet}.
3.130 + *
3.131 + * @param obj An object whose field to conditionally set
3.132 + * @param expect the expected value
3.133 + * @param update the new value
3.134 + * @return true if successful.
3.135 + */
3.136 + public abstract boolean weakCompareAndSet(T obj, V expect, V update);
3.137 +
3.138 + /**
3.139 + * Sets the field of the given object managed by this updater to the
3.140 + * given updated value. This operation is guaranteed to act as a volatile
3.141 + * store with respect to subsequent invocations of {@code compareAndSet}.
3.142 + *
3.143 + * @param obj An object whose field to set
3.144 + * @param newValue the new value
3.145 + */
3.146 + public abstract void set(T obj, V newValue);
3.147 +
3.148 + /**
3.149 + * Eventually sets the field of the given object managed by this
3.150 + * updater to the given updated value.
3.151 + *
3.152 + * @param obj An object whose field to set
3.153 + * @param newValue the new value
3.154 + * @since 1.6
3.155 + */
3.156 + public abstract void lazySet(T obj, V newValue);
3.157 +
3.158 + /**
3.159 + * Gets the current value held in the field of the given object managed
3.160 + * by this updater.
3.161 + *
3.162 + * @param obj An object whose field to get
3.163 + * @return the current value
3.164 + */
3.165 + public abstract V get(T obj);
3.166 +
3.167 + /**
3.168 + * Atomically sets the field of the given object managed by this updater
3.169 + * to the given value and returns the old value.
3.170 + *
3.171 + * @param obj An object whose field to get and set
3.172 + * @param newValue the new value
3.173 + * @return the previous value
3.174 + */
3.175 + public V getAndSet(T obj, V newValue) {
3.176 + for (;;) {
3.177 + V current = get(obj);
3.178 + if (compareAndSet(obj, current, newValue))
3.179 + return current;
3.180 + }
3.181 + }
3.182 +
3.183 + private static final class AtomicReferenceFieldUpdaterImpl<T,V>
3.184 + extends AtomicReferenceFieldUpdater<T,V> {
3.185 + private static final Unsafe unsafe = Unsafe.getUnsafe();
3.186 + private final long offset;
3.187 + private final Class<T> tclass;
3.188 + private final Class<V> vclass;
3.189 + private final Class cclass;
3.190 +
3.191 + /*
3.192 + * Internal type checks within all update methods contain
3.193 + * internal inlined optimizations checking for the common
3.194 + * cases where the class is final (in which case a simple
3.195 + * getClass comparison suffices) or is of type Object (in
3.196 + * which case no check is needed because all objects are
3.197 + * instances of Object). The Object case is handled simply by
3.198 + * setting vclass to null in constructor. The targetCheck and
3.199 + * updateCheck methods are invoked when these faster
3.200 + * screenings fail.
3.201 + */
3.202 +
3.203 + AtomicReferenceFieldUpdaterImpl(Class<T> tclass,
3.204 + Class<V> vclass,
3.205 + String fieldName) {
3.206 + Field field = null;
3.207 + Class fieldClass = null;
3.208 + Class caller = null;
3.209 + int modifiers = 0;
3.210 + try {
3.211 + field = tclass.getDeclaredField(fieldName);
3.212 + caller = sun.reflect.Reflection.getCallerClass(3);
3.213 + modifiers = field.getModifiers();
3.214 + sun.reflect.misc.ReflectUtil.ensureMemberAccess(
3.215 + caller, tclass, null, modifiers);
3.216 + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
3.217 + fieldClass = field.getType();
3.218 + } catch (Exception ex) {
3.219 + throw new RuntimeException(ex);
3.220 + }
3.221 +
3.222 + if (vclass != fieldClass)
3.223 + throw new ClassCastException();
3.224 +
3.225 + if (!Modifier.isVolatile(modifiers))
3.226 + throw new IllegalArgumentException("Must be volatile type");
3.227 +
3.228 + this.cclass = (Modifier.isProtected(modifiers) &&
3.229 + caller != tclass) ? caller : null;
3.230 + this.tclass = tclass;
3.231 + if (vclass == Object.class)
3.232 + this.vclass = null;
3.233 + else
3.234 + this.vclass = vclass;
3.235 + offset = unsafe.objectFieldOffset(field);
3.236 + }
3.237 +
3.238 + void targetCheck(T obj) {
3.239 + if (!tclass.isInstance(obj))
3.240 + throw new ClassCastException();
3.241 + if (cclass != null)
3.242 + ensureProtectedAccess(obj);
3.243 + }
3.244 +
3.245 + void updateCheck(T obj, V update) {
3.246 + if (!tclass.isInstance(obj) ||
3.247 + (update != null && vclass != null && !vclass.isInstance(update)))
3.248 + throw new ClassCastException();
3.249 + if (cclass != null)
3.250 + ensureProtectedAccess(obj);
3.251 + }
3.252 +
3.253 + public boolean compareAndSet(T obj, V expect, V update) {
3.254 + if (obj == null || obj.getClass() != tclass || cclass != null ||
3.255 + (update != null && vclass != null &&
3.256 + vclass != update.getClass()))
3.257 + updateCheck(obj, update);
3.258 + return unsafe.compareAndSwapObject(obj, offset, expect, update);
3.259 + }
3.260 +
3.261 + public boolean weakCompareAndSet(T obj, V expect, V update) {
3.262 + // same implementation as strong form for now
3.263 + if (obj == null || obj.getClass() != tclass || cclass != null ||
3.264 + (update != null && vclass != null &&
3.265 + vclass != update.getClass()))
3.266 + updateCheck(obj, update);
3.267 + return unsafe.compareAndSwapObject(obj, offset, expect, update);
3.268 + }
3.269 +
3.270 + public void set(T obj, V newValue) {
3.271 + if (obj == null || obj.getClass() != tclass || cclass != null ||
3.272 + (newValue != null && vclass != null &&
3.273 + vclass != newValue.getClass()))
3.274 + updateCheck(obj, newValue);
3.275 + unsafe.putObjectVolatile(obj, offset, newValue);
3.276 + }
3.277 +
3.278 + public void lazySet(T obj, V newValue) {
3.279 + if (obj == null || obj.getClass() != tclass || cclass != null ||
3.280 + (newValue != null && vclass != null &&
3.281 + vclass != newValue.getClass()))
3.282 + updateCheck(obj, newValue);
3.283 + unsafe.putOrderedObject(obj, offset, newValue);
3.284 + }
3.285 +
3.286 + public V get(T obj) {
3.287 + if (obj == null || obj.getClass() != tclass || cclass != null)
3.288 + targetCheck(obj);
3.289 + return (V)unsafe.getObjectVolatile(obj, offset);
3.290 + }
3.291 +
3.292 + private void ensureProtectedAccess(T obj) {
3.293 + if (cclass.isInstance(obj)) {
3.294 + return;
3.295 + }
3.296 + throw new RuntimeException(
3.297 + new IllegalAccessException("Class " +
3.298 + cclass.getName() +
3.299 + " can not access a protected member of class " +
3.300 + tclass.getName() +
3.301 + " using an instance of " +
3.302 + obj.getClass().getName()
3.303 + )
3.304 + );
3.305 + }
3.306 + }
3.307 +}