summaryrefslogtreecommitdiff
path: root/libjava/classpath/external/jsr166/java/util/concurrent/atomic
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/external/jsr166/java/util/concurrent/atomic')
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java133
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java234
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java255
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java316
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java248
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java255
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java406
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java161
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java124
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java163
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java275
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java165
12 files changed, 2735 insertions, 0 deletions
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java
new file mode 100644
index 000000000..bd823bd2c
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicBoolean.java
@@ -0,0 +1,133 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * A <tt>boolean</tt> value that may be updated atomically. See the
+ * {@link java.util.concurrent.atomic} package specification for
+ * description of the properties of atomic variables. An
+ * <tt>AtomicBoolean</tt> is used in applications such as atomically
+ * updated flags, and cannot be used as a replacement for a
+ * {@link java.lang.Boolean}.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicBoolean implements java.io.Serializable {
+ private static final long serialVersionUID = 4654671469794556979L;
+ // setup to use Unsafe.compareAndSwapInt for updates
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long valueOffset;
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicBoolean.class.getDeclaredField("value"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile int value;
+
+ /**
+ * Creates a new <tt>AtomicBoolean</tt> with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicBoolean(boolean initialValue) {
+ value = initialValue ? 1 : 0;
+ }
+
+ /**
+ * Creates a new <tt>AtomicBoolean</tt> with initial value <tt>false</tt>.
+ */
+ public AtomicBoolean() {
+ }
+
+ /**
+ * Returns the current value.
+ *
+ * @return the current value
+ */
+ public final boolean get() {
+ return value != 0;
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(boolean expect, boolean update) {
+ int e = expect ? 1 : 0;
+ int u = update ? 1 : 0;
+ return unsafe.compareAndSwapInt(this, valueOffset, e, u);
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public boolean weakCompareAndSet(boolean expect, boolean update) {
+ int e = expect ? 1 : 0;
+ int u = update ? 1 : 0;
+ return unsafe.compareAndSwapInt(this, valueOffset, e, u);
+ }
+
+ /**
+ * Unconditionally sets to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(boolean newValue) {
+ value = newValue ? 1 : 0;
+ }
+
+ /**
+ * Eventually sets to the given value.
+ *
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(boolean newValue) {
+ int v = newValue ? 1 : 0;
+ unsafe.putOrderedInt(this, valueOffset, v);
+ }
+
+ /**
+ * Atomically sets to the given value and returns the previous value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final boolean getAndSet(boolean newValue) {
+ for (;;) {
+ boolean current = get();
+ if (compareAndSet(current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return Boolean.toString(get());
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java
new file mode 100644
index 000000000..0f723f613
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicInteger.java
@@ -0,0 +1,234 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * An <tt>int</tt> value that may be updated atomically. See the
+ * {@link java.util.concurrent.atomic} package specification for
+ * description of the properties of atomic variables. An
+ * <tt>AtomicInteger</tt> is used in applications such as atomically
+ * incremented counters, and cannot be used as a replacement for an
+ * {@link java.lang.Integer}. However, this class does extend
+ * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * deal with numerically-based classes.
+ *
+ * @since 1.5
+ * @author Doug Lea
+*/
+public class AtomicInteger extends Number implements java.io.Serializable {
+ private static final long serialVersionUID = 6214790243416807050L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long valueOffset;
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicInteger.class.getDeclaredField("value"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile int value;
+
+ /**
+ * Creates a new AtomicInteger with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicInteger(int initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Creates a new AtomicInteger with initial value <tt>0</tt>.
+ */
+ public AtomicInteger() {
+ }
+
+ /**
+ * Gets the current value.
+ *
+ * @return the current value
+ */
+ public final int get() {
+ return value;
+ }
+
+ /**
+ * Sets to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(int newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Eventually sets to the given value.
+ *
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(int newValue) {
+ unsafe.putOrderedInt(this, valueOffset, newValue);
+ }
+
+ /**
+ * Atomically sets to the given value and returns the old value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final int getAndSet(int newValue) {
+ for (;;) {
+ int current = get();
+ if (compareAndSet(current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int expect, int update) {
+ return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int expect, int update) {
+ return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically increments by one the current value.
+ *
+ * @return the previous value
+ */
+ public final int getAndIncrement() {
+ for (;;) {
+ int current = get();
+ int next = current + 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value.
+ *
+ * @return the previous value
+ */
+ public final int getAndDecrement() {
+ for (;;) {
+ int current = get();
+ int next = current - 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value.
+ *
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public final int getAndAdd(int delta) {
+ for (;;) {
+ int current = get();
+ int next = current + delta;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the current value.
+ *
+ * @return the updated value
+ */
+ public final int incrementAndGet() {
+ for (;;) {
+ int current = get();
+ int next = current + 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value.
+ *
+ * @return the updated value
+ */
+ public final int decrementAndGet() {
+ for (;;) {
+ int current = get();
+ int next = current - 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value.
+ *
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public final int addAndGet(int delta) {
+ for (;;) {
+ int current = get();
+ int next = current + delta;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return Integer.toString(get());
+ }
+
+
+ public int intValue() {
+ return get();
+ }
+
+ public long longValue() {
+ return (long)get();
+ }
+
+ public float floatValue() {
+ return (float)get();
+ }
+
+ public double doubleValue() {
+ return (double)get();
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java
new file mode 100644
index 000000000..2ad754fda
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerArray.java
@@ -0,0 +1,255 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.util.*;
+
+/**
+ * An <tt>int</tt> array in which elements may be updated atomically.
+ * See the {@link java.util.concurrent.atomic} package
+ * specification for description of the properties of atomic
+ * variables.
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicIntegerArray implements java.io.Serializable {
+ private static final long serialVersionUID = 2862133569453604235L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final int base = unsafe.arrayBaseOffset(int[].class);
+ private static final int scale = unsafe.arrayIndexScale(int[].class);
+ private final int[] array;
+
+ private long rawIndex(int i) {
+ if (i < 0 || i >= array.length)
+ throw new IndexOutOfBoundsException("index " + i);
+ return base + i * scale;
+ }
+
+ /**
+ * Creates a new AtomicIntegerArray of given length.
+ *
+ * @param length the length of the array
+ */
+ public AtomicIntegerArray(int length) {
+ array = new int[length];
+ // must perform at least one volatile write to conform to JMM
+ if (length > 0)
+ unsafe.putIntVolatile(array, rawIndex(0), 0);
+ }
+
+ /**
+ * Creates a new AtomicIntegerArray with the same length as, and
+ * all elements copied from, the given array.
+ *
+ * @param array the array to copy elements from
+ * @throws NullPointerException if array is null
+ */
+ public AtomicIntegerArray(int[] array) {
+ if (array == null)
+ throw new NullPointerException();
+ int length = array.length;
+ this.array = new int[length];
+ if (length > 0) {
+ int last = length-1;
+ for (int i = 0; i < last; ++i)
+ this.array[i] = array[i];
+ // Do the last write as volatile
+ unsafe.putIntVolatile(this.array, rawIndex(last), array[last]);
+ }
+ }
+
+ /**
+ * Returns the length of the array.
+ *
+ * @return the length of the array
+ */
+ public final int length() {
+ return array.length;
+ }
+
+ /**
+ * Gets the current value at position <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the current value
+ */
+ public final int get(int i) {
+ return unsafe.getIntVolatile(array, rawIndex(i));
+ }
+
+ /**
+ * Sets the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ */
+ public final void set(int i, int newValue) {
+ unsafe.putIntVolatile(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Eventually sets the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(int i, int newValue) {
+ unsafe.putOrderedInt(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given
+ * value and returns the old value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final int getAndSet(int i, int newValue) {
+ while (true) {
+ int current = get(i);
+ if (compareAndSet(i, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given
+ * updated value if the current value <tt>==</tt> the expected value.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int i, int expect, int update) {
+ return unsafe.compareAndSwapInt(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given
+ * updated value if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int i, int expect, int update) {
+ return compareAndSet(i, expect, update);
+ }
+
+ /**
+ * Atomically increments by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value
+ */
+ public final int getAndIncrement(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current + 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value
+ */
+ public final int getAndDecrement(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current - 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public final int getAndAdd(int i, int delta) {
+ while (true) {
+ int current = get(i);
+ int next = current + delta;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value
+ */
+ public final int incrementAndGet(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current + 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value
+ */
+ public final int decrementAndGet(int i) {
+ while (true) {
+ int current = get(i);
+ int next = current - 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public final int addAndGet(int i, int delta) {
+ while (true) {
+ int current = get(i);
+ int next = current + delta;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current values of array.
+ * @return the String representation of the current values of array.
+ */
+ public String toString() {
+ if (array.length > 0) // force volatile read
+ get(0);
+ return Arrays.toString(array);
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
new file mode 100644
index 000000000..c957bbf3f
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -0,0 +1,316 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+/**
+ * A reflection-based utility that enables atomic updates to
+ * designated <tt>volatile int</tt> fields of designated classes.
+ * This class is designed for use in atomic data structures in which
+ * several fields of the same node are independently subject to atomic
+ * updates.
+ *
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ */
+public abstract class AtomicIntegerFieldUpdater<T> {
+ /**
+ * Creates and returns an updater for objects with the given field.
+ * The Class argument is needed to check that reflective types and
+ * generic types match.
+ *
+ * @param tclass the class of the objects holding the field
+ * @param fieldName the name of the field to be updated
+ * @return the updater
+ * @throws IllegalArgumentException if the field is not a
+ * volatile integer type
+ * @throws RuntimeException with a nested reflection-based
+ * exception if the class does not hold field or is the wrong type
+ */
+ public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
+ return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicIntegerFieldUpdater() {
+ }
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value <tt>==</tt> the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not
+ * necessarily with respect to other changes in the field.
+ *
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor
+ */
+ public abstract boolean compareAndSet(T obj, int expect, int update);
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value <tt>==</tt> the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not
+ * necessarily with respect to other changes in the field.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor
+ */
+ public abstract boolean weakCompareAndSet(T obj, int expect, int update);
+
+ /**
+ * Sets the field of the given object managed by this updater to the
+ * given updated value. This operation is guaranteed to act as a volatile
+ * store with respect to subsequent invocations of
+ * <tt>compareAndSet</tt>.
+ *
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ */
+ public abstract void set(T obj, int newValue);
+
+ /**
+ * Eventually sets the field of the given object managed by this
+ * updater to the given updated value.
+ *
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public abstract void lazySet(T obj, int newValue);
+
+
+ /**
+ * Gets the current value held in the field of the given object managed
+ * by this updater.
+ *
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract int get(T obj);
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given value and returns the old value.
+ *
+ * @param obj An object whose field to get and set
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public int getAndSet(T obj, int newValue) {
+ for (;;) {
+ int current = get(obj);
+ if (compareAndSet(obj, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the previous value
+ */
+ public int getAndIncrement(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the previous value
+ */
+ public int getAndDecrement(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public int getAndAdd(T obj, int delta) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the updated value
+ */
+ public int incrementAndGet(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the updated value
+ */
+ public int decrementAndGet(T obj) {
+ for (;;) {
+ int current = get(obj);
+ int next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public int addAndGet(T obj, int delta) {
+ for (;;) {
+ int current = get(obj);
+ int next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Standard hotspot implementation using intrinsics
+ */
+ private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private final long offset;
+ private final Class<T> tclass;
+ private final Class cclass;
+
+ AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
+ Field field = null;
+ Class caller = null;
+ int modifiers = 0;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ caller = sun.reflect.Reflection.getCallerClass(3);
+ modifiers = field.getModifiers();
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ Class fieldt = field.getType();
+ if (fieldt != int.class)
+ throw new IllegalArgumentException("Must be integer type");
+
+ if (!Modifier.isVolatile(modifiers))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ private void fullCheck(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, int expect, int update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ return unsafe.compareAndSwapInt(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, int expect, int update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ return unsafe.compareAndSwapInt(obj, offset, expect, update);
+ }
+
+ public void set(T obj, int newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ unsafe.putIntVolatile(obj, offset, newValue);
+ }
+
+ public void lazySet(T obj, int newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ unsafe.putOrderedInt(obj, offset, newValue);
+ }
+
+ public final int get(T obj) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ return unsafe.getIntVolatile(obj, offset);
+ }
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException(
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java
new file mode 100644
index 000000000..fa254ba62
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLong.java
@@ -0,0 +1,248 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * A <tt>long</tt> value that may be updated atomically. See the
+ * {@link java.util.concurrent.atomic} package specification for
+ * description of the properties of atomic variables. An
+ * <tt>AtomicLong</tt> is used in applications such as atomically
+ * incremented sequence numbers, and cannot be used as a replacement
+ * for a {@link java.lang.Long}. However, this class does extend
+ * <tt>Number</tt> to allow uniform access by tools and utilities that
+ * deal with numerically-based classes.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicLong extends Number implements java.io.Serializable {
+ private static final long serialVersionUID = 1927816293512124184L;
+
+ // setup to use Unsafe.compareAndSwapLong for updates
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long valueOffset;
+
+ /**
+ * Records whether the underlying JVM supports lockless
+ * CompareAndSet for longs. While the unsafe.CompareAndSetLong
+ * method works in either case, some constructions should be
+ * handled at Java level to avoid locking user-visible locks.
+ */
+ static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
+
+ /**
+ * Returns whether underlying JVM supports lockless CompareAndSet
+ * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
+ */
+ private static native boolean VMSupportsCS8();
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicLong.class.getDeclaredField("value"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile long value;
+
+ /**
+ * Creates a new AtomicLong with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicLong(long initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Creates a new AtomicLong with initial value <tt>0</tt>.
+ */
+ public AtomicLong() {
+ }
+
+ /**
+ * Gets the current value.
+ *
+ * @return the current value
+ */
+ public final long get() {
+ return value;
+ }
+
+ /**
+ * Sets to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(long newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Eventually sets to the given value.
+ *
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(long newValue) {
+ unsafe.putOrderedLong(this, valueOffset, newValue);
+ }
+
+ /**
+ * Atomically sets to the given value and returns the old value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final long getAndSet(long newValue) {
+ while (true) {
+ long current = get();
+ if (compareAndSet(current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(long expect, long update) {
+ return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(long expect, long update) {
+ return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically increments by one the current value.
+ *
+ * @return the previous value
+ */
+ public final long getAndIncrement() {
+ while (true) {
+ long current = get();
+ long next = current + 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value.
+ *
+ * @return the previous value
+ */
+ public final long getAndDecrement() {
+ while (true) {
+ long current = get();
+ long next = current - 1;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value.
+ *
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public final long getAndAdd(long delta) {
+ while (true) {
+ long current = get();
+ long next = current + delta;
+ if (compareAndSet(current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the current value.
+ *
+ * @return the updated value
+ */
+ public final long incrementAndGet() {
+ for (;;) {
+ long current = get();
+ long next = current + 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value.
+ *
+ * @return the updated value
+ */
+ public final long decrementAndGet() {
+ for (;;) {
+ long current = get();
+ long next = current - 1;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value.
+ *
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public final long addAndGet(long delta) {
+ for (;;) {
+ long current = get();
+ long next = current + delta;
+ if (compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return Long.toString(get());
+ }
+
+
+ public int intValue() {
+ return (int)get();
+ }
+
+ public long longValue() {
+ return (long)get();
+ }
+
+ public float floatValue() {
+ return (float)get();
+ }
+
+ public double doubleValue() {
+ return (double)get();
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java
new file mode 100644
index 000000000..c582cba54
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongArray.java
@@ -0,0 +1,255 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.util.*;
+
+/**
+ * A <tt>long</tt> array in which elements may be updated atomically.
+ * See the {@link java.util.concurrent.atomic} package specification
+ * for description of the properties of atomic variables.
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class AtomicLongArray implements java.io.Serializable {
+ private static final long serialVersionUID = -2308431214976778248L;
+
+ // setup to use Unsafe.compareAndSwapInt for updates
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final int base = unsafe.arrayBaseOffset(long[].class);
+ private static final int scale = unsafe.arrayIndexScale(long[].class);
+ private final long[] array;
+
+ private long rawIndex(int i) {
+ if (i < 0 || i >= array.length)
+ throw new IndexOutOfBoundsException("index " + i);
+ return base + i * scale;
+ }
+
+ /**
+ * Creates a new AtomicLongArray of given length.
+ *
+ * @param length the length of the array
+ */
+ public AtomicLongArray(int length) {
+ array = new long[length];
+ // must perform at least one volatile write to conform to JMM
+ if (length > 0)
+ unsafe.putLongVolatile(array, rawIndex(0), 0);
+ }
+
+ /**
+ * Creates a new AtomicLongArray with the same length as, and
+ * all elements copied from, the given array.
+ *
+ * @param array the array to copy elements from
+ * @throws NullPointerException if array is null
+ */
+ public AtomicLongArray(long[] array) {
+ if (array == null)
+ throw new NullPointerException();
+ int length = array.length;
+ this.array = new long[length];
+ if (length > 0) {
+ int last = length-1;
+ for (int i = 0; i < last; ++i)
+ this.array[i] = array[i];
+ // Do the last write as volatile
+ unsafe.putLongVolatile(this.array, rawIndex(last), array[last]);
+ }
+ }
+
+ /**
+ * Returns the length of the array.
+ *
+ * @return the length of the array
+ */
+ public final int length() {
+ return array.length;
+ }
+
+ /**
+ * Gets the current value at position <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the current value
+ */
+ public final long get(int i) {
+ return unsafe.getLongVolatile(array, rawIndex(i));
+ }
+
+ /**
+ * Sets the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ */
+ public final void set(int i, long newValue) {
+ unsafe.putLongVolatile(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Eventually sets the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(int i, long newValue) {
+ unsafe.putOrderedLong(array, rawIndex(i), newValue);
+ }
+
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given value
+ * and returns the old value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final long getAndSet(int i, long newValue) {
+ while (true) {
+ long current = get(i);
+ if (compareAndSet(i, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int i, long expect, long update) {
+ return unsafe.compareAndSwapLong(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int i, long expect, long update) {
+ return compareAndSet(i, expect, update);
+ }
+
+ /**
+ * Atomically increments by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value
+ */
+ public final long getAndIncrement(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current + 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the previous value
+ */
+ public final long getAndDecrement(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current - 1;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public final long getAndAdd(int i, long delta) {
+ while (true) {
+ long current = get(i);
+ long next = current + delta;
+ if (compareAndSet(i, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value
+ */
+ public final long incrementAndGet(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current + 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the updated value
+ */
+ public final long decrementAndGet(int i) {
+ while (true) {
+ long current = get(i);
+ long next = current - 1;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the element at index <tt>i</tt>.
+ *
+ * @param i the index
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public long addAndGet(int i, long delta) {
+ while (true) {
+ long current = get(i);
+ long next = current + delta;
+ if (compareAndSet(i, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current values of array.
+ * @return the String representation of the current values of array.
+ */
+ public String toString() {
+ if (array.length > 0) // force volatile read
+ get(0);
+ return Arrays.toString(array);
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
new file mode 100644
index 000000000..f6135d1fc
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -0,0 +1,406 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+/**
+ * A reflection-based utility that enables atomic updates to
+ * designated <tt>volatile long</tt> fields of designated classes.
+ * This class is designed for use in atomic data structures in which
+ * several fields of the same node are independently subject to atomic
+ * updates.
+ *
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ */
+public abstract class AtomicLongFieldUpdater<T> {
+ /**
+ * Creates and returns an updater for objects with the given field.
+ * The Class argument is needed to check that reflective types and
+ * generic types match.
+ *
+ * @param tclass the class of the objects holding the field
+ * @param fieldName the name of the field to be updated.
+ * @return the updater
+ * @throws IllegalArgumentException if the field is not a
+ * volatile long type.
+ * @throws RuntimeException with a nested reflection-based
+ * exception if the class does not hold field or is the wrong type.
+ */
+ public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
+ if (AtomicLong.VM_SUPPORTS_LONG_CAS)
+ return new CASUpdater<U>(tclass, fieldName);
+ else
+ return new LockedUpdater<U>(tclass, fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicLongFieldUpdater() {
+ }
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value <tt>==</tt> the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not
+ * necessarily with respect to other changes in the field.
+ *
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor.
+ */
+ public abstract boolean compareAndSet(T obj, long expect, long update);
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value <tt>==</tt> the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not
+ * necessarily with respect to other changes in the field.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ * @throws ClassCastException if <tt>obj</tt> is not an instance
+ * of the class possessing the field established in the constructor.
+ */
+ public abstract boolean weakCompareAndSet(T obj, long expect, long update);
+
+ /**
+ * Sets the field of the given object managed by this updater to the
+ * given updated value. This operation is guaranteed to act as a volatile
+ * store with respect to subsequent invocations of
+ * <tt>compareAndSet</tt>.
+ *
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ */
+ public abstract void set(T obj, long newValue);
+
+ /**
+ * Eventually sets the field of the given object managed by this
+ * updater to the given updated value.
+ *
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public abstract void lazySet(T obj, long newValue);
+
+ /**
+ * Gets the current value held in the field of the given object managed
+ * by this updater.
+ *
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract long get(T obj);
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given value and returns the old value.
+ *
+ * @param obj An object whose field to get and set
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public long getAndSet(T obj, long newValue) {
+ for (;;) {
+ long current = get(obj);
+ if (compareAndSet(obj, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the previous value
+ */
+ public long getAndIncrement(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the previous value
+ */
+ public long getAndDecrement(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the previous value
+ */
+ public long getAndAdd(T obj, long delta) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically increments by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the updated value
+ */
+ public long incrementAndGet(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically decrements by one the current value of the field of the
+ * given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @return the updated value
+ */
+ public long decrementAndGet(T obj) {
+ for (;;) {
+ long current = get(obj);
+ long next = current - 1;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ /**
+ * Atomically adds the given value to the current value of the field of
+ * the given object managed by this updater.
+ *
+ * @param obj An object whose field to get and set
+ * @param delta the value to add
+ * @return the updated value
+ */
+ public long addAndGet(T obj, long delta) {
+ for (;;) {
+ long current = get(obj);
+ long next = current + delta;
+ if (compareAndSet(obj, current, next))
+ return next;
+ }
+ }
+
+ private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private final long offset;
+ private final Class<T> tclass;
+ private final Class cclass;
+
+ CASUpdater(Class<T> tclass, String fieldName) {
+ Field field = null;
+ Class caller = null;
+ int modifiers = 0;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ caller = sun.reflect.Reflection.getCallerClass(3);
+ modifiers = field.getModifiers();
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ Class fieldt = field.getType();
+ if (fieldt != long.class)
+ throw new IllegalArgumentException("Must be long type");
+
+ if (!Modifier.isVolatile(modifiers))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ private void fullCheck(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ return unsafe.compareAndSwapLong(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, long expect, long update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ return unsafe.compareAndSwapLong(obj, offset, expect, update);
+ }
+
+ public void set(T obj, long newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ unsafe.putLongVolatile(obj, offset, newValue);
+ }
+
+ public void lazySet(T obj, long newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ unsafe.putOrderedLong(obj, offset, newValue);
+ }
+
+ public long get(T obj) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ return unsafe.getLongVolatile(obj, offset);
+ }
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException (
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
+ }
+
+
+ private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private final long offset;
+ private final Class<T> tclass;
+ private final Class cclass;
+
+ LockedUpdater(Class<T> tclass, String fieldName) {
+ Field field = null;
+ Class caller = null;
+ int modifiers = 0;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ caller = sun.reflect.Reflection.getCallerClass(3);
+ modifiers = field.getModifiers();
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ Class fieldt = field.getType();
+ if (fieldt != long.class)
+ throw new IllegalArgumentException("Must be long type");
+
+ if (!Modifier.isVolatile(modifiers))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ private void fullCheck(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ synchronized(this) {
+ long v = unsafe.getLong(obj, offset);
+ if (v != expect)
+ return false;
+ unsafe.putLong(obj, offset, update);
+ return true;
+ }
+ }
+
+ public boolean weakCompareAndSet(T obj, long expect, long update) {
+ return compareAndSet(obj, expect, update);
+ }
+
+ public void set(T obj, long newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ synchronized(this) {
+ unsafe.putLong(obj, offset, newValue);
+ }
+ }
+
+ public void lazySet(T obj, long newValue) {
+ set(obj, newValue);
+ }
+
+ public long get(T obj) {
+ if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ synchronized(this) {
+ return unsafe.getLong(obj, offset);
+ }
+ }
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException (
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java
new file mode 100644
index 000000000..85335b737
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicMarkableReference.java
@@ -0,0 +1,161 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+
+/**
+ * An <tt>AtomicMarkableReference</tt> maintains an object reference
+ * along with a mark bit, that can be updated atomically.
+ * <p>
+ * <p> Implementation note. This implementation maintains markable
+ * references by creating internal objects representing "boxed"
+ * [reference, boolean] pairs.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicMarkableReference<V> {
+
+ private static class ReferenceBooleanPair<T> {
+ private final T reference;
+ private final boolean bit;
+ ReferenceBooleanPair(T r, boolean i) {
+ reference = r; bit = i;
+ }
+ }
+
+ private final AtomicReference<ReferenceBooleanPair<V>> atomicRef;
+
+ /**
+ * Creates a new <tt>AtomicMarkableReference</tt> with the given
+ * initial values.
+ *
+ * @param initialRef the initial reference
+ * @param initialMark the initial mark
+ */
+ public AtomicMarkableReference(V initialRef, boolean initialMark) {
+ atomicRef = new AtomicReference<ReferenceBooleanPair<V>> (new ReferenceBooleanPair<V>(initialRef, initialMark));
+ }
+
+ /**
+ * Returns the current value of the reference.
+ *
+ * @return the current value of the reference
+ */
+ public V getReference() {
+ return atomicRef.get().reference;
+ }
+
+ /**
+ * Returns the current value of the mark.
+ *
+ * @return the current value of the mark
+ */
+ public boolean isMarked() {
+ return atomicRef.get().bit;
+ }
+
+ /**
+ * Returns the current values of both the reference and the mark.
+ * Typical usage is <tt>boolean[1] holder; ref = v.get(holder); </tt>.
+ *
+ * @param markHolder an array of size of at least one. On return,
+ * <tt>markholder[0]</tt> will hold the value of the mark.
+ * @return the current value of the reference
+ */
+ public V get(boolean[] markHolder) {
+ ReferenceBooleanPair<V> p = atomicRef.get();
+ markHolder[0] = p.bit;
+ return p.reference;
+ }
+
+ /**
+ * Atomically sets the value of both the reference and mark
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current mark is equal to the expected mark.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedMark the expected value of the mark
+ * @param newMark the new value for the mark
+ * @return true if successful
+ */
+ public boolean weakCompareAndSet(V expectedReference,
+ V newReference,
+ boolean expectedMark,
+ boolean newMark) {
+ ReferenceBooleanPair<V> current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedMark == current.bit &&
+ ((newReference == current.reference && newMark == current.bit) ||
+ atomicRef.weakCompareAndSet(current,
+ new ReferenceBooleanPair<V>(newReference,
+ newMark)));
+ }
+
+ /**
+ * Atomically sets the value of both the reference and mark
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current mark is equal to the expected mark.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedMark the expected value of the mark
+ * @param newMark the new value for the mark
+ * @return true if successful
+ */
+ public boolean compareAndSet(V expectedReference,
+ V newReference,
+ boolean expectedMark,
+ boolean newMark) {
+ ReferenceBooleanPair<V> current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedMark == current.bit &&
+ ((newReference == current.reference && newMark == current.bit) ||
+ atomicRef.compareAndSet(current,
+ new ReferenceBooleanPair<V>(newReference,
+ newMark)));
+ }
+
+ /**
+ * Unconditionally sets the value of both the reference and mark.
+ *
+ * @param newReference the new value for the reference
+ * @param newMark the new value for the mark
+ */
+ public void set(V newReference, boolean newMark) {
+ ReferenceBooleanPair<V> current = atomicRef.get();
+ if (newReference != current.reference || newMark != current.bit)
+ atomicRef.set(new ReferenceBooleanPair<V>(newReference, newMark));
+ }
+
+ /**
+ * Atomically sets the value of the mark to the given update value
+ * if the current reference is <tt>==</tt> to the expected
+ * reference. Any given invocation of this operation may fail
+ * (return <tt>false</tt>) spuriously, but repeated invocation
+ * when the current value holds the expected value and no other
+ * thread is also attempting to set the value will eventually
+ * succeed.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newMark the new value for the mark
+ * @return true if successful
+ */
+ public boolean attemptMark(V expectedReference, boolean newMark) {
+ ReferenceBooleanPair<V> current = atomicRef.get();
+ return expectedReference == current.reference &&
+ (newMark == current.bit ||
+ atomicRef.compareAndSet
+ (current, new ReferenceBooleanPair<V>(expectedReference,
+ newMark)));
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java
new file mode 100644
index 000000000..e7c989c2b
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReference.java
@@ -0,0 +1,124 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+
+/**
+ * An object reference that may be updated atomically. See the {@link
+ * java.util.concurrent.atomic} package specification for description
+ * of the properties of atomic variables.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicReference<V> implements java.io.Serializable {
+ private static final long serialVersionUID = -1848883965231344442L;
+
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long valueOffset;
+
+ static {
+ try {
+ valueOffset = unsafe.objectFieldOffset
+ (AtomicReference.class.getDeclaredField("value"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ private volatile V value;
+
+ /**
+ * Creates a new AtomicReference with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicReference(V initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Creates a new AtomicReference with null initial value.
+ */
+ public AtomicReference() {
+ }
+
+ /**
+ * Gets the current value.
+ *
+ * @return the current value
+ */
+ public final V get() {
+ return value;
+ }
+
+ /**
+ * Sets to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(V newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Eventually sets to the given value.
+ *
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(V newValue) {
+ unsafe.putOrderedObject(this, valueOffset, newValue);
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(V expect, V update) {
+ return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically sets the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(V expect, V update) {
+ return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
+ }
+
+ /**
+ * Atomically sets to the given value and returns the old value.
+ *
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final V getAndSet(V newValue) {
+ while (true) {
+ V x = get();
+ if (compareAndSet(x, newValue))
+ return x;
+ }
+ }
+
+ /**
+ * Returns the String representation of the current value.
+ * @return the String representation of the current value.
+ */
+ public String toString() {
+ return String.valueOf(get());
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java
new file mode 100644
index 000000000..91b601ed9
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceArray.java
@@ -0,0 +1,163 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.util.*;
+
+/**
+ * An array of object references in which elements may be updated
+ * atomically. See the {@link java.util.concurrent.atomic} package
+ * specification for description of the properties of atomic
+ * variables.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> The base class of elements held in this array
+ */
+public class AtomicReferenceArray<E> implements java.io.Serializable {
+ private static final long serialVersionUID = -6209656149925076980L;
+
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final int base = unsafe.arrayBaseOffset(Object[].class);
+ private static final int scale = unsafe.arrayIndexScale(Object[].class);
+ private final Object[] array;
+
+ private long rawIndex(int i) {
+ if (i < 0 || i >= array.length)
+ throw new IndexOutOfBoundsException("index " + i);
+ return base + i * scale;
+ }
+
+ /**
+ * Creates a new AtomicReferenceArray of given length.
+ * @param length the length of the array
+ */
+ public AtomicReferenceArray(int length) {
+ array = new Object[length];
+ // must perform at least one volatile write to conform to JMM
+ if (length > 0)
+ unsafe.putObjectVolatile(array, rawIndex(0), null);
+ }
+
+ /**
+ * Creates a new AtomicReferenceArray with the same length as, and
+ * all elements copied from, the given array.
+ *
+ * @param array the array to copy elements from
+ * @throws NullPointerException if array is null
+ */
+ public AtomicReferenceArray(E[] array) {
+ if (array == null)
+ throw new NullPointerException();
+ int length = array.length;
+ this.array = new Object[length];
+ if (length > 0) {
+ int last = length-1;
+ for (int i = 0; i < last; ++i)
+ this.array[i] = array[i];
+ // Do the last write as volatile
+ E e = array[last];
+ unsafe.putObjectVolatile(this.array, rawIndex(last), e);
+ }
+ }
+
+ /**
+ * Returns the length of the array.
+ *
+ * @return the length of the array
+ */
+ public final int length() {
+ return array.length;
+ }
+
+ /**
+ * Gets the current value at position <tt>i</tt>.
+ *
+ * @param i the index
+ * @return the current value
+ */
+ public final E get(int i) {
+ return (E) unsafe.getObjectVolatile(array, rawIndex(i));
+ }
+
+ /**
+ * Sets the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ */
+ public final void set(int i, E newValue) {
+ unsafe.putObjectVolatile(array, rawIndex(i), newValue);
+ }
+
+ /**
+ * Eventually sets the element at position <tt>i</tt> to the given value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public final void lazySet(int i, E newValue) {
+ unsafe.putOrderedObject(array, rawIndex(i), newValue);
+ }
+
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given
+ * value and returns the old value.
+ *
+ * @param i the index
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public final E getAndSet(int i, E newValue) {
+ while (true) {
+ E current = get(i);
+ if (compareAndSet(i, current, newValue))
+ return current;
+ }
+ }
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given
+ * updated value if the current value <tt>==</tt> the expected value.
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that
+ * the actual value was not equal to the expected value.
+ */
+ public final boolean compareAndSet(int i, E expect, E update) {
+ return unsafe.compareAndSwapObject(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically sets the element at position <tt>i</tt> to the given
+ * updated value if the current value <tt>==</tt> the expected value.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param i the index
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public final boolean weakCompareAndSet(int i, E expect, E update) {
+ return compareAndSet(i, expect, update);
+ }
+
+ /**
+ * Returns the String representation of the current values of array.
+ * @return the String representation of the current values of array.
+ */
+ public String toString() {
+ if (array.length > 0) // force volatile read
+ get(0);
+ return Arrays.toString(array);
+ }
+
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
new file mode 100644
index 000000000..24014a9df
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -0,0 +1,275 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+import sun.misc.Unsafe;
+import java.lang.reflect.*;
+
+/**
+ * A reflection-based utility that enables atomic updates to
+ * designated <tt>volatile</tt> reference fields of designated
+ * classes. This class is designed for use in atomic data structures
+ * in which several reference fields of the same node are
+ * independently subject to atomic updates. For example, a tree node
+ * might be declared as
+ *
+ * <pre>
+ * class Node {
+ * private volatile Node left, right;
+ *
+ * private static final AtomicReferenceFieldUpdater&lt;Node, Node&gt; leftUpdater =
+ * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
+ * private static AtomicReferenceFieldUpdater&lt;Node, Node&gt; rightUpdater =
+ * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
+ *
+ * Node getLeft() { return left; }
+ * boolean compareAndSetLeft(Node expect, Node update) {
+ * return leftUpdater.compareAndSet(this, expect, update);
+ * }
+ * // ... and so on
+ * }
+ * </pre>
+ *
+ * <p>Note that the guarantees of the {@code compareAndSet}
+ * method in this class are weaker than in other atomic classes.
+ * Because this class cannot ensure that all uses of the field
+ * are appropriate for purposes of atomic access, it can
+ * guarantee atomicity only with respect to other invocations of
+ * {@code compareAndSet} and {@code set} on the same updater.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ * @param <V> The type of the field
+ */
+public abstract class AtomicReferenceFieldUpdater<T, V> {
+
+ /**
+ * Creates and returns an updater for objects with the given field.
+ * The Class arguments are needed to check that reflective types and
+ * generic types match.
+ *
+ * @param tclass the class of the objects holding the field.
+ * @param vclass the class of the field
+ * @param fieldName the name of the field to be updated.
+ * @return the updater
+ * @throws IllegalArgumentException if the field is not a volatile reference type.
+ * @throws RuntimeException with a nested reflection-based
+ * exception if the class does not hold field or is the wrong type.
+ */
+ public static <U, W> AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName) {
+ return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
+ vclass,
+ fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicReferenceFieldUpdater() {
+ }
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value <tt>==</tt> the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not
+ * necessarily with respect to other changes in the field.
+ *
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public abstract boolean compareAndSet(T obj, V expect, V update);
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given updated value if the current value <tt>==</tt> the
+ * expected value. This method is guaranteed to be atomic with respect to
+ * other calls to <tt>compareAndSet</tt> and <tt>set</tt>, but not
+ * necessarily with respect to other changes in the field.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param obj An object whose field to conditionally set
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful.
+ */
+ public abstract boolean weakCompareAndSet(T obj, V expect, V update);
+
+ /**
+ * Sets the field of the given object managed by this updater to the
+ * given updated value. This operation is guaranteed to act as a volatile
+ * store with respect to subsequent invocations of
+ * <tt>compareAndSet</tt>.
+ *
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ */
+ public abstract void set(T obj, V newValue);
+
+ /**
+ * Eventually sets the field of the given object managed by this
+ * updater to the given updated value.
+ *
+ * @param obj An object whose field to set
+ * @param newValue the new value
+ * @since 1.6
+ */
+ public abstract void lazySet(T obj, V newValue);
+
+ /**
+ * Gets the current value held in the field of the given object managed
+ * by this updater.
+ *
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract V get(T obj);
+
+ /**
+ * Atomically sets the field of the given object managed by this updater
+ * to the given value and returns the old value.
+ *
+ * @param obj An object whose field to get and set
+ * @param newValue the new value
+ * @return the previous value
+ */
+ public V getAndSet(T obj, V newValue) {
+ for (;;) {
+ V current = get(obj);
+ if (compareAndSet(obj, current, newValue))
+ return current;
+ }
+ }
+
+ private static final class AtomicReferenceFieldUpdaterImpl<T,V>
+ extends AtomicReferenceFieldUpdater<T,V> {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private final long offset;
+ private final Class<T> tclass;
+ private final Class<V> vclass;
+ private final Class cclass;
+
+ /*
+ * Internal type checks within all update methods contain
+ * internal inlined optimizations checking for the common
+ * cases where the class is final (in which case a simple
+ * getClass comparison suffices) or is of type Object (in
+ * which case no check is needed because all objects are
+ * instances of Object). The Object case is handled simply by
+ * setting vclass to null in constructor. The targetCheck and
+ * updateCheck methods are invoked when these faster
+ * screenings fail.
+ */
+
+ AtomicReferenceFieldUpdaterImpl(Class<T> tclass,
+ Class<V> vclass,
+ String fieldName) {
+ Field field = null;
+ Class fieldClass = null;
+ Class caller = null;
+ int modifiers = 0;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ caller = sun.reflect.Reflection.getCallerClass(3);
+ modifiers = field.getModifiers();
+ sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+ caller, tclass, null, modifiers);
+ sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+ fieldClass = field.getType();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ if (vclass != fieldClass)
+ throw new ClassCastException();
+
+ if (!Modifier.isVolatile(modifiers))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.cclass = (Modifier.isProtected(modifiers) &&
+ caller != tclass) ? caller : null;
+ this.tclass = tclass;
+ if (vclass == Object.class)
+ this.vclass = null;
+ else
+ this.vclass = vclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ void targetCheck(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ void updateCheck(T obj, V update) {
+ if (!tclass.isInstance(obj) ||
+ (update != null && vclass != null && !vclass.isInstance(update)))
+ throw new ClassCastException();
+ if (cclass != null)
+ ensureProtectedAccess(obj);
+ }
+
+ public boolean compareAndSet(T obj, V expect, V update) {
+ if (obj == null || obj.getClass() != tclass || cclass != null ||
+ (update != null && vclass != null &&
+ vclass != update.getClass()))
+ updateCheck(obj, update);
+ return unsafe.compareAndSwapObject(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, V expect, V update) {
+ // same implementation as strong form for now
+ if (obj == null || obj.getClass() != tclass || cclass != null ||
+ (update != null && vclass != null &&
+ vclass != update.getClass()))
+ updateCheck(obj, update);
+ return unsafe.compareAndSwapObject(obj, offset, expect, update);
+ }
+
+ public void set(T obj, V newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null ||
+ (newValue != null && vclass != null &&
+ vclass != newValue.getClass()))
+ updateCheck(obj, newValue);
+ unsafe.putObjectVolatile(obj, offset, newValue);
+ }
+
+ public void lazySet(T obj, V newValue) {
+ if (obj == null || obj.getClass() != tclass || cclass != null ||
+ (newValue != null && vclass != null &&
+ vclass != newValue.getClass()))
+ updateCheck(obj, newValue);
+ unsafe.putOrderedObject(obj, offset, newValue);
+ }
+
+ public V get(T obj) {
+ if (obj == null || obj.getClass() != tclass || cclass != null)
+ targetCheck(obj);
+ return (V)unsafe.getObjectVolatile(obj, offset);
+ }
+
+ private void ensureProtectedAccess(T obj) {
+ if (cclass.isInstance(obj)) {
+ return;
+ }
+ throw new RuntimeException (
+ new IllegalAccessException("Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()
+ )
+ );
+ }
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java
new file mode 100644
index 000000000..558808216
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/atomic/AtomicStampedReference.java
@@ -0,0 +1,165 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.atomic;
+
+/**
+ * An <tt>AtomicStampedReference</tt> maintains an object reference
+ * along with an integer "stamp", that can be updated atomically.
+ *
+ * <p> Implementation note. This implementation maintains stamped
+ * references by creating internal objects representing "boxed"
+ * [reference, integer] pairs.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicStampedReference<V> {
+
+ private static class ReferenceIntegerPair<T> {
+ private final T reference;
+ private final int integer;
+ ReferenceIntegerPair(T r, int i) {
+ reference = r; integer = i;
+ }
+ }
+
+ private final AtomicReference<ReferenceIntegerPair<V>> atomicRef;
+
+ /**
+ * Creates a new <tt>AtomicStampedReference</tt> with the given
+ * initial values.
+ *
+ * @param initialRef the initial reference
+ * @param initialStamp the initial stamp
+ */
+ public AtomicStampedReference(V initialRef, int initialStamp) {
+ atomicRef = new AtomicReference<ReferenceIntegerPair<V>>
+ (new ReferenceIntegerPair<V>(initialRef, initialStamp));
+ }
+
+ /**
+ * Returns the current value of the reference.
+ *
+ * @return the current value of the reference
+ */
+ public V getReference() {
+ return atomicRef.get().reference;
+ }
+
+ /**
+ * Returns the current value of the stamp.
+ *
+ * @return the current value of the stamp
+ */
+ public int getStamp() {
+ return atomicRef.get().integer;
+ }
+
+ /**
+ * Returns the current values of both the reference and the stamp.
+ * Typical usage is <tt>int[1] holder; ref = v.get(holder); </tt>.
+ *
+ * @param stampHolder an array of size of at least one. On return,
+ * <tt>stampholder[0]</tt> will hold the value of the stamp.
+ * @return the current value of the reference
+ */
+ public V get(int[] stampHolder) {
+ ReferenceIntegerPair<V> p = atomicRef.get();
+ stampHolder[0] = p.integer;
+ return p.reference;
+ }
+
+ /**
+ * Atomically sets the value of both the reference and stamp
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current stamp is equal to the expected stamp.
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedStamp the expected value of the stamp
+ * @param newStamp the new value for the stamp
+ * @return true if successful
+ */
+ public boolean weakCompareAndSet(V expectedReference,
+ V newReference,
+ int expectedStamp,
+ int newStamp) {
+ ReferenceIntegerPair<V> current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedStamp == current.integer &&
+ ((newReference == current.reference &&
+ newStamp == current.integer) ||
+ atomicRef.weakCompareAndSet(current,
+ new ReferenceIntegerPair<V>(newReference,
+ newStamp)));
+ }
+
+ /**
+ * Atomically sets the value of both the reference and stamp
+ * to the given update values if the
+ * current reference is <tt>==</tt> to the expected reference
+ * and the current stamp is equal to the expected stamp.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newReference the new value for the reference
+ * @param expectedStamp the expected value of the stamp
+ * @param newStamp the new value for the stamp
+ * @return true if successful
+ */
+ public boolean compareAndSet(V expectedReference,
+ V newReference,
+ int expectedStamp,
+ int newStamp) {
+ ReferenceIntegerPair<V> current = atomicRef.get();
+ return expectedReference == current.reference &&
+ expectedStamp == current.integer &&
+ ((newReference == current.reference &&
+ newStamp == current.integer) ||
+ atomicRef.compareAndSet(current,
+ new ReferenceIntegerPair<V>(newReference,
+ newStamp)));
+ }
+
+
+ /**
+ * Unconditionally sets the value of both the reference and stamp.
+ *
+ * @param newReference the new value for the reference
+ * @param newStamp the new value for the stamp
+ */
+ public void set(V newReference, int newStamp) {
+ ReferenceIntegerPair<V> current = atomicRef.get();
+ if (newReference != current.reference || newStamp != current.integer)
+ atomicRef.set(new ReferenceIntegerPair<V>(newReference, newStamp));
+ }
+
+ /**
+ * Atomically sets the value of the stamp to the given update value
+ * if the current reference is <tt>==</tt> to the expected
+ * reference. Any given invocation of this operation may fail
+ * (return <tt>false</tt>) spuriously, but repeated invocation
+ * when the current value holds the expected value and no other
+ * thread is also attempting to set the value will eventually
+ * succeed.
+ *
+ * @param expectedReference the expected value of the reference
+ * @param newStamp the new value for the stamp
+ * @return true if successful
+ */
+ public boolean attemptStamp(V expectedReference, int newStamp) {
+ ReferenceIntegerPair<V> current = atomicRef.get();
+ return expectedReference == current.reference &&
+ (newStamp == current.integer ||
+ atomicRef.compareAndSet(current,
+ new ReferenceIntegerPair<V>(expectedReference,
+ newStamp)));
+ }
+}