16232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson/*
26232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Written by Doug Lea with assistance from members of JCP JSR-166
36232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Expert Group and released to the public domain, as explained at
4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
56232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */
66232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
76232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonpackage java.util.concurrent.locks;
8aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath
991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.ArrayList;
1091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.Collection;
1191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.Date;
12e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.concurrent.TimeUnit;
13e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.concurrent.locks.AbstractQueuedSynchronizer.Node;
146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson/**
166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * A version of {@link AbstractQueuedSynchronizer} in
1791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * which synchronization state is maintained as a {@code long}.
186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * This class has exactly the same structure, properties, and methods
1991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * as {@code AbstractQueuedSynchronizer} with the exception
206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * that all state-related parameters and results are defined
2191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * as {@code long} rather than {@code int}. This class
226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * may be useful when creating synchronizers such as
236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * multilevel locks and barriers that require
246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 64 bits of state.
256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson *
266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>See {@link AbstractQueuedSynchronizer} for usage
276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * notes and examples.
286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson *
296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6
306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @author Doug Lea
316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */
326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonpublic abstract class AbstractQueuedLongSynchronizer
336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    extends AbstractOwnableSynchronizer
346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    implements java.io.Serializable {
356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private static final long serialVersionUID = 7373984972572414692L;
376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /*
396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson      To keep sources in sync, the remainder of this source file is
406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson      exactly cloned from AbstractQueuedSynchronizer, replacing class
416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson      name and changing ints related with sync state to longs. Please
426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson      keep it that way.
436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    */
446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
4691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Creates a new {@code AbstractQueuedLongSynchronizer} instance
476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * with initial synchronization state of zero.
486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected AbstractQueuedLongSynchronizer() { }
506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Head of the wait queue, lazily initialized.  Except for
536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * initialization, it is modified only via method setHead.  Note:
546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * If head exists, its waitStatus is guaranteed not to be
556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * CANCELLED.
566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private transient volatile Node head;
586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Tail of the wait queue, lazily initialized.  Modified only via
616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * method enq to add new wait node.
626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private transient volatile Node tail;
646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * The synchronization state.
676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private volatile long state;
696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns the current value of synchronization state.
7291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * This operation has memory semantics of a {@code volatile} read.
736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return current state value
746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected final long getState() {
766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return state;
776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Sets the value of synchronization state.
8191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * This operation has memory semantics of a {@code volatile} write.
826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param newState the new state value
836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected final void setState(long newState) {
85e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        // Use putLongVolatile instead of ordinary volatile store when
86e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        // using compareAndSwapLong, for sake of some 32bit systems.
87e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        U.putLongVolatile(this, STATE, newState);
886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Atomically sets synchronization state to the given updated
926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * value if the current state value equals the expected value.
9391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * This operation has memory semantics of a {@code volatile} read
946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * and write.
956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param expect the expected value
976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param update the new value
98e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * @return {@code true} if successful. False return indicates that the actual
996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         value was not equal to the expected value.
1006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected final boolean compareAndSetState(long expect, long update) {
102e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        return U.compareAndSwapLong(this, STATE, expect, update);
1036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
1046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Queuing utilities
1066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * The number of nanoseconds for which it is faster to spin
1096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * rather than to use timed park. A rough estimate suffices
1106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * to improve responsiveness with very short timeouts.
1116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
112e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    static final long SPIN_FOR_TIMEOUT_THRESHOLD = 1000L;
1136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Inserts node into queue, initializing if necessary. See picture above.
1166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node to insert
1176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return node's predecessor
1186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
119e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    private Node enq(Node node) {
1206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (;;) {
121e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            Node oldTail = tail;
122e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            if (oldTail != null) {
123e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                U.putObject(node, Node.PREV, oldTail);
124e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (compareAndSetTail(oldTail, node)) {
125e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    oldTail.next = node;
126e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    return oldTail;
1276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
128e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            } else {
129e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                initializeSyncQueue();
1306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
1316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
1326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
1336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Creates and enqueues node for current thread and given mode.
1366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
1386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the new node
1396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private Node addWaiter(Node mode) {
141e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        Node node = new Node(mode);
142e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak
143e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        for (;;) {
144e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            Node oldTail = tail;
145e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            if (oldTail != null) {
146e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                U.putObject(node, Node.PREV, oldTail);
147e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (compareAndSetTail(oldTail, node)) {
148e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    oldTail.next = node;
149e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    return node;
150e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                }
151e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            } else {
152e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                initializeSyncQueue();
1536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
1546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
1556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
1566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Sets head of queue to be node, thus dequeuing. Called only by
1596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire methods.  Also nulls out unused fields for sake of GC
1606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * and to suppress unnecessary signals and traversals.
1616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
1636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void setHead(Node node) {
1656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        head = node;
1666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        node.thread = null;
1676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        node.prev = null;
1686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
1696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Wakes up node's successor, if one exists.
1726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
1746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void unparkSuccessor(Node node) {
1766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
1776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * If status is negative (i.e., possibly needing signal) try
1786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * to clear in anticipation of signalling.  It is OK if this
1796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * fails or if status is changed by waiting thread.
1806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
1816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        int ws = node.waitStatus;
1826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (ws < 0)
183e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            node.compareAndSetWaitStatus(ws, 0);
1846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
1866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Thread to unpark is held in successor, which is normally
1876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * just the next node.  But if cancelled or apparently null,
1886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * traverse backwards from tail to find the actual
1896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * non-cancelled successor.
1906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
1916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node s = node.next;
1926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (s == null || s.waitStatus > 0) {
1936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            s = null;
194e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            for (Node p = tail; p != node && p != null; p = p.prev)
195aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath                if (p.waitStatus <= 0)
196aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath                    s = p;
1976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
1986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (s != null)
1996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            LockSupport.unpark(s.thread);
2006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
2016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
20391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Release action for shared mode -- signals successor and ensures
2046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * propagation. (Note: For exclusive mode, release just amounts
2056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * to calling unparkSuccessor of head if it needs signal.)
2066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
2076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void doReleaseShared() {
2086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
2096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Ensure that a release propagates, even if there are other
2106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * in-progress acquires/releases.  This proceeds in the usual
2116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * way of trying to unparkSuccessor of head if it needs
2126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * signal. But if it does not, status is set to PROPAGATE to
2136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * ensure that upon release, propagation continues.
2146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Additionally, we must loop in case a new node is added
2156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * while we are doing this. Also, unlike other uses of
2166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * unparkSuccessor, we need to know if CAS to reset status
2176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * fails, if so rechecking.
2186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
2196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (;;) {
2206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node h = head;
2216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (h != null && h != tail) {
2226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                int ws = h.waitStatus;
2236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (ws == Node.SIGNAL) {
224e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    if (!h.compareAndSetWaitStatus(Node.SIGNAL, 0))
2256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        continue;            // loop to recheck cases
2266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    unparkSuccessor(h);
2276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
2286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                else if (ws == 0 &&
229e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                         !h.compareAndSetWaitStatus(0, Node.PROPAGATE))
2306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    continue;                // loop on failed CAS
2316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
2326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (h == head)                   // loop if head changed
2336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                break;
2346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
2356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
2366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
2386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Sets head of queue, and checks if successor may be waiting
2396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * in shared mode, if so propagating if either propagate > 0 or
2406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * PROPAGATE status was set.
2416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
2426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
2436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param propagate the return value from a tryAcquireShared
2446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
2456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void setHeadAndPropagate(Node node, long propagate) {
2466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node h = head; // Record old head for check below
2476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        setHead(node);
2486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
2496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Try to signal next queued node if:
2506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *   Propagation was indicated by caller,
251e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     or was recorded (as h.waitStatus either before
252e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     or after setHead) by a previous operation
2536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *     (note: this uses sign-check of waitStatus because
2546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *      PROPAGATE status may transition to SIGNAL.)
2556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * and
2566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *   The next node is waiting in shared mode,
2576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *     or we don't know, because it appears null
2586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
2596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * The conservatism in both of these checks may cause
2606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * unnecessary wake-ups, but only when there are multiple
2616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * racing acquires/releases, so most need signals now or soon
2626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * anyway.
2636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
264e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        if (propagate > 0 || h == null || h.waitStatus < 0 ||
265e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            (h = head) == null || h.waitStatus < 0) {
2666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node s = node.next;
2676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (s == null || s.isShared())
2686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                doReleaseShared();
2696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
2706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
2716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Utilities for various versions of acquire
2736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
2756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Cancels an ongoing attempt to acquire.
2766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
2776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
2786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
2796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void cancelAcquire(Node node) {
2806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // Ignore if node doesn't exist
2816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (node == null)
2826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return;
2836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        node.thread = null;
2856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // Skip cancelled predecessors
2876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node pred = node.prev;
2886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        while (pred.waitStatus > 0)
2896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            node.prev = pred = pred.prev;
2906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // predNext is the apparent node to unsplice. CASes below will
2926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // fail if not, in which case, we lost race vs another cancel
2936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // or signal, so no further action is necessary.
2946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node predNext = pred.next;
2956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
2966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // Can use unconditional write instead of CAS here.
2976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // After this atomic step, other Nodes can skip past us.
2986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // Before, we are free of interference from other threads.
2996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        node.waitStatus = Node.CANCELLED;
3006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // If we are the tail, remove ourselves.
3026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (node == tail && compareAndSetTail(node, pred)) {
303e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            pred.compareAndSetNext(predNext, null);
3046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        } else {
3056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            // If successor needs signal, try to set pred's next-link
3066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            // so it will get one. Otherwise wake it up to propagate.
3076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            int ws;
3086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (pred != head &&
3096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                ((ws = pred.waitStatus) == Node.SIGNAL ||
310e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                 (ws <= 0 && pred.compareAndSetWaitStatus(ws, Node.SIGNAL))) &&
3116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                pred.thread != null) {
3126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                Node next = node.next;
3136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (next != null && next.waitStatus <= 0)
314e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    pred.compareAndSetNext(predNext, next);
3156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            } else {
3166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unparkSuccessor(node);
3176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
3186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            node.next = node; // help GC
3206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
3216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
3226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
3246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Checks and updates status for a node that failed to acquire.
3256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns true if thread should block. This is the main signal
32691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * control in all acquire loops.  Requires that pred == node.prev.
3276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
3286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param pred node's predecessor holding status
3296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
3306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if thread should block
3316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
3326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
3336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        int ws = pred.waitStatus;
3346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (ws == Node.SIGNAL)
3356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            /*
3366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * This node has already set status asking a release
3376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * to signal it, so it can safely park.
3386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             */
3396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return true;
3406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (ws > 0) {
3416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            /*
3426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * Predecessor was cancelled. Skip over predecessors and
3436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * indicate retry.
3446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             */
3456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            do {
3466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                node.prev = pred = pred.prev;
3476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            } while (pred.waitStatus > 0);
3486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            pred.next = node;
3496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        } else {
3506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            /*
3516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * waitStatus must be 0 or PROPAGATE.  Indicate that we
3526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * need a signal, but don't park yet.  Caller will need to
3536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             * retry to make sure it cannot acquire before parking.
3546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             */
355e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            pred.compareAndSetWaitStatus(ws, Node.SIGNAL);
3566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
3576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return false;
3586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
3596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
3616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Convenience method to interrupt current thread.
3626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
363a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    static void selfInterrupt() {
3646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Thread.currentThread().interrupt();
3656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
3666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
368e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * Convenience method to park and then check if interrupted.
3696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
3706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if interrupted
3716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
3726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private final boolean parkAndCheckInterrupt() {
3736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        LockSupport.park(this);
3746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return Thread.interrupted();
3756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
3766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /*
3786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Various flavors of acquire, varying in exclusive/shared and
3796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * control modes.  Each is mostly the same, but annoyingly
3806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * different.  Only a little bit of factoring is possible due to
3816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * interactions of exception mechanics (including ensuring that we
3826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * cancel if tryAcquire throws exception) and other control, at
3836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * least not without hurting performance too much.
3846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
3856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
3866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
3876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in exclusive uninterruptible mode for thread already in
3886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * queue. Used by condition wait methods as well as acquire.
3896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
3906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
3916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument
3926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if interrupted while waiting
3936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
3946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    final boolean acquireQueued(final Node node, long arg) {
3956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
3966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            boolean interrupted = false;
3976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (;;) {
3986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                final Node p = node.predecessor();
3996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (p == head && tryAcquire(arg)) {
4006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    setHead(node);
4016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    p.next = null; // help GC
4026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    return interrupted;
4036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
4046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (shouldParkAfterFailedAcquire(p, node) &&
4056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    parkAndCheckInterrupt())
4066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    interrupted = true;
4076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
408e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
409e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            cancelAcquire(node);
410e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
4116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
4126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
4136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
4146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
4156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in exclusive interruptible mode.
4166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument
4176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
4186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void doAcquireInterruptibly(long arg)
4196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throws InterruptedException {
4206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        final Node node = addWaiter(Node.EXCLUSIVE);
4216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
4226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (;;) {
4236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                final Node p = node.predecessor();
4246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (p == head && tryAcquire(arg)) {
4256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    setHead(node);
4266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    p.next = null; // help GC
4276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    return;
4286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
4296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (shouldParkAfterFailedAcquire(p, node) &&
4306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    parkAndCheckInterrupt())
4316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    throw new InterruptedException();
4326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
433e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
434e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            cancelAcquire(node);
435e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
4366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
4376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
4386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
4396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
4406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in exclusive timed mode.
4416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
4426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument
4436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param nanosTimeout max wait time
4446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if acquired
4456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
4466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private boolean doAcquireNanos(long arg, long nanosTimeout)
44791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            throws InterruptedException {
44891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle        if (nanosTimeout <= 0L)
44991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            return false;
45091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle        final long deadline = System.nanoTime() + nanosTimeout;
4516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        final Node node = addWaiter(Node.EXCLUSIVE);
4526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
4536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (;;) {
4546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                final Node p = node.predecessor();
4556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (p == head && tryAcquire(arg)) {
4566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    setHead(node);
4576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    p.next = null; // help GC
4586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    return true;
4596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
46091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                nanosTimeout = deadline - System.nanoTime();
461e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (nanosTimeout <= 0L) {
462e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    cancelAcquire(node);
4636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    return false;
464e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                }
4656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (shouldParkAfterFailedAcquire(p, node) &&
466e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
4676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    LockSupport.parkNanos(this, nanosTimeout);
4686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (Thread.interrupted())
4696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    throw new InterruptedException();
4706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
471e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
472e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            cancelAcquire(node);
473e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
4746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
4756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
4766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
4776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
4786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in shared uninterruptible mode.
4796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument
4806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
4816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void doAcquireShared(long arg) {
4826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        final Node node = addWaiter(Node.SHARED);
4836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
4846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            boolean interrupted = false;
4856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (;;) {
4866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                final Node p = node.predecessor();
4876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (p == head) {
4886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    long r = tryAcquireShared(arg);
4896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    if (r >= 0) {
4906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        setHeadAndPropagate(node, r);
4916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        p.next = null; // help GC
4926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        if (interrupted)
4936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                            selfInterrupt();
4946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        return;
4956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    }
4966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
4976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (shouldParkAfterFailedAcquire(p, node) &&
4986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    parkAndCheckInterrupt())
4996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    interrupted = true;
5006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
501e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
502e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            cancelAcquire(node);
503e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
5046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
5056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
5066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
5076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
5086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in shared interruptible mode.
5096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument
5106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
5116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private void doAcquireSharedInterruptibly(long arg)
5126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throws InterruptedException {
5136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        final Node node = addWaiter(Node.SHARED);
5146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
5156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (;;) {
5166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                final Node p = node.predecessor();
5176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (p == head) {
5186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    long r = tryAcquireShared(arg);
5196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    if (r >= 0) {
5206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        setHeadAndPropagate(node, r);
5216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        p.next = null; // help GC
5226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        return;
5236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    }
5246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
5256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (shouldParkAfterFailedAcquire(p, node) &&
5266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    parkAndCheckInterrupt())
5276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    throw new InterruptedException();
5286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
529e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
530e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            cancelAcquire(node);
531e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
5326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
5336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
5346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
5356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
5366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in shared timed mode.
5376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
5386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument
5396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param nanosTimeout max wait time
5406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if acquired
5416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
5426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private boolean doAcquireSharedNanos(long arg, long nanosTimeout)
54391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            throws InterruptedException {
54491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle        if (nanosTimeout <= 0L)
54591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle            return false;
54691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle        final long deadline = System.nanoTime() + nanosTimeout;
5476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        final Node node = addWaiter(Node.SHARED);
5486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
5496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (;;) {
5506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                final Node p = node.predecessor();
5516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (p == head) {
5526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    long r = tryAcquireShared(arg);
5536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    if (r >= 0) {
5546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        setHeadAndPropagate(node, r);
5556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        p.next = null; // help GC
5566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        return true;
5576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    }
5586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
55991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                nanosTimeout = deadline - System.nanoTime();
560e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (nanosTimeout <= 0L) {
561e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    cancelAcquire(node);
5626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    return false;
563e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                }
5646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (shouldParkAfterFailedAcquire(p, node) &&
565e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                    nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
5666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    LockSupport.parkNanos(this, nanosTimeout);
5676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (Thread.interrupted())
5686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    throw new InterruptedException();
5696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
570e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
571e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            cancelAcquire(node);
572e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
5736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
5746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
5756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
5766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Main exported methods
5776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
5786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
5796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Attempts to acquire in exclusive mode. This method should query
5806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * if the state of the object permits it to be acquired in the
5816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * exclusive mode, and if so to acquire it.
5826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
5836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This method is always invoked by the thread performing
5846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire.  If this method reports failure, the acquire method
5856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * may queue the thread, if it is not already queued, until it is
5866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * signalled by a release from some other thread. This can be used
5876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * to implement method {@link Lock#tryLock()}.
5886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
5896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>The default
5906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * implementation throws {@link UnsupportedOperationException}.
5916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
5926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument. This value is always the one
5936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        passed to an acquire method, or is the value saved on entry
5946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        to a condition wait.  The value is otherwise uninterpreted
5956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        and can represent anything you like.
5966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if successful. Upon success, this object has
5976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         been acquired.
5986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if acquiring would place this
5996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         synchronizer in an illegal state. This exception must be
6006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         thrown in a consistent fashion for synchronization to work
6016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         correctly.
6026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws UnsupportedOperationException if exclusive mode is not supported
6036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
6046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected boolean tryAcquire(long arg) {
6056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throw new UnsupportedOperationException();
6066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
6076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
6086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
6096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Attempts to set the state to reflect a release in exclusive
6106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * mode.
6116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This method is always invoked by the thread performing release.
6136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>The default implementation throws
6156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@link UnsupportedOperationException}.
6166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the release argument. This value is always the one
6186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        passed to a release method, or the current state value upon
6196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        entry to a condition wait.  The value is otherwise
6206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        uninterpreted and can represent anything you like.
6216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if this object is now in a fully released
6226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         state, so that any waiting threads may attempt to acquire;
6236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         and {@code false} otherwise.
6246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if releasing would place this
6256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         synchronizer in an illegal state. This exception must be
6266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         thrown in a consistent fashion for synchronization to work
6276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         correctly.
6286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws UnsupportedOperationException if exclusive mode is not supported
6296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
6306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected boolean tryRelease(long arg) {
6316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throw new UnsupportedOperationException();
6326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
6336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
6346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
6356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Attempts to acquire in shared mode. This method should query if
6366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * the state of the object permits it to be acquired in the shared
6376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * mode, and if so to acquire it.
6386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This method is always invoked by the thread performing
6406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire.  If this method reports failure, the acquire method
6416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * may queue the thread, if it is not already queued, until it is
6426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * signalled by a release from some other thread.
6436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>The default implementation throws {@link
6456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * UnsupportedOperationException}.
6466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument. This value is always the one
6486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        passed to an acquire method, or is the value saved on entry
6496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        to a condition wait.  The value is otherwise uninterpreted
6506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        and can represent anything you like.
6516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return a negative value on failure; zero if acquisition in shared
6526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         mode succeeded but no subsequent shared-mode acquire can
6536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         succeed; and a positive value if acquisition in shared
6546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         mode succeeded and subsequent shared-mode acquires might
6556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         also succeed, in which case a subsequent waiting thread
6566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         must check availability. (Support for three different
6576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         return values enables this method to be used in contexts
6586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         where acquires only sometimes act exclusively.)  Upon
6596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         success, this object has been acquired.
6606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if acquiring would place this
6616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         synchronizer in an illegal state. This exception must be
6626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         thrown in a consistent fashion for synchronization to work
6636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         correctly.
6646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws UnsupportedOperationException if shared mode is not supported
6656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
6666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected long tryAcquireShared(long arg) {
6676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throw new UnsupportedOperationException();
6686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
6696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
6706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
6716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Attempts to set the state to reflect a release in shared mode.
6726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This method is always invoked by the thread performing release.
6746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>The default implementation throws
6766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@link UnsupportedOperationException}.
6776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
6786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the release argument. This value is always the one
6796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        passed to a release method, or the current state value upon
6806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        entry to a condition wait.  The value is otherwise
6816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        uninterpreted and can represent anything you like.
6826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if this release of shared mode may permit a
6836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         waiting acquire (shared or exclusive) to succeed; and
6846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         {@code false} otherwise
6856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if releasing would place this
6866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         synchronizer in an illegal state. This exception must be
6876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         thrown in a consistent fashion for synchronization to work
6886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         correctly.
6896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws UnsupportedOperationException if shared mode is not supported
6906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
6916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected boolean tryReleaseShared(long arg) {
6926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throw new UnsupportedOperationException();
6936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
6946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
6956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
6966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns {@code true} if synchronization is held exclusively with
6976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * respect to the current (calling) thread.  This method is invoked
6986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * upon each call to a non-waiting {@link ConditionObject} method.
6996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * (Waiting methods instead invoke {@link #release}.)
7006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
7016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>The default implementation throws {@link
7026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * UnsupportedOperationException}. This method is invoked
7036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * internally only within {@link ConditionObject} methods, so need
7046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * not be defined if conditions are not used.
7056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
7066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if synchronization is held exclusively;
7076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         {@code false} otherwise
7086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws UnsupportedOperationException if conditions are not supported
7096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
7106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    protected boolean isHeldExclusively() {
7116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        throw new UnsupportedOperationException();
7126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
7136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
7146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
7156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in exclusive mode, ignoring interrupts.  Implemented
7166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * by invoking at least once {@link #tryAcquire},
7176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * returning on success.  Otherwise the thread is queued, possibly
7186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * repeatedly blocking and unblocking, invoking {@link
7196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * #tryAcquire} until success.  This method can be used
7206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * to implement method {@link Lock#lock}.
7216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
7226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument.  This value is conveyed to
7236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryAcquire} but is otherwise uninterpreted and
7246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        can represent anything you like.
7256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
7266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final void acquire(long arg) {
7276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (!tryAcquire(arg) &&
7286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
7296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            selfInterrupt();
7306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
7316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
7326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
7336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in exclusive mode, aborting if interrupted.
7346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Implemented by first checking interrupt status, then invoking
7356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * at least once {@link #tryAcquire}, returning on
7366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * success.  Otherwise the thread is queued, possibly repeatedly
7376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * blocking and unblocking, invoking {@link #tryAcquire}
7386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * until success or the thread is interrupted.  This method can be
7396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * used to implement method {@link Lock#lockInterruptibly}.
7406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
7416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument.  This value is conveyed to
7426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryAcquire} but is otherwise uninterpreted and
7436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        can represent anything you like.
7446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws InterruptedException if the current thread is interrupted
7456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
7468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    public final void acquireInterruptibly(long arg)
7478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throws InterruptedException {
7486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (Thread.interrupted())
7496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new InterruptedException();
7506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (!tryAcquire(arg))
7516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            doAcquireInterruptibly(arg);
7526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
7536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
7546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
7556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Attempts to acquire in exclusive mode, aborting if interrupted,
7566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * and failing if the given timeout elapses.  Implemented by first
7576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * checking interrupt status, then invoking at least once {@link
7586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * #tryAcquire}, returning on success.  Otherwise, the thread is
7596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * queued, possibly repeatedly blocking and unblocking, invoking
7606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@link #tryAcquire} until success or the thread is interrupted
7616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * or the timeout elapses.  This method can be used to implement
7626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * method {@link Lock#tryLock(long, TimeUnit)}.
7636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
7646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument.  This value is conveyed to
7656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryAcquire} but is otherwise uninterpreted and
7666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        can represent anything you like.
7676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param nanosTimeout the maximum number of nanoseconds to wait
7686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if acquired; {@code false} if timed out
7696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws InterruptedException if the current thread is interrupted
7706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
7718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    public final boolean tryAcquireNanos(long arg, long nanosTimeout)
7728eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throws InterruptedException {
7736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (Thread.interrupted())
7746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new InterruptedException();
7756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return tryAcquire(arg) ||
7766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            doAcquireNanos(arg, nanosTimeout);
7776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
7786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
7796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
7806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Releases in exclusive mode.  Implemented by unblocking one or
7816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * more threads if {@link #tryRelease} returns true.
7826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * This method can be used to implement method {@link Lock#unlock}.
7836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
7846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the release argument.  This value is conveyed to
7856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryRelease} but is otherwise uninterpreted and
7866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        can represent anything you like.
7876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the value returned from {@link #tryRelease}
7886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
7896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean release(long arg) {
7906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (tryRelease(arg)) {
7916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node h = head;
7926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (h != null && h.waitStatus != 0)
7936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unparkSuccessor(h);
7946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return true;
7956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
7966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return false;
7976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
7986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
7996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
8006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in shared mode, ignoring interrupts.  Implemented by
8016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * first invoking at least once {@link #tryAcquireShared},
8026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * returning on success.  Otherwise the thread is queued, possibly
8036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * repeatedly blocking and unblocking, invoking {@link
8046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * #tryAcquireShared} until success.
8056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
8066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument.  This value is conveyed to
8076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryAcquireShared} but is otherwise uninterpreted
8086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        and can represent anything you like.
8096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
8106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final void acquireShared(long arg) {
8116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (tryAcquireShared(arg) < 0)
8126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            doAcquireShared(arg);
8136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
8146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
8156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
8166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Acquires in shared mode, aborting if interrupted.  Implemented
8176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * by first checking interrupt status, then invoking at least once
8186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@link #tryAcquireShared}, returning on success.  Otherwise the
8196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * thread is queued, possibly repeatedly blocking and unblocking,
8206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * invoking {@link #tryAcquireShared} until success or the thread
8216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * is interrupted.
82291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @param arg the acquire argument.
8236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * This value is conveyed to {@link #tryAcquireShared} but is
8246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * otherwise uninterpreted and can represent anything
8256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * you like.
8266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws InterruptedException if the current thread is interrupted
8276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
8288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    public final void acquireSharedInterruptibly(long arg)
8298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throws InterruptedException {
8306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (Thread.interrupted())
8316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new InterruptedException();
8326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (tryAcquireShared(arg) < 0)
8336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            doAcquireSharedInterruptibly(arg);
8346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
8356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
8366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
8376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Attempts to acquire in shared mode, aborting if interrupted, and
8386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * failing if the given timeout elapses.  Implemented by first
8396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * checking interrupt status, then invoking at least once {@link
8406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * #tryAcquireShared}, returning on success.  Otherwise, the
8416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * thread is queued, possibly repeatedly blocking and unblocking,
8426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * invoking {@link #tryAcquireShared} until success or the thread
8436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * is interrupted or the timeout elapses.
8446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
8456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the acquire argument.  This value is conveyed to
8466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryAcquireShared} but is otherwise uninterpreted
8476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        and can represent anything you like.
8486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param nanosTimeout the maximum number of nanoseconds to wait
8496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if acquired; {@code false} if timed out
8506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws InterruptedException if the current thread is interrupted
8516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
8528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout)
8538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throws InterruptedException {
8546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (Thread.interrupted())
8556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new InterruptedException();
8566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return tryAcquireShared(arg) >= 0 ||
8576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            doAcquireSharedNanos(arg, nanosTimeout);
8586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
8596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
8606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
8616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Releases in shared mode.  Implemented by unblocking one or more
8626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * threads if {@link #tryReleaseShared} returns true.
8636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
8646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param arg the release argument.  This value is conveyed to
8656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        {@link #tryReleaseShared} but is otherwise uninterpreted
8666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        and can represent anything you like.
8676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the value returned from {@link #tryReleaseShared}
8686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
8696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean releaseShared(long arg) {
8706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (tryReleaseShared(arg)) {
8716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            doReleaseShared();
8726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return true;
8736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
8746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return false;
8756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
8766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
8776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Queue inspection methods
8786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
8796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
8806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Queries whether any threads are waiting to acquire. Note that
8816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * because cancellations due to interrupts and timeouts may occur
8826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * at any time, a {@code true} return does not guarantee that any
8836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * other thread will ever acquire.
8846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
8856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>In this implementation, this operation returns in
8866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * constant time.
8876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
8886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if there may be other threads waiting to acquire
8896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
8906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean hasQueuedThreads() {
8916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return head != tail;
8926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
8936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
8946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
8956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Queries whether any threads have ever contended to acquire this
896e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * synchronizer; that is, if an acquire method has ever blocked.
8976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
8986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>In this implementation, this operation returns in
8996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * constant time.
9006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
9016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if there has ever been contention
9026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
9036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean hasContended() {
9046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return head != null;
9056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
9066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
9086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns the first (longest-waiting) thread in the queue, or
9096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@code null} if no threads are currently queued.
9106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
9116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>In this implementation, this operation normally returns in
9126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * constant time, but may iterate upon contention if other threads are
9136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * concurrently modifying the queue.
9146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
9156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the first (longest-waiting) thread in the queue, or
9166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         {@code null} if no threads are currently queued
9176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
9186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final Thread getFirstQueuedThread() {
9196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // handle only fast path, else relay
9206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return (head == tail) ? null : fullGetFirstQueuedThread();
9216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
9226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
924e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * Version of getFirstQueuedThread called when fastpath fails.
9256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
9266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private Thread fullGetFirstQueuedThread() {
9276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
9286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * The first node is normally head.next. Try to get its
9296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * thread field, ensuring consistent reads: If thread
9306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * field is nulled out or s.prev is no longer head, then
9316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * some other thread(s) concurrently performed setHead in
9326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * between some of our reads. We try this twice before
9336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * resorting to traversal.
9346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
9356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node h, s;
9366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Thread st;
9376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (((h = head) != null && (s = h.next) != null &&
9386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             s.prev == head && (st = s.thread) != null) ||
9396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            ((h = head) != null && (s = h.next) != null &&
9406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson             s.prev == head && (st = s.thread) != null))
9416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return st;
9426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
9446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Head's next field might not have been set yet, or may have
9456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * been unset after setHead. So we must check to see if tail
9466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * is actually first node. If not, we continue on, safely
9476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * traversing from tail back to head to find first,
9486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * guaranteeing termination.
9496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
9506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Thread firstThread = null;
952e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        for (Node p = tail; p != null && p != head; p = p.prev) {
953e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            Thread t = p.thread;
954e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            if (t != null)
955e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                firstThread = t;
9566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
9576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return firstThread;
9586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
9596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
9616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns true if the given thread is currently queued.
9626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
9636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This implementation traverses the queue to determine
9646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * presence of the given thread.
9656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
9666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param thread the thread
9676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if the given thread is on the queue
9686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws NullPointerException if the thread is null
9696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
9706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean isQueued(Thread thread) {
9716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (thread == null)
9726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new NullPointerException();
9736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (Node p = tail; p != null; p = p.prev)
9746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (p.thread == thread)
9756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                return true;
9766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return false;
9776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
9786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
9806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns {@code true} if the apparent first queued thread, if one
9816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * exists, is waiting in exclusive mode.  If this method returns
9826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@code true}, and the current thread is attempting to acquire in
9836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * shared mode (that is, this method is invoked from {@link
9846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * #tryAcquireShared}) then it is guaranteed that the current thread
9856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * is not the first queued thread.  Used only as a heuristic in
9866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * ReentrantReadWriteLock.
9876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
9886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    final boolean apparentlyFirstQueuedIsExclusive() {
9896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node h, s;
9906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return (h = head) != null &&
9916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            (s = h.next)  != null &&
9926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            !s.isShared()         &&
9936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            s.thread != null;
9946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
9956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
9966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
9976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Queries whether any threads have been waiting to acquire longer
9986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * than the current thread.
9996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>An invocation of this method is equivalent to (but may be
10016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * more efficient than):
1002e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * <pre> {@code
1003e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * getFirstQueuedThread() != Thread.currentThread()
1004e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     *   && hasQueuedThreads()}</pre>
10056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>Note that because cancellations due to interrupts and
10076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * timeouts may occur at any time, a {@code true} return does not
10086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * guarantee that some other thread will acquire before the current
10096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * thread.  Likewise, it is possible for another thread to win a
10106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * race to enqueue after this method has returned {@code false},
10116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * due to the queue being empty.
10126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This method is designed to be used by a fair synchronizer to
1014a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     * avoid <a href="AbstractQueuedSynchronizer.html#barging">barging</a>.
10156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Such a synchronizer's {@link #tryAcquire} method should return
10166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@code false}, and its {@link #tryAcquireShared} method should
10176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * return a negative value, if this method returns {@code true}
10186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * (unless this is a reentrant acquire).  For example, the {@code
10196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * tryAcquire} method for a fair, reentrant, exclusive mode
10206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * synchronizer might look like this:
10216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1022e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * <pre> {@code
10236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * protected boolean tryAcquire(int arg) {
10246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *   if (isHeldExclusively()) {
10256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *     // A reentrant acquire; increment hold count
10266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *     return true;
10276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *   } else if (hasQueuedPredecessors()) {
10286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *     return false;
10296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *   } else {
10306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *     // try to acquire normally
10316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *   }
10326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * }}</pre>
10336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if there is a queued thread preceding the
10356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         current thread, and {@code false} if the current thread
10366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         is at the head of the queue or the queue is empty
10376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.7
10386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
103991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle    public final boolean hasQueuedPredecessors() {
10406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // The correctness of this depends on head being initialized
10416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // before tail and on head.next being accurate if the current
10426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // thread is first in queue.
10436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node t = tail; // Read fields in reverse initialization order
10446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node h = head;
10456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node s;
10466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return h != t &&
10476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            ((s = h.next) == null || s.thread != Thread.currentThread());
10486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
10496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
10506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
10516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Instrumentation and monitoring methods
10526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
10536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
10546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns an estimate of the number of threads waiting to
10556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire.  The value is only an estimate because the number of
10566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * threads may change dynamically while this method traverses
10576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * internal data structures.  This method is designed for use in
1058e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * monitoring system state, not for synchronization control.
10596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the estimated number of threads waiting to acquire
10616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
10626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final int getQueueLength() {
10636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        int n = 0;
10646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (Node p = tail; p != null; p = p.prev) {
10656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (p.thread != null)
10666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                ++n;
10676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
10686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return n;
10696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
10706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
10716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
10726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns a collection containing threads that may be waiting to
10736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire.  Because the actual set of threads may change
10746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * dynamically while constructing this result, the returned
10756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * collection is only a best-effort estimate.  The elements of the
10766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * returned collection are in no particular order.  This method is
10776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * designed to facilitate construction of subclasses that provide
10786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * more extensive monitoring facilities.
10796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the collection of threads
10816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
10826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final Collection<Thread> getQueuedThreads() {
1083e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        ArrayList<Thread> list = new ArrayList<>();
10846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (Node p = tail; p != null; p = p.prev) {
10856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Thread t = p.thread;
10866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (t != null)
10876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                list.add(t);
10886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
10896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return list;
10906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
10916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
10926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
10936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns a collection containing threads that may be waiting to
10946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire in exclusive mode. This has the same properties
10956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * as {@link #getQueuedThreads} except that it only returns
10966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * those threads waiting due to an exclusive acquire.
10976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
10986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the collection of threads
10996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
11006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final Collection<Thread> getExclusiveQueuedThreads() {
1101e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        ArrayList<Thread> list = new ArrayList<>();
11026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (Node p = tail; p != null; p = p.prev) {
11036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (!p.isShared()) {
11046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                Thread t = p.thread;
11056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (t != null)
11066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    list.add(t);
11076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
11086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
11096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return list;
11106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
11116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
11136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns a collection containing threads that may be waiting to
11146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * acquire in shared mode. This has the same properties
11156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * as {@link #getQueuedThreads} except that it only returns
11166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * those threads waiting due to a shared acquire.
11176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
11186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the collection of threads
11196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
11206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final Collection<Thread> getSharedQueuedThreads() {
1121e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        ArrayList<Thread> list = new ArrayList<>();
11226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        for (Node p = tail; p != null; p = p.prev) {
11236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (p.isShared()) {
11246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                Thread t = p.thread;
11256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (t != null)
11266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    list.add(t);
11276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
11286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
11296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return list;
11306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
11316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
11336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns a string identifying this synchronizer, as well as its state.
11346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * The state, in brackets, includes the String {@code "State ="}
11356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * followed by the current value of {@link #getState}, and either
11366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * {@code "nonempty"} or {@code "empty"} depending on whether the
11376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * queue is empty.
11386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
11396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return a string identifying this synchronizer, as well as its state
11406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
11416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public String toString() {
1142e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        return super.toString()
1143e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            + "[State = " + getState() + ", "
1144e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            + (hasQueuedThreads() ? "non" : "") + "empty queue]";
11456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
11466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Internal support methods for Conditions
11496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
11516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns true if a node, always one that was initially placed on
11526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * a condition queue, is now waiting to reacquire on sync queue.
11536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
11546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return true if is reacquiring
11556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
11566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    final boolean isOnSyncQueue(Node node) {
11576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (node.waitStatus == Node.CONDITION || node.prev == null)
11586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return false;
11596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (node.next != null) // If has successor, it must be on queue
11606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return true;
11616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
11626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * node.prev can be non-null, but not yet on queue because
11636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * the CAS to place it on queue can fail. So we have to
11646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * traverse from tail to make sure it actually made it.  It
11656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * will always be near the tail in calls to this method, and
11666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * unless the CAS failed (which is unlikely), it will be
11676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * there, so we hardly ever traverse much.
11686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
11696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return findNodeFromTail(node);
11706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
11716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
11736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns true if node is on sync queue by searching backwards from tail.
11746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Called only when needed by isOnSyncQueue.
11756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return true if present
11766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
11776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private boolean findNodeFromTail(Node node) {
1178e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        // We check for node first, since it's likely to be at or near tail.
1179e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        // tail is known to be non-null, so we could re-order to "save"
1180e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        // one null check, but we leave it this way to help the VM.
1181e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        for (Node p = tail;;) {
1182aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath            if (p == node)
11836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                return true;
1184aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath            if (p == null)
11856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                return false;
1186aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath            p = p.prev;
11876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
11886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
11896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
11906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
11916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Transfers a node from a condition queue onto sync queue.
11926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns true if successful.
11936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the node
11946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return true if successfully transferred (else the node was
119591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * cancelled before signal)
11966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
11976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    final boolean transferForSignal(Node node) {
11986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
11996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * If cannot change waitStatus, the node has been cancelled.
12006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
1201e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        if (!node.compareAndSetWaitStatus(Node.CONDITION, 0))
12026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return false;
12036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
12056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Splice onto queue and try to set waitStatus of predecessor to
12066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * indicate that thread is (probably) waiting. If cancelled or
12076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * attempt to set waitStatus fails, wake up to resync (in which
12086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * case the waitStatus can be transiently and harmlessly wrong).
12096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
12106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        Node p = enq(node);
12116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        int ws = p.waitStatus;
1212e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL))
12136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            LockSupport.unpark(node.thread);
12146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return true;
12156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
12166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
121891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Transfers node, if necessary, to sync queue after a cancelled wait.
121991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Returns true if thread was cancelled before being signalled.
122091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     *
122191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @param node the node
12226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return true if cancelled before the node was signalled
12236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
12246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    final boolean transferAfterCancelledWait(Node node) {
1225e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        if (node.compareAndSetWaitStatus(Node.CONDITION, 0)) {
12266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            enq(node);
12276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return true;
12286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
12296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
12306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * If we lost out to a signal(), then we can't proceed
12316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * until it finishes its enq().  Cancelling during an
12326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * incomplete transfer is both rare and transient, so just
12336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * spin.
12346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
12356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        while (!isOnSyncQueue(node))
12366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Thread.yield();
12376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return false;
12386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
12396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
12416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Invokes release with current state value; returns saved state.
12426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Cancels node and throws exception on failure.
12436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param node the condition node for this wait
12446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return previous sync state
12456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
12466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    final long fullyRelease(Node node) {
12476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
12486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long savedState = getState();
1249e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            if (release(savedState))
12506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                return savedState;
1251e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw new IllegalMonitorStateException();
1252e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (Throwable t) {
1253e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            node.waitStatus = Node.CANCELLED;
1254e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw t;
12556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
12566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
12576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    // Instrumentation methods for conditions
12596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
12616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Queries whether the given ConditionObject
12626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * uses this synchronizer as its lock.
12636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
12646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param condition the condition
126591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if owned
12666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws NullPointerException if the condition is null
12676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
12686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean owns(ConditionObject condition) {
12696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return condition.isOwnedBy(this);
12706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
12716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
12736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Queries whether any threads are waiting on the given condition
12746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * associated with this synchronizer. Note that because timeouts
127591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * and interrupts may occur at any time, a {@code true} return
127691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * does not guarantee that a future {@code signal} will awaken
12776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * any threads.  This method is designed primarily for use in
12786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * monitoring of the system state.
12796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
12806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param condition the condition
128191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if there are any waiting threads
12826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if exclusive synchronization
12836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         is not held
12846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalArgumentException if the given condition is
12856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         not associated with this synchronizer
12866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws NullPointerException if the condition is null
12876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
12886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final boolean hasWaiters(ConditionObject condition) {
12896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (!owns(condition))
12906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new IllegalArgumentException("Not owner");
12916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return condition.hasWaiters();
12926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
12936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
12946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
12956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns an estimate of the number of threads waiting on the
12966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * given condition associated with this synchronizer. Note that
12976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * because timeouts and interrupts may occur at any time, the
12986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * estimate serves only as an upper bound on the actual number of
1299e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * waiters.  This method is designed for use in monitoring system
1300e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * state, not for synchronization control.
13016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
13026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param condition the condition
13036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the estimated number of waiting threads
13046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if exclusive synchronization
13056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         is not held
13066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalArgumentException if the given condition is
13076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         not associated with this synchronizer
13086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws NullPointerException if the condition is null
13096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
13106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final int getWaitQueueLength(ConditionObject condition) {
13116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (!owns(condition))
13126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new IllegalArgumentException("Not owner");
13136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return condition.getWaitQueueLength();
13146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
13156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
13166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
13176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns a collection containing those threads that may be
13186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * waiting on the given condition associated with this
13196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * synchronizer.  Because the actual set of threads may change
13206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * dynamically while constructing this result, the returned
13216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * collection is only a best-effort estimate. The elements of the
13226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * returned collection are in no particular order.
13236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
13246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param condition the condition
13256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return the collection of threads
13266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalMonitorStateException if exclusive synchronization
13276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         is not held
13286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalArgumentException if the given condition is
13296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         not associated with this synchronizer
13306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws NullPointerException if the condition is null
13316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
13326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
13336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (!owns(condition))
13346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new IllegalArgumentException("Not owner");
13356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return condition.getWaitingThreads();
13366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
13376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
13386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
13396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Condition implementation for a {@link
13406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * AbstractQueuedLongSynchronizer} serving as the basis of a {@link
13416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Lock} implementation.
13426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
13436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>Method documentation for this class describes mechanics,
13446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * not behavioral specifications from the point of view of Lock
13456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * and Condition users. Exported versions of this class will in
13466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * general need to be accompanied by documentation describing
13476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * condition semantics that rely on those of the associated
134891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * {@code AbstractQueuedLongSynchronizer}.
13496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
13506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * <p>This class is Serializable, but all fields are transient,
13516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * so deserialized conditions have no waiters.
13526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
13536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
13546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
13556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public class ConditionObject implements Condition, java.io.Serializable {
13566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private static final long serialVersionUID = 1173984872572414699L;
13576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /** First node of condition queue. */
13586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private transient Node firstWaiter;
13596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /** Last node of condition queue. */
13606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private transient Node lastWaiter;
13616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
13626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
136391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle         * Creates a new {@code ConditionObject} instance.
13646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
13656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public ConditionObject() { }
13666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
13676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // Internal methods
13686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
13696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
13706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Adds a new waiter to wait queue.
13716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @return its new wait node
13726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
13736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private Node addConditionWaiter() {
13746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node t = lastWaiter;
13756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            // If lastWaiter is cancelled, clean out.
13766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (t != null && t.waitStatus != Node.CONDITION) {
13776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unlinkCancelledWaiters();
13786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                t = lastWaiter;
13796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
1380e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak
1381e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            Node node = new Node(Node.CONDITION);
1382e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak
13836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (t == null)
13846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                firstWaiter = node;
13856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            else
13866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                t.nextWaiter = node;
13876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            lastWaiter = node;
13886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return node;
13896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
13906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
13916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
13926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Removes and transfers nodes until hit non-cancelled one or
13936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * null. Split out from signal in part to encourage compilers
13946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * to inline the case of no waiters.
13956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @param first (non-null) the first node on condition queue
13966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
13976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private void doSignal(Node first) {
13986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            do {
13996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if ( (firstWaiter = first.nextWaiter) == null)
14006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    lastWaiter = null;
14016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                first.nextWaiter = null;
14026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            } while (!transferForSignal(first) &&
14036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                     (first = firstWaiter) != null);
14046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
14056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
14066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
14076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Removes and transfers all nodes.
14086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @param first (non-null) the first node on condition queue
14096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
14106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private void doSignalAll(Node first) {
14116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            lastWaiter = firstWaiter = null;
14126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            do {
14136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                Node next = first.nextWaiter;
14146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                first.nextWaiter = null;
14156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                transferForSignal(first);
14166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                first = next;
14176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            } while (first != null);
14186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
14196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
14206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
14216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Unlinks cancelled waiter nodes from condition queue.
14226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Called only while holding lock. This is called when
14236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * cancellation occurred during condition wait, and upon
14246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * insertion of a new waiter when lastWaiter is seen to have
14256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * been cancelled. This method is needed to avoid garbage
14266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * retention in the absence of signals. So even though it may
14276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * require a full traversal, it comes into play only when
14286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * timeouts or cancellations occur in the absence of
14296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * signals. It traverses all nodes rather than stopping at a
14306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * particular target to unlink all pointers to garbage nodes
14316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * without requiring many re-traversals during cancellation
14326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * storms.
14336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
14346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private void unlinkCancelledWaiters() {
14356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node t = firstWaiter;
14366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node trail = null;
14376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            while (t != null) {
14386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                Node next = t.nextWaiter;
14396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (t.waitStatus != Node.CONDITION) {
14406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    t.nextWaiter = null;
14416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    if (trail == null)
14426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        firstWaiter = next;
14436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    else
14446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        trail.nextWaiter = next;
14456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    if (next == null)
14466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        lastWaiter = trail;
14476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
14486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                else
14496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    trail = t;
14506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                t = next;
14516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
14526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
14536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
14546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        // public methods
14556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
14566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
14576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Moves the longest-waiting thread, if one exists, from the
14586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * wait queue for this condition to the wait queue for the
14596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * owning lock.
14606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
14616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
14626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *         returns {@code false}
14636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
14646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public final void signal() {
14656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (!isHeldExclusively())
14666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new IllegalMonitorStateException();
14676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node first = firstWaiter;
14686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (first != null)
14696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                doSignal(first);
14706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
14716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
14726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
14736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Moves all threads from the wait queue for this condition to
14746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * the wait queue for the owning lock.
14756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
14766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
14776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *         returns {@code false}
14786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
14796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public final void signalAll() {
14806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (!isHeldExclusively())
14816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new IllegalMonitorStateException();
14826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node first = firstWaiter;
14836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (first != null)
14846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                doSignalAll(first);
14856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
14866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
14876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
14886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Implements uninterruptible condition wait.
14896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * <ol>
1490e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Save lock state returned by {@link #getState}.
1491e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Invoke {@link #release} with saved state as argument,
1492e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     throwing IllegalMonitorStateException if it fails.
1493e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Block until signalled.
1494e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Reacquire by invoking specialized version of
1495e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     {@link #acquire} with saved state as argument.
14966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * </ol>
14976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
14986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public final void awaitUninterruptibly() {
14996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node node = addConditionWaiter();
15006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long savedState = fullyRelease(node);
15016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            boolean interrupted = false;
15026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            while (!isOnSyncQueue(node)) {
15036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                LockSupport.park(this);
15046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (Thread.interrupted())
15056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    interrupted = true;
15066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
15076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (acquireQueued(node, savedState) || interrupted)
15086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                selfInterrupt();
15096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
15106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /*
15126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * For interruptible waits, we need to track whether to throw
15136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * InterruptedException, if interrupted while blocked on
15146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * condition, versus reinterrupt current thread, if
15156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * interrupted while blocked waiting to re-acquire.
15166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
15176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /** Mode meaning to reinterrupt on exit from wait */
15196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private static final int REINTERRUPT =  1;
15206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /** Mode meaning to throw InterruptedException on exit from wait */
15216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private static final int THROW_IE    = -1;
15226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
15246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Checks for interrupt, returning THROW_IE if interrupted
15256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * before signalled, REINTERRUPT if after signalled, or
15266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * 0 if not interrupted.
15276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
15286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private int checkInterruptWhileWaiting(Node node) {
15296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return Thread.interrupted() ?
15306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
15316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                0;
15326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
15336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
15356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Throws InterruptedException, reinterrupts current thread, or
15366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * does nothing, depending on mode.
15376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
15386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        private void reportInterruptAfterWait(int interruptMode)
15396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throws InterruptedException {
15406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (interruptMode == THROW_IE)
15416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new InterruptedException();
15426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            else if (interruptMode == REINTERRUPT)
15436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                selfInterrupt();
15446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
15456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
15476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Implements interruptible condition wait.
15486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * <ol>
1549e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If current thread is interrupted, throw InterruptedException.
1550e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Save lock state returned by {@link #getState}.
1551e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Invoke {@link #release} with saved state as argument,
1552e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     throwing IllegalMonitorStateException if it fails.
1553e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Block until signalled or interrupted.
1554e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Reacquire by invoking specialized version of
1555e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     {@link #acquire} with saved state as argument.
1556e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If interrupted while blocked in step 4, throw InterruptedException.
15576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * </ol>
15586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
15596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        public final void await() throws InterruptedException {
15606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (Thread.interrupted())
15616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new InterruptedException();
15626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node node = addConditionWaiter();
15636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long savedState = fullyRelease(node);
15646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            int interruptMode = 0;
15656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            while (!isOnSyncQueue(node)) {
15666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                LockSupport.park(this);
15676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
15686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
15696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
15706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
15716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                interruptMode = REINTERRUPT;
15726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (node.nextWaiter != null) // clean up if cancelled
15736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unlinkCancelledWaiters();
15746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (interruptMode != 0)
15756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                reportInterruptAfterWait(interruptMode);
15766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
15776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
15796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Implements timed condition wait.
15806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * <ol>
1581e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If current thread is interrupted, throw InterruptedException.
1582e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Save lock state returned by {@link #getState}.
1583e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Invoke {@link #release} with saved state as argument,
1584e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     throwing IllegalMonitorStateException if it fails.
1585e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Block until signalled, interrupted, or timed out.
1586e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Reacquire by invoking specialized version of
1587e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     {@link #acquire} with saved state as argument.
1588e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If interrupted while blocked in step 4, throw InterruptedException.
15896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * </ol>
15906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
15918eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        public final long awaitNanos(long nanosTimeout)
15928eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                throws InterruptedException {
15936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (Thread.interrupted())
15946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new InterruptedException();
1595e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            // We don't check for nanosTimeout <= 0L here, to allow
1596e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            // awaitNanos(0) as a way to "yield the lock".
1597e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            final long deadline = System.nanoTime() + nanosTimeout;
1598aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath            long initialNanos = nanosTimeout;
15996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node node = addConditionWaiter();
16006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long savedState = fullyRelease(node);
16016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            int interruptMode = 0;
16026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            while (!isOnSyncQueue(node)) {
16036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (nanosTimeout <= 0L) {
16046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    transferAfterCancelledWait(node);
16056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
16066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
1607e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
160891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                    LockSupport.parkNanos(this, nanosTimeout);
16096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
16106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
161191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                nanosTimeout = deadline - System.nanoTime();
16126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
16136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
16146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                interruptMode = REINTERRUPT;
16156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (node.nextWaiter != null)
16166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unlinkCancelledWaiters();
16176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (interruptMode != 0)
16186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                reportInterruptAfterWait(interruptMode);
1619aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath            long remaining = deadline - System.nanoTime(); // avoid overflow
16208fc2ac0fa8eb47ce607f8412e469d4f680b6ef85Neil Fuller            return (remaining <= initialNanos) ? remaining : Long.MIN_VALUE;
16216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
16226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
16236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
16246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Implements absolute timed condition wait.
16256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * <ol>
1626e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If current thread is interrupted, throw InterruptedException.
1627e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Save lock state returned by {@link #getState}.
1628e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Invoke {@link #release} with saved state as argument,
1629e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     throwing IllegalMonitorStateException if it fails.
1630e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Block until signalled, interrupted, or timed out.
1631e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Reacquire by invoking specialized version of
1632e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     {@link #acquire} with saved state as argument.
1633e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If interrupted while blocked in step 4, throw InterruptedException.
1634e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If timed out while blocked in step 4, return false, else true.
16356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * </ol>
16366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
16378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        public final boolean awaitUntil(Date deadline)
16388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                throws InterruptedException {
16396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long abstime = deadline.getTime();
16406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (Thread.interrupted())
16416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new InterruptedException();
16426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node node = addConditionWaiter();
16436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long savedState = fullyRelease(node);
16446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            boolean timedout = false;
16456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            int interruptMode = 0;
16466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            while (!isOnSyncQueue(node)) {
1647e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (System.currentTimeMillis() >= abstime) {
16486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    timedout = transferAfterCancelledWait(node);
16496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
16506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
16516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                LockSupport.parkUntil(this, abstime);
16526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
16536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
16546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
16556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
16566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                interruptMode = REINTERRUPT;
16576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (node.nextWaiter != null)
16586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unlinkCancelledWaiters();
16596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (interruptMode != 0)
16606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                reportInterruptAfterWait(interruptMode);
16616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return !timedout;
16626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
16636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
16646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
16656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Implements timed condition wait.
16666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * <ol>
1667e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If current thread is interrupted, throw InterruptedException.
1668e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Save lock state returned by {@link #getState}.
1669e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Invoke {@link #release} with saved state as argument,
1670e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     throwing IllegalMonitorStateException if it fails.
1671e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Block until signalled, interrupted, or timed out.
1672e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>Reacquire by invoking specialized version of
1673e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         *     {@link #acquire} with saved state as argument.
1674e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If interrupted while blocked in step 4, throw InterruptedException.
1675e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * <li>If timed out while blocked in step 4, return false, else true.
16766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * </ol>
16776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
16788eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        public final boolean await(long time, TimeUnit unit)
16798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                throws InterruptedException {
16806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long nanosTimeout = unit.toNanos(time);
16816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (Thread.interrupted())
16826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new InterruptedException();
1683e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            // We don't check for nanosTimeout <= 0L here, to allow
1684e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            // await(0, unit) as a way to "yield the lock".
1685e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            final long deadline = System.nanoTime() + nanosTimeout;
16866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            Node node = addConditionWaiter();
16876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            long savedState = fullyRelease(node);
16886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            boolean timedout = false;
16896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            int interruptMode = 0;
16906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            while (!isOnSyncQueue(node)) {
16916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (nanosTimeout <= 0L) {
16926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    timedout = transferAfterCancelledWait(node);
16936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
16946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
1695e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak                if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
16966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    LockSupport.parkNanos(this, nanosTimeout);
16976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
16986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    break;
169991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle                nanosTimeout = deadline - System.nanoTime();
17006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
17016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
17026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                interruptMode = REINTERRUPT;
17036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (node.nextWaiter != null)
17046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                unlinkCancelledWaiters();
17056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (interruptMode != 0)
17066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                reportInterruptAfterWait(interruptMode);
17076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return !timedout;
17086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
17096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        //  support for instrumentation
17116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
17136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Returns true if this condition was created by the given
17146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * synchronization object.
17156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
17166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @return {@code true} if owned
17176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
17186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) {
17196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return sync == AbstractQueuedLongSynchronizer.this;
17206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
17216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
17236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Queries whether any threads are waiting on this condition.
1724e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters(ConditionObject)}.
17256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
17266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @return {@code true} if there are any waiting threads
17276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
17286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *         returns {@code false}
17296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
17306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        protected final boolean hasWaiters() {
17316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (!isHeldExclusively())
17326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new IllegalMonitorStateException();
17336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
17346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (w.waitStatus == Node.CONDITION)
17356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    return true;
17366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
17376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return false;
17386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
17396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
17416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Returns an estimate of the number of threads waiting on
17426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * this condition.
1743e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength(ConditionObject)}.
17446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
17456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @return the estimated number of waiting threads
17466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
17476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *         returns {@code false}
17486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
17496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        protected final int getWaitQueueLength() {
17506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (!isHeldExclusively())
17516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new IllegalMonitorStateException();
17526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            int n = 0;
17536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
17546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (w.waitStatus == Node.CONDITION)
17556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    ++n;
17566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
17576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return n;
17586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
17596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        /**
17616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * Returns a collection containing those threads that may be
17626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * waiting on this Condition.
1763e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak         * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads(ConditionObject)}.
17646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *
17656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @return the collection of threads
17666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
17676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         *         returns {@code false}
17686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson         */
17696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        protected final Collection<Thread> getWaitingThreads() {
17706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (!isHeldExclusively())
17716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                throw new IllegalMonitorStateException();
1772e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            ArrayList<Thread> list = new ArrayList<>();
17736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
17746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (w.waitStatus == Node.CONDITION) {
17756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    Thread t = w.thread;
17766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                    if (t != null)
17776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                        list.add(t);
17786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                }
17796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            }
17806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            return list;
17816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
17826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
17836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
17856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Setup to support compareAndSet. We need to natively implement
17866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * this here: For the sake of permitting future enhancements, we
17876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * cannot explicitly subclass AtomicLong, which would be
17886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * efficient and useful otherwise. So, as the lesser of evils, we
17896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * natively implement using hotspot intrinsics API. And while we
17906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * are at it, we do the same for other CASable fields (which could
17916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * otherwise be done with atomic field updaters).
17926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1793e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
1794e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    private static final long STATE;
1795e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    private static final long HEAD;
1796e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    private static final long TAIL;
17976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
17986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    static {
17996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        try {
1800e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            STATE = U.objectFieldOffset
18016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
1802e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            HEAD = U.objectFieldOffset
18036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
1804e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            TAIL = U.objectFieldOffset
18056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
1806e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        } catch (ReflectiveOperationException e) {
1807e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            throw new Error(e);
1808e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        }
1809aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath
1810aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath        // Reduce the risk of rare disastrous classloading in first call to
1811aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
1812aa2ed9e105504f21641d919b410c692981cfe386Narayan Kamath        Class<?> ensureLoaded = LockSupport.class;
18136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
18146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
18156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1816e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * Initializes head and tail fields on first contention.
18176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1818e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    private final void initializeSyncQueue() {
1819e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        Node h;
1820e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
1821e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak            tail = h;
18226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
18236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
18246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1825e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak     * CASes tail field.
18266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
18276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private final boolean compareAndSetTail(Node expect, Node update) {
1828e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak        return U.compareAndSwapObject(this, TAIL, expect, update);
18296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
18306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson}
1831