You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by nd...@apache.org on 2006/08/24 05:42:33 UTC
svn commit: r434296 [7/19] - in /incubator/harmony/enhanced/classlib/trunk:
make/ modules/concurrent/ modules/concurrent/.settings/
modules/concurrent/META-INF/ modules/concurrent/make/
modules/concurrent/src/ modules/concurrent/src/main/ modules/concu...
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,258 @@
+/*
+ * 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 <tt>compareAndSet</tt> 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 and volatile
+ * semantics only with respect to other invocations of
+ * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ */
+public abstract class AtomicIntegerFieldUpdater<T> {
+ /**
+ * Creates 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 set the value of 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 set the value of 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, and may fail spuriously.
+ * @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);
+
+ /**
+ * Set the field of the given object managed by this updater. 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);
+
+ /**
+ * Get the current value held in the field by the given object.
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract int get(T obj);
+
+ /**
+ * Set to the given value and return 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 increment by one the current value.
+ * @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 decrement by one the current value.
+ * @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 add the given value to current value.
+ * @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 increment by one the current value.
+ * @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 decrement by one the current value.
+ * @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 add the given value to current value.
+ * @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;
+
+ AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
+ Field field = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ } 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(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ public boolean compareAndSet(T obj, int expect, int update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapInt(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, int expect, int update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapInt(obj, offset, expect, update);
+ }
+
+ public void set(T obj, int newValue) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ unsafe.putIntVolatile(obj, offset, newValue);
+ }
+
+ public final int get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.getIntVolatile(obj, offset);
+ }
+ }
+}
+
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,232 @@
+/*
+ * 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;
+
+ /**
+ * Record 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;
+
+ /**
+ * Create a new AtomicLong with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicLong(long initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Create a new AtomicLong with initial value <tt>0</tt>.
+ */
+ public AtomicLong() {
+ }
+
+ /**
+ * Get the current value.
+ *
+ * @return the current value
+ */
+ public final long get() {
+ return value;
+ }
+
+ /**
+ * Set to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(long newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Set to the give value and return 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 set 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 set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @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 increment 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 decrement 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 add the given value to 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 increment 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 decrement 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 add the given value to 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();
+ }
+
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,240 @@
+/*
+ * 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;
+ }
+
+ /**
+ * Create 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);
+ }
+
+ /**
+ * Create 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;
+ }
+
+ /**
+ * Get 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));
+ }
+
+ /**
+ * Set 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);
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value and return 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 set 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 set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @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 increment 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 decrement 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 add the given value to 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 increment 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 decrement 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 add the given value to 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);
+ }
+
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,317 @@
+/*
+ * 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 <tt>compareAndSet</tt> 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 and volatile
+ * semantics only with respect to other invocations of
+ * <tt>compareAndSet</tt> and <tt>set</tt>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <T> The type of the object holding the updatable field
+ */
+public abstract class AtomicLongFieldUpdater<T> {
+ /**
+ * Creates 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 set the value of 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 set the value of 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, and may fail spuriously.
+ * @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);
+
+ /**
+ * Set the field of the given object managed by this updater. 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);
+
+ /**
+ * Get the current value held in the field by the given object.
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract long get(T obj);
+
+ /**
+ * Set to the given value and return 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 increment by one the current value.
+ * @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 decrement by one the current value.
+ * @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 add the given value to current value.
+ * @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 increment by one the current value.
+ * @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 decrement by one the current value.
+ * @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 add the given value to current value.
+ * @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;
+
+ CASUpdater(Class<T> tclass, String fieldName) {
+ Field field = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ } 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(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapLong(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, long expect, long update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapLong(obj, offset, expect, update);
+ }
+
+ public void set(T obj, long newValue) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ unsafe.putLongVolatile(obj, offset, newValue);
+ }
+
+ public long get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return unsafe.getLongVolatile(obj, offset);
+ }
+ }
+
+
+ private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private final long offset;
+ private final Class<T> tclass;
+
+ LockedUpdater(Class<T> tclass, String fieldName) {
+ Field field = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ } 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(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+ public boolean compareAndSet(T obj, long expect, long update) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ 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 (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ synchronized(this) {
+ unsafe.putLong(obj, offset, newValue);
+ }
+ }
+
+ public long get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ synchronized(this) {
+ return unsafe.getLong(obj, offset);
+ }
+ }
+ }
+}
+
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java Wed Aug 23 20:42:25 2006
@@ -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;
+
+/**
+ * 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. 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 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 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 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 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 current = atomicRef.get();
+ return expectedReference == current.reference &&
+ (newMark == current.bit ||
+ atomicRef.compareAndSet
+ (current, new ReferenceBooleanPair<V>(expectedReference,
+ newMark)));
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicMarkableReference.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,112 @@
+/*
+ * 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;
+
+ /**
+ * Create a new AtomicReference with the given initial value.
+ *
+ * @param initialValue the initial value
+ */
+ public AtomicReference(V initialValue) {
+ value = initialValue;
+ }
+
+ /**
+ * Create a new AtomicReference with null initial value.
+ */
+ public AtomicReference() {
+ }
+
+ /**
+ * Get the current value.
+ *
+ * @return the current value
+ */
+ public final V get() {
+ return value;
+ }
+
+ /**
+ * Set to the given value.
+ *
+ * @param newValue the new value
+ */
+ public final void set(V newValue) {
+ value = newValue;
+ }
+
+ /**
+ * Atomically set 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 set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @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);
+ }
+
+ /**
+ * Set to the given value and return 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());
+ }
+
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,149 @@
+/*
+ * 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;
+ }
+
+ /**
+ * Create 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);
+ }
+
+ /**
+ * Create 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;
+ }
+
+ /**
+ * Get 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));
+ }
+
+ /**
+ * Set 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);
+ }
+
+ /**
+ * Set the element at position <tt>i</tt> to the given value and return 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 set 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, E expect, E update) {
+ return unsafe.compareAndSwapObject(array, rawIndex(i),
+ expect, update);
+ }
+
+ /**
+ * Atomically set the value to the given updated value
+ * if the current value <tt>==</tt> the expected value.
+ * May fail spuriously.
+ * @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);
+ }
+
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,195 @@
+/*
+ * 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<Node, Node> leftUpdater =
+ * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
+ * private static AtomicReferenceFieldUpdater<Node, Node> 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 <tt>compareAndSet</tt>
+ * 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 and volatile
+ * semantics only with respect to other invocations of
+ * <tt>compareAndSet</tt> and <tt>set</tt>.
+ * @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 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) {
+ // Currently rely on standard intrinsics implementation
+ return new AtomicReferenceFieldUpdaterImpl<U,W>(tclass,
+ vclass,
+ fieldName);
+ }
+
+ /**
+ * Protected do-nothing constructor for use by subclasses.
+ */
+ protected AtomicReferenceFieldUpdater() {
+ }
+
+ /**
+ * Atomically set the value of 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 set the value of 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, and may fail spuriously.
+ * @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);
+
+ /**
+ * Set the field of the given object managed by this updater. 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);
+
+ /**
+ * Get the current value held in the field by the given object.
+ * @param obj An object whose field to get
+ * @return the current value
+ */
+ public abstract V get(T obj);
+
+ /**
+ * Set to the given value and return 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;
+ }
+ }
+
+ /**
+ * Standard hotspot implementation using intrinsics
+ */
+ private static 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;
+
+ AtomicReferenceFieldUpdaterImpl(Class<T> tclass, Class<V> vclass, String fieldName) {
+ Field field = null;
+ Class fieldClass = null;
+ try {
+ field = tclass.getDeclaredField(fieldName);
+ fieldClass = field.getType();
+ } catch(Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ if (vclass != fieldClass)
+ throw new ClassCastException();
+
+ if (!Modifier.isVolatile(field.getModifiers()))
+ throw new IllegalArgumentException("Must be volatile type");
+
+ this.tclass = tclass;
+ this.vclass = vclass;
+ offset = unsafe.objectFieldOffset(field);
+ }
+
+
+ public boolean compareAndSet(T obj, V expect, V update) {
+ if (!tclass.isInstance(obj) ||
+ (update != null && !vclass.isInstance(update)))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapObject(obj, offset, expect, update);
+ }
+
+ public boolean weakCompareAndSet(T obj, V expect, V update) {
+ // same implementation as strong form for now
+ if (!tclass.isInstance(obj) ||
+ (update != null && !vclass.isInstance(update)))
+ throw new ClassCastException();
+ return unsafe.compareAndSwapObject(obj, offset, expect, update);
+ }
+
+
+ public void set(T obj, V newValue) {
+ if (!tclass.isInstance(obj) ||
+ (newValue != null && !vclass.isInstance(newValue)))
+ throw new ClassCastException();
+ unsafe.putObjectVolatile(obj, offset, newValue);
+ }
+
+ public V get(T obj) {
+ if (!tclass.isInstance(obj))
+ throw new ClassCastException();
+ return (V)unsafe.getObjectVolatile(obj, offset);
+ }
+ }
+}
+
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java Wed Aug 23 20:42:25 2006
@@ -0,0 +1,167 @@
+/*
+ * 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. 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 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 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 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 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 current = atomicRef.get();
+ return expectedReference == current.reference &&
+ (newStamp == current.integer ||
+ atomicRef.compareAndSet(current,
+ new ReferenceIntegerPair<V>(expectedReference,
+ newStamp)));
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/AtomicStampedReference.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/package.html
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/package.html?rev=434296&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/package.html (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/package.html Wed Aug 23 20:42:25 2006
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Atomics</title>
+</head>
+
+<body>
+
+A small toolkit of classes that support lock-free thread-safe
+programming on single variables. In essence, the classes in this
+package extend the notion of <tt>volatile</tt> values, fields, and
+array elements to those that also provide an atomic conditional update
+operation of the form:
+
+<pre>
+ boolean compareAndSet(expectedValue, updateValue);
+</pre>
+
+<p> This method (which varies in argument types across different
+classes) atomically sets a variable to the <tt>updateValue</tt> if it
+currently holds the <tt>expectedValue</tt>, reporting <tt>true</tt> on
+success. The classes in this package also contain methods to get and
+unconditionally set values, as well as a weaker conditional atomic
+update operation <tt> weakCompareAndSet</tt>. The weak version may be
+more efficient in the normal case, but differs in that any given
+invocation of <tt>weakCompareAndSet</tt> method may fail, even
+spuriously (that is, for no apparent reason). A <tt>false</tt> return
+means only that the operation may be retried if desired, relying on
+the guarantee that repeated invocation when the variable holds
+<tt>expectedValue</tt> and no other thread is also attempting to set
+the variable will eventually succeed.
+
+<p> The specifications of these methods enable implementations to
+employ efficient machine-level atomic instructions that are available
+on contemporary processors. However on some platforms, support may
+entail some form of internal locking. Thus the methods are not
+strictly guaranteed to be non-blocking --
+a thread may block transiently before performing the operation.
+
+<p> Instances of classes {@link
+java.util.concurrent.atomic.AtomicBoolean}, {@link
+java.util.concurrent.atomic.AtomicInteger}, {@link
+java.util.concurrent.atomic.AtomicLong}, and {@link
+java.util.concurrent.atomic.AtomicReference} each provide access and
+updates to a single variable of the corresponding type. Each class
+also provides appropriate utility methods for that type. For example,
+classes <tt>AtomicLong</tt> and <tt>AtomicInteger</tt> provide atomic
+increment methods. One application is to generate sequence numbers,
+as in:
+
+<pre>
+class Sequencer {
+ private AtomicLong sequenceNumber = new AtomicLong(0);
+ public long next() { return sequenceNumber.getAndIncrement(); }
+}
+</pre>
+
+<p>The memory effects for accesses and updates of atomics generally follow the
+rules for volatiles:
+
+<ul>
+
+ <li> <tt>get</tt> has the memory effects of reading a
+<tt>volatile</tt> variable.
+
+ <li> <tt>set</tt> has the memory effects of writing (assigning) a
+<tt>volatile</tt> variable.
+
+ <li><tt>weakCompareAndSet</tt> atomically reads and conditionally
+ writes a variable, is ordered with respect to other
+ memory operations on that variable, but otherwise acts as an
+ ordinary non-volatile memory operation.
+
+ <li> <tt>compareAndSet</tt>
+ and all other read-and-update operations such as <tt>getAndIncrement</tt>
+ have the memory effects of both reading and
+ writing <tt>volatile</tt> variables.
+</ul>
+
+<p>In addition to classes representing single values, this package
+contains <em>Updater</em> classes that can be used to obtain
+<tt>compareAndSet</tt> operations on any selected <tt>volatile</tt>
+field of any selected class. {@link
+java.util.concurrent.atomic.AtomicReferenceFieldUpdater}, {@link
+java.util.concurrent.atomic.AtomicIntegerFieldUpdater}, and {@link
+java.util.concurrent.atomic.AtomicLongFieldUpdater} are
+reflection-based utilities that provide access to the associated field
+types. These are mainly of use in atomic data structures in which
+several <tt>volatile</tt> fields of the same node (for example, the
+links of a tree node) are independently subject to atomic
+updates. These classes enable greater flexibility in how and when to
+use atomic updates, at the expense of more awkward reflection-based
+setup, less convenient usage, and weaker guarantees.
+
+<p>The {@link java.util.concurrent.atomic.AtomicIntegerArray}, {@link
+java.util.concurrent.atomic.AtomicLongArray}, and {@link
+java.util.concurrent.atomic.AtomicReferenceArray} classes further
+extend atomic operation support to arrays of these types. These
+classes are also notable in providing <tt>volatile</tt> access
+semantics for their array elements, which is not supported for
+ordinary arrays.
+
+<p> The {@link java.util.concurrent.atomic.AtomicMarkableReference}
+class associates a single boolean with a reference. For example, this
+bit might be used inside a data structure to mean that the object
+being referenced has logically been deleted. The {@link
+java.util.concurrent.atomic.AtomicStampedReference} class associates
+an integer value with a reference. This may be used for example, to
+represent version numbers corresponding to series of updates.
+
+<p> Atomic classes are designed primarily as building blocks for
+implementing non-blocking data structures and related infrastructure
+classes. The <tt>compareAndSet</tt> method is not a general
+replacement for locking. It applies only when critical updates for an
+object are confined to a <em>single</em> variable.
+
+<p> Atomic classes are not general purpose replacements for
+<tt>java.lang.Integer</tt> and related classes. They do <em>not</em>
+define methods such as <tt>hashCode</tt> and
+<tt>compareTo</tt>. (Because atomic variables are expected to be
+mutated, they are poor choices for hash table keys.) Additionally,
+classes are provided only for those types that are commonly useful in
+intended applications. For example, there is no atomic class for
+representing <tt>byte</tt>. In those infrequent cases where you would
+like to do so, you can use an <tt>AtomicInteger</tt> to hold
+<tt>byte</tt> values, and cast appropriately. You can also hold floats
+using <tt>Float.floatToIntBits</tt> and <tt>Float.intBitstoFloat</tt>
+conversions, and doubles using <tt>Double.doubleToLongBits</tt> and
+<tt>Double.longBitsToDouble</tt> conversions.
+
+@since 1.5
+
+</body> </html>
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/atomic/package.html
------------------------------------------------------------------------------
svn:eol-style = native