1.1 --- a/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Sat Mar 19 10:54:10 2016 +0100
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Sat Mar 19 11:01:40 2016 +0100
1.3 @@ -36,8 +36,6 @@
1.4 package java.util.concurrent.locks;
1.5 import java.util.*;
1.6 import java.util.concurrent.*;
1.7 -import java.util.concurrent.atomic.*;
1.8 -import sun.misc.Unsafe;
1.9
1.10 /**
1.11 * A version of {@link AbstractQueuedSynchronizer} in
1.12 @@ -340,7 +338,11 @@
1.13 */
1.14 protected final boolean compareAndSetState(long expect, long update) {
1.15 // See below for intrinsics setup to support this
1.16 - return unsafe.compareAndSwapLong(this, stateOffset, expect, update);
1.17 + if (this.state == expect) {
1.18 + this.state = update;
1.19 + return true;
1.20 + }
1.21 + return false;
1.22 }
1.23
1.24 // Queuing utilities
1.25 @@ -2043,49 +2045,25 @@
1.26 }
1.27
1.28 /**
1.29 - * Setup to support compareAndSet. We need to natively implement
1.30 - * this here: For the sake of permitting future enhancements, we
1.31 - * cannot explicitly subclass AtomicLong, which would be
1.32 - * efficient and useful otherwise. So, as the lesser of evils, we
1.33 - * natively implement using hotspot intrinsics API. And while we
1.34 - * are at it, we do the same for other CASable fields (which could
1.35 - * otherwise be done with atomic field updaters).
1.36 - */
1.37 - private static final Unsafe unsafe = Unsafe.getUnsafe();
1.38 - private static final long stateOffset;
1.39 - private static final long headOffset;
1.40 - private static final long tailOffset;
1.41 - private static final long waitStatusOffset;
1.42 - private static final long nextOffset;
1.43 -
1.44 - static {
1.45 - try {
1.46 - stateOffset = unsafe.objectFieldOffset
1.47 - (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
1.48 - headOffset = unsafe.objectFieldOffset
1.49 - (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
1.50 - tailOffset = unsafe.objectFieldOffset
1.51 - (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
1.52 - waitStatusOffset = unsafe.objectFieldOffset
1.53 - (Node.class.getDeclaredField("waitStatus"));
1.54 - nextOffset = unsafe.objectFieldOffset
1.55 - (Node.class.getDeclaredField("next"));
1.56 -
1.57 - } catch (Exception ex) { throw new Error(ex); }
1.58 - }
1.59 -
1.60 - /**
1.61 * CAS head field. Used only by enq.
1.62 */
1.63 private final boolean compareAndSetHead(Node update) {
1.64 - return unsafe.compareAndSwapObject(this, headOffset, null, update);
1.65 + if (head == null) {
1.66 + head = update;
1.67 + return true;
1.68 + }
1.69 + return false;
1.70 }
1.71
1.72 /**
1.73 * CAS tail field. Used only by enq.
1.74 */
1.75 private final boolean compareAndSetTail(Node expect, Node update) {
1.76 - return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
1.77 + if (tail == null) {
1.78 + tail = update;
1.79 + return true;
1.80 + }
1.81 + return false;
1.82 }
1.83
1.84 /**
1.85 @@ -2094,8 +2072,11 @@
1.86 private static final boolean compareAndSetWaitStatus(Node node,
1.87 int expect,
1.88 int update) {
1.89 - return unsafe.compareAndSwapInt(node, waitStatusOffset,
1.90 - expect, update);
1.91 + if (node.waitStatus == expect) {
1.92 + node.waitStatus = update;
1.93 + return true;
1.94 + }
1.95 + return false;
1.96 }
1.97
1.98 /**
1.99 @@ -2104,6 +2085,10 @@
1.100 private static final boolean compareAndSetNext(Node node,
1.101 Node expect,
1.102 Node update) {
1.103 - return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
1.104 + if (node.next == expect) {
1.105 + node.next = update;
1.106 + return true;
1.107 + }
1.108 + return false;
1.109 }
1.110 }
2.1 --- a/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Sat Mar 19 10:54:10 2016 +0100
2.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Sat Mar 19 11:01:40 2016 +0100
2.3 @@ -36,8 +36,6 @@
2.4 package java.util.concurrent.locks;
2.5 import java.util.*;
2.6 import java.util.concurrent.*;
2.7 -import java.util.concurrent.atomic.*;
2.8 -import sun.misc.Unsafe;
2.9
2.10 /**
2.11 * Provides a framework for implementing blocking locks and related
2.12 @@ -563,7 +561,11 @@
2.13 */
2.14 protected final boolean compareAndSetState(int expect, int update) {
2.15 // See below for intrinsics setup to support this
2.16 - return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
2.17 + if (this.state == expect) {
2.18 + this.state = update;
2.19 + return true;
2.20 + }
2.21 + return false;
2.22 }
2.23
2.24 // Queuing utilities
2.25 @@ -2272,41 +2274,28 @@
2.26 * are at it, we do the same for other CASable fields (which could
2.27 * otherwise be done with atomic field updaters).
2.28 */
2.29 - private static final Unsafe unsafe = Unsafe.getUnsafe();
2.30 - private static final long stateOffset;
2.31 - private static final long headOffset;
2.32 - private static final long tailOffset;
2.33 - private static final long waitStatusOffset;
2.34 - private static final long nextOffset;
2.35
2.36 - static {
2.37 - try {
2.38 - stateOffset = unsafe.objectFieldOffset
2.39 - (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
2.40 - headOffset = unsafe.objectFieldOffset
2.41 - (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
2.42 - tailOffset = unsafe.objectFieldOffset
2.43 - (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
2.44 - waitStatusOffset = unsafe.objectFieldOffset
2.45 - (Node.class.getDeclaredField("waitStatus"));
2.46 - nextOffset = unsafe.objectFieldOffset
2.47 - (Node.class.getDeclaredField("next"));
2.48 -
2.49 - } catch (Exception ex) { throw new Error(ex); }
2.50 - }
2.51
2.52 /**
2.53 * CAS head field. Used only by enq.
2.54 */
2.55 private final boolean compareAndSetHead(Node update) {
2.56 - return unsafe.compareAndSwapObject(this, headOffset, null, update);
2.57 + if (head == null) {
2.58 + head = update;
2.59 + return true;
2.60 + }
2.61 + return false;
2.62 }
2.63
2.64 /**
2.65 * CAS tail field. Used only by enq.
2.66 */
2.67 private final boolean compareAndSetTail(Node expect, Node update) {
2.68 - return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
2.69 + if (tail == null) {
2.70 + tail = update;
2.71 + return true;
2.72 + }
2.73 + return false;
2.74 }
2.75
2.76 /**
2.77 @@ -2315,8 +2304,11 @@
2.78 private static final boolean compareAndSetWaitStatus(Node node,
2.79 int expect,
2.80 int update) {
2.81 - return unsafe.compareAndSwapInt(node, waitStatusOffset,
2.82 - expect, update);
2.83 + if (node.waitStatus == expect) {
2.84 + node.waitStatus = update;
2.85 + return true;
2.86 + }
2.87 + return false;
2.88 }
2.89
2.90 /**
2.91 @@ -2325,6 +2317,10 @@
2.92 private static final boolean compareAndSetNext(Node node,
2.93 Node expect,
2.94 Node update) {
2.95 - return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
2.96 + if (node.next == expect) {
2.97 + node.next = update;
2.98 + return true;
2.99 + }
2.100 + return false;
2.101 }
2.102 }
3.1 --- a/rt/emul/compact/src/main/java/java/util/concurrent/locks/LockSupport.java Sat Mar 19 10:54:10 2016 +0100
3.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/LockSupport.java Sat Mar 19 11:01:40 2016 +0100
3.3 @@ -34,8 +34,6 @@
3.4 */
3.5
3.6 package java.util.concurrent.locks;
3.7 -import java.util.concurrent.*;
3.8 -import sun.misc.Unsafe;
3.9
3.10
3.11 /**
3.12 @@ -120,22 +118,6 @@
3.13 public class LockSupport {
3.14 private LockSupport() {} // Cannot be instantiated.
3.15
3.16 - // Hotspot implementation via intrinsics API
3.17 - private static final Unsafe unsafe = Unsafe.getUnsafe();
3.18 - private static final long parkBlockerOffset;
3.19 -
3.20 - static {
3.21 - try {
3.22 - parkBlockerOffset = unsafe.objectFieldOffset
3.23 - (java.lang.Thread.class.getDeclaredField("parkBlocker"));
3.24 - } catch (Exception ex) { throw new Error(ex); }
3.25 - }
3.26 -
3.27 - private static void setBlocker(Thread t, Object arg) {
3.28 - // Even though volatile, hotspot doesn't need a write barrier here.
3.29 - unsafe.putObject(t, parkBlockerOffset, arg);
3.30 - }
3.31 -
3.32 /**
3.33 * Makes available the permit for the given thread, if it
3.34 * was not already available. If the thread was blocked on
3.35 @@ -148,8 +130,6 @@
3.36 * this operation has no effect
3.37 */
3.38 public static void unpark(Thread thread) {
3.39 - if (thread != null)
3.40 - unsafe.unpark(thread);
3.41 }
3.42
3.43 /**
3.44 @@ -181,10 +161,6 @@
3.45 * @since 1.6
3.46 */
3.47 public static void park(Object blocker) {
3.48 - Thread t = Thread.currentThread();
3.49 - setBlocker(t, blocker);
3.50 - unsafe.park(false, 0L);
3.51 - setBlocker(t, null);
3.52 }
3.53
3.54 /**
3.55 @@ -220,12 +196,6 @@
3.56 * @since 1.6
3.57 */
3.58 public static void parkNanos(Object blocker, long nanos) {
3.59 - if (nanos > 0) {
3.60 - Thread t = Thread.currentThread();
3.61 - setBlocker(t, blocker);
3.62 - unsafe.park(false, nanos);
3.63 - setBlocker(t, null);
3.64 - }
3.65 }
3.66
3.67 /**
3.68 @@ -262,10 +232,6 @@
3.69 * @since 1.6
3.70 */
3.71 public static void parkUntil(Object blocker, long deadline) {
3.72 - Thread t = Thread.currentThread();
3.73 - setBlocker(t, blocker);
3.74 - unsafe.park(true, deadline);
3.75 - setBlocker(t, null);
3.76 }
3.77
3.78 /**
3.79 @@ -281,9 +247,7 @@
3.80 * @since 1.6
3.81 */
3.82 public static Object getBlocker(Thread t) {
3.83 - if (t == null)
3.84 - throw new NullPointerException();
3.85 - return unsafe.getObjectVolatile(t, parkBlockerOffset);
3.86 + return null;
3.87 }
3.88
3.89 /**
3.90 @@ -312,7 +276,6 @@
3.91 * for example, the interrupt status of the thread upon return.
3.92 */
3.93 public static void park() {
3.94 - unsafe.park(false, 0L);
3.95 }
3.96
3.97 /**
3.98 @@ -345,8 +308,6 @@
3.99 * @param nanos the maximum number of nanoseconds to wait
3.100 */
3.101 public static void parkNanos(long nanos) {
3.102 - if (nanos > 0)
3.103 - unsafe.park(false, nanos);
3.104 }
3.105
3.106 /**
3.107 @@ -380,6 +341,5 @@
3.108 * to wait until
3.109 */
3.110 public static void parkUntil(long deadline) {
3.111 - unsafe.park(true, deadline);
3.112 }
3.113 }