Can compile java.util.concurrent.locks
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 19 Mar 2016 11:01:40 +0100
changeset 189475ee4eca04e3
parent 1893 bf15352bb298
child 1895 bfaf3300b7ba
Can compile java.util.concurrent.locks
rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
rt/emul/compact/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
rt/emul/compact/src/main/java/java/util/concurrent/locks/LockSupport.java
     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  }