jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java
author mchung
Fri, 22 May 2015 16:43:39 -0700
changeset 30789 9eca83469588
parent 25859 3317bb8137f4
child 32991 b27c76b82713
permissions -rw-r--r--
8074431: Remove native2ascii tool Reviewed-by: erikj, alanb, okutsu, mfang, naoto
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     6
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     8
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * This file is available under and governed by the GNU General Public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * License version 2 only, as published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * However, the following notice accompanied the original version of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * file:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * Written by Doug Lea, Bill Scherer, and Michael Scott with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * assistance from members of JCP JSR-166 Expert Group and released to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * the public domain, as explained at
9242
ef138d47df58 7034657: Update Creative Commons license URL in legal notices
dl
parents: 8544
diff changeset
    34
 * http://creativecommons.org/publicdomain/zero/1.0/
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
package java.util.concurrent;
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
    38
import java.util.concurrent.locks.LockSupport;
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
    39
import java.util.concurrent.locks.ReentrantLock;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.*;
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
    41
import java.util.Spliterator;
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
    42
import java.util.Spliterators;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * A {@linkplain BlockingQueue blocking queue} in which each insert
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * operation must wait for a corresponding remove operation by another
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * thread, and vice versa.  A synchronous queue does not have any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * internal capacity, not even a capacity of one.  You cannot
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    49
 * {@code peek} at a synchronous queue because an element is only
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * present when you try to remove it; you cannot insert an element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * (using any method) unless another thread is trying to remove it;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * you cannot iterate as there is nothing to iterate.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * <em>head</em> of the queue is the element that the first queued
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * inserting thread is trying to add to the queue; if there is no such
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * queued thread then no element is available for removal and
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    56
 * {@code poll()} will return {@code null}.  For purposes of other
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    57
 * {@code Collection} methods (for example {@code contains}), a
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    58
 * {@code SynchronousQueue} acts as an empty collection.  This queue
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    59
 * does not permit {@code null} elements.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * <p>Synchronous queues are similar to rendezvous channels used in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * CSP and Ada. They are well suited for handoff designs, in which an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * object running in one thread must sync up with an object running
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * in another thread in order to hand it some information, event, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    67
 * <p>This class supports an optional fairness policy for ordering
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * waiting producer and consumer threads.  By default, this ordering
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * is not guaranteed. However, a queue constructed with fairness set
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    70
 * to {@code true} grants threads access in FIFO order.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * <p>This class and its iterator implement all of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * <em>optional</em> methods of the {@link Collection} and {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * Iterator} interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * <p>This class is a member of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * Java Collections Framework</a>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * @author Doug Lea and Bill Scherer and Michael Scott
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * @param <E> the type of elements held in this collection
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
public class SynchronousQueue<E> extends AbstractQueue<E>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    implements BlockingQueue<E>, java.io.Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    private static final long serialVersionUID = -3223113410248163686L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
     * This class implements extensions of the dual stack and dual
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * queue algorithms described in "Nonblocking Concurrent Objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * with Condition Synchronization", by W. N. Scherer III and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * M. L. Scott.  18th Annual Conf. on Distributed Computing,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * Oct. 2004 (see also
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/duals.html).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * The (Lifo) stack is used for non-fair mode, and the (Fifo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * queue for fair mode. The performance of the two is generally
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     * similar. Fifo usually supports higher throughput under
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * contention but Lifo maintains higher thread locality in common
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * applications.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * A dual queue (and similarly stack) is one that at any given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * time either holds "data" -- items provided by put operations,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * or "requests" -- slots representing take operations, or is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * empty. A call to "fulfill" (i.e., a call requesting an item
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * from a queue holding data or vice versa) dequeues a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * complementary node.  The most interesting feature of these
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * queues is that any operation can figure out which mode the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * queue is in, and act accordingly without needing locks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * Both the queue and stack extend abstract class Transferer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * defining the single method transfer that does a put or a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * take. These are unified into a single method because in dual
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * data structures, the put and take operations are symmetrical,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * so nearly all code can be combined. The resulting transfer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * methods are on the long side, but are easier to follow than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * they would be if broken up into nearly-duplicated parts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * The queue and stack data structures share many conceptual
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * similarities but very few concrete details. For simplicity,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * they are kept distinct so that they can later evolve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * separately.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * The algorithms here differ from the versions in the above paper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * in extending them for use in synchronous queues, as well as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * dealing with cancellation. The main differences include:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *  1. The original algorithms used bit-marked pointers, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     *     the ones here use mode bits in nodes, leading to a number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     *     of further adaptations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     *  2. SynchronousQueues must block threads waiting to become
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     *     fulfilled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     *  3. Support for cancellation via timeout and interrupts,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     *     including cleaning out cancelled nodes/threads
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     *     from lists to avoid garbage retention and memory depletion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * Blocking is mainly accomplished using LockSupport park/unpark,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * except that nodes that appear to be the next ones to become
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * fulfilled first spin a bit (on multiprocessors only). On very
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * busy synchronous queues, spinning can dramatically improve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * throughput. And on less busy ones, the amount of spinning is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * small enough not to be noticeable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * Cleaning is done in different ways in queues vs stacks.  For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * queues, we can almost always remove a node immediately in O(1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * time (modulo retries for consistency checks) when it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * cancelled. But if it may be pinned as the current tail, it must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * wait until some subsequent cancellation. For stacks, we need a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * potentially O(n) traversal to be sure that we can remove the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * node, but this can run concurrently with other threads
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * accessing the stack.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * While garbage collection takes care of most node reclamation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * issues that otherwise complicate nonblocking algorithms, care
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * is taken to "forget" references to data, other nodes, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * threads that might be held on to long-term by blocked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * threads. In cases where setting to null would otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * conflict with main algorithms, this is done by changing a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * node's link to now point to the node itself. This doesn't arise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * much for Stack nodes (because blocked threads do not hang on to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * old head pointers), but references in Queue nodes must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * aggressively forgotten to avoid reachability of everything any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * node has ever referred to since arrival.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * Shared internal API for dual stacks and queues.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   168
    abstract static class Transferer<E> {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
         * Performs a put or take.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
         * @param e if non-null, the item to be handed to a consumer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         *          if null, requests that transfer return an item
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         *          offered by producer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         * @param timed if this operation should timeout
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
         * @param nanos the timeout, in nanoseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
         * @return if non-null, the item provided or received; if null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
         *         the operation failed due to timeout or interrupt --
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
         *         the caller can distinguish which of these occurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
         *         by checking Thread.interrupted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
         */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   182
        abstract E transfer(E e, boolean timed, long nanos);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    /** The number of CPUs, for spin control */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    static final int NCPUS = Runtime.getRuntime().availableProcessors();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * The number of times to spin before blocking in timed waits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * The value is empirically derived -- it works well across a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * variety of processors and OSes. Empirically, the best value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * seems not to vary with number of CPUs (beyond 2) so is just
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * a constant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     */
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   195
    static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * The number of times to spin before blocking in untimed waits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     * This is greater than timed value because untimed waits spin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * faster since they don't need to check times on each spin.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    static final int maxUntimedSpins = maxTimedSpins * 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * The number of nanoseconds for which it is faster to spin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * rather than to use timed park. A rough estimate suffices.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    static final long spinForTimeoutThreshold = 1000L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    /** Dual stack */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   211
    static final class TransferStack<E> extends Transferer<E> {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
         * This extends Scherer-Scott dual stack algorithm, differing,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
         * among other ways, by using "covering" nodes rather than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
         * bit-marked pointers: Fulfilling operations push on marker
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
         * nodes (with FULFILLING bit set in mode) to reserve a spot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
         * to match a waiting node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        /* Modes for SNodes, ORed together in node fields */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        /** Node represents an unfulfilled consumer */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        static final int REQUEST    = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        /** Node represents an unfulfilled producer */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        static final int DATA       = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        /** Node is fulfilling another unfulfilled DATA or REQUEST */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        static final int FULFILLING = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   228
        /** Returns true if m has fulfilling bit set. */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        static boolean isFulfilling(int m) { return (m & FULFILLING) != 0; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        /** Node class for TransferStacks. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        static final class SNode {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            volatile SNode next;        // next node in stack
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            volatile SNode match;       // the node matched to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            volatile Thread waiter;     // to control park/unpark
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            Object item;                // data; or null for REQUESTs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            int mode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            // Note: item and mode fields don't need to be volatile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            // since they are always written before, and read after,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            // other volatile/atomic operations.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            SNode(Object item) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                this.item = item;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            boolean casNext(SNode cmp, SNode val) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   247
                return cmp == next &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   248
                    UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
             * Tries to match node s to this node, if so, waking up thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
             * Fulfillers call tryMatch to identify their waiters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
             * Waiters block until they have been matched.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
             * @param s the node to match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
             * @return true if successfully matched to s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            boolean tryMatch(SNode s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                if (match == null &&
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   261
                    UNSAFE.compareAndSwapObject(this, matchOffset, null, s)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                    Thread w = waiter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                    if (w != null) {    // waiters need at most one unpark
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                        waiter = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                        LockSupport.unpark(w);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                return match == s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
             * Tries to cancel a wait by matching node to itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            void tryCancel() {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   276
                UNSAFE.compareAndSwapObject(this, matchOffset, null, this);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            boolean isCancelled() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                return match == this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            }
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   282
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   283
            // Unsafe mechanics
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   284
            private static final sun.misc.Unsafe UNSAFE;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   285
            private static final long matchOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   286
            private static final long nextOffset;
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   287
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   288
            static {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   289
                try {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   290
                    UNSAFE = sun.misc.Unsafe.getUnsafe();
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   291
                    Class<?> k = SNode.class;
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   292
                    matchOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   293
                        (k.getDeclaredField("match"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   294
                    nextOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   295
                        (k.getDeclaredField("next"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   296
                } catch (Exception e) {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   297
                    throw new Error(e);
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   298
                }
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   299
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        /** The head (top) of the stack */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        volatile SNode head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        boolean casHead(SNode h, SNode nh) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   306
            return h == head &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   307
                UNSAFE.compareAndSwapObject(this, headOffset, h, nh);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
         * Creates or resets fields of a node. Called only from transfer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
         * where the node to push on stack is lazily created and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
         * reused when possible to help reduce intervals between reads
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
         * and CASes of head and to avoid surges of garbage when CASes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
         * to push nodes fail due to contention.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        static SNode snode(SNode s, Object e, SNode next, int mode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            if (s == null) s = new SNode(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            s.mode = mode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            s.next = next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            return s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
         * Puts or takes an item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
         */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   327
        @SuppressWarnings("unchecked")
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   328
        E transfer(E e, boolean timed, long nanos) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
             * Basic algorithm is to loop trying one of three actions:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
             * 1. If apparently empty or already containing nodes of same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
             *    mode, try to push node on stack and wait for a match,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
             *    returning it, or null if cancelled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
             * 2. If apparently containing node of complementary mode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
             *    try to push a fulfilling node on to stack, match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
             *    with corresponding waiting node, pop both from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
             *    stack, and return matched item. The matching or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
             *    unlinking might not actually be necessary because of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
             *    other threads performing action 3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
             * 3. If top of stack already holds another fulfilling node,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
             *    help it out by doing its match and/or pop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
             *    operations, and then continue. The code for helping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
             *    is essentially the same as for fulfilling, except
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
             *    that it doesn't return the item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            SNode s = null; // constructed/reused as needed
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   351
            int mode = (e == null) ? REQUEST : DATA;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                SNode h = head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                if (h == null || h.mode == mode) {  // empty or same-mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                    if (timed && nanos <= 0) {      // can't wait
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                        if (h != null && h.isCancelled())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                            casHead(h, h.next);     // pop cancelled node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                    } else if (casHead(h, s = snode(s, e, h, mode))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                        SNode m = awaitFulfill(s, timed, nanos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                        if (m == s) {               // wait was cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                            clean(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                        if ((h = head) != null && h.next == s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                            casHead(h, s.next);     // help s's fulfiller
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   369
                        return (E) ((mode == REQUEST) ? m.item : s.item);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                } else if (!isFulfilling(h.mode)) { // try to fulfill
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                    if (h.isCancelled())            // already cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                        casHead(h, h.next);         // pop and retry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                    else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                        for (;;) { // loop until matched or waiters disappear
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                            SNode m = s.next;       // m is s's match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                            if (m == null) {        // all waiters are gone
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                                casHead(s, null);   // pop fulfill node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                                s = null;           // use new node next time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                                break;              // restart main loop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                            SNode mn = m.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                            if (m.tryMatch(s)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                                casHead(s, mn);     // pop both s and m
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   385
                                return (E) ((mode == REQUEST) ? m.item : s.item);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                            } else                  // lost match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                                s.casNext(m, mn);   // help unlink
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                } else {                            // help a fulfiller
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                    SNode m = h.next;               // m is h's match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                    if (m == null)                  // waiter is gone
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                        casHead(h, null);           // pop fulfilling node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                        SNode mn = m.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                        if (m.tryMatch(h))          // help match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                            casHead(h, mn);         // pop both h and m
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                        else                        // lost match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                            h.casNext(m, mn);       // help unlink
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
         * Spins/blocks until node s is matched by a fulfill operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
         * @param s the waiting node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
         * @param timed true if timed wait
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
         * @param nanos timeout value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
         * @return matched node, or s if cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        SNode awaitFulfill(SNode s, boolean timed, long nanos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
             * When a node/thread is about to block, it sets its waiter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
             * field and then rechecks state at least one more time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
             * before actually parking, thus covering race vs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
             * fulfiller noticing that waiter is non-null so should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
             * woken.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
             * When invoked by nodes that appear at the point of call
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
             * to be at the head of the stack, calls to park are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
             * preceded by spins to avoid blocking when producers and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
             * consumers are arriving very close in time.  This can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
             * happen enough to bother only on multiprocessors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
             * The order of checks for returning out of main loop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
             * reflects fact that interrupts have precedence over
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
             * normal returns, which have precedence over
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
             * timeouts. (So, on timeout, one last check for match is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
             * done before giving up.) Except that calls from untimed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
             * SynchronousQueue.{poll/offer} don't check interrupts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
             * and don't wait at all, so are trapped in transfer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
             * method rather than calling awaitFulfill.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
             */
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   436
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            Thread w = Thread.currentThread();
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   438
            int spins = (shouldSpin(s) ?
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   439
                         (timed ? maxTimedSpins : maxUntimedSpins) : 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                if (w.isInterrupted())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                    s.tryCancel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                SNode m = s.match;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                if (m != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                    return m;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                if (timed) {
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   447
                    nanos = deadline - System.nanoTime();
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   448
                    if (nanos <= 0L) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                        s.tryCancel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                if (spins > 0)
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   454
                    spins = shouldSpin(s) ? (spins-1) : 0;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                else if (s.waiter == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                    s.waiter = w; // establish waiter so can park next iter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                else if (!timed)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                    LockSupport.park(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                else if (nanos > spinForTimeoutThreshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                    LockSupport.parkNanos(this, nanos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
         * Returns true if node s is at head or there is an active
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
         * fulfiller.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        boolean shouldSpin(SNode s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            SNode h = head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            return (h == s || h == null || isFulfilling(h.mode));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
         * Unlinks s from the stack.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        void clean(SNode s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            s.item = null;   // forget item
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            s.waiter = null; // forget thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
             * At worst we may need to traverse entire stack to unlink
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
             * s. If there are multiple concurrent calls to clean, we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
             * might not see s if another thread has already removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
             * it. But we can stop when we see any node known to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
             * follow s. We use s.next unless it too is cancelled, in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
             * which case we try the node one past. We don't check any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
             * further because we don't want to doubly traverse just to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
             * find sentinel.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            SNode past = s.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            if (past != null && past.isCancelled())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                past = past.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            // Absorb cancelled nodes at head
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            SNode p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            while ((p = head) != null && p != past && p.isCancelled())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                casHead(p, p.next);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            // Unsplice embedded nodes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            while (p != null && p != past) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                SNode n = p.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                if (n != null && n.isCancelled())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                    p.casNext(n, n.next);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                    p = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        }
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   509
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   510
        // Unsafe mechanics
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   511
        private static final sun.misc.Unsafe UNSAFE;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   512
        private static final long headOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   513
        static {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   514
            try {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   515
                UNSAFE = sun.misc.Unsafe.getUnsafe();
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   516
                Class<?> k = TransferStack.class;
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   517
                headOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   518
                    (k.getDeclaredField("head"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   519
            } catch (Exception e) {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   520
                throw new Error(e);
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   521
            }
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   522
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    /** Dual Queue */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   526
    static final class TransferQueue<E> extends Transferer<E> {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
         * This extends Scherer-Scott dual queue algorithm, differing,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
         * among other ways, by using modes within nodes rather than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
         * marked pointers. The algorithm is a little simpler than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
         * that for stacks because fulfillers do not need explicit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
         * nodes, and matching is done by CAS'ing QNode.item field
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
         * from non-null to null (for put) or vice versa (for take).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        /** Node class for TransferQueue. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        static final class QNode {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            volatile QNode next;          // next node in queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            volatile Object item;         // CAS'ed to or from null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            volatile Thread waiter;       // to control park/unpark
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            final boolean isData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            QNode(Object item, boolean isData) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                this.item = item;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                this.isData = isData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            boolean casNext(QNode cmp, QNode val) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   549
                return next == cmp &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   550
                    UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            boolean casItem(Object cmp, Object val) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   554
                return item == cmp &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   555
                    UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
             * Tries to cancel by CAS'ing ref to this as item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            void tryCancel(Object cmp) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   562
                UNSAFE.compareAndSwapObject(this, itemOffset, cmp, this);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            boolean isCancelled() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                return item == this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
             * Returns true if this node is known to be off the queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
             * because its next pointer has been forgotten due to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
             * an advanceHead operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            boolean isOffList() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                return next == this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            }
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   577
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   578
            // Unsafe mechanics
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   579
            private static final sun.misc.Unsafe UNSAFE;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   580
            private static final long itemOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   581
            private static final long nextOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   582
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   583
            static {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   584
                try {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   585
                    UNSAFE = sun.misc.Unsafe.getUnsafe();
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   586
                    Class<?> k = QNode.class;
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   587
                    itemOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   588
                        (k.getDeclaredField("item"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   589
                    nextOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   590
                        (k.getDeclaredField("next"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   591
                } catch (Exception e) {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   592
                    throw new Error(e);
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   593
                }
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   594
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        /** Head of queue */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        transient volatile QNode head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        /** Tail of queue */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        transient volatile QNode tail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
         * Reference to a cancelled node that might not yet have been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
         * unlinked from queue because it was the last inserted node
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   604
         * when it was cancelled.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        transient volatile QNode cleanMe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        TransferQueue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            QNode h = new QNode(null, false); // initialize to dummy node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            head = h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            tail = h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
         * Tries to cas nh as new head; if successful, unlink
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
         * old head's next node to avoid garbage retention.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        void advanceHead(QNode h, QNode nh) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   619
            if (h == head &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   620
                UNSAFE.compareAndSwapObject(this, headOffset, h, nh))
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                h.next = h; // forget old next
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
         * Tries to cas nt as new tail.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        void advanceTail(QNode t, QNode nt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            if (tail == t)
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   629
                UNSAFE.compareAndSwapObject(this, tailOffset, t, nt);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
         * Tries to CAS cleanMe slot.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        boolean casCleanMe(QNode cmp, QNode val) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   636
            return cleanMe == cmp &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   637
                UNSAFE.compareAndSwapObject(this, cleanMeOffset, cmp, val);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
         * Puts or takes an item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
         */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   643
        @SuppressWarnings("unchecked")
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   644
        E transfer(E e, boolean timed, long nanos) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            /* Basic algorithm is to loop trying to take either of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
             * two actions:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
             * 1. If queue apparently empty or holding same-mode nodes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
             *    try to add node to queue of waiters, wait to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
             *    fulfilled (or cancelled) and return matching item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
             * 2. If queue apparently contains waiting items, and this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
             *    call is of complementary mode, try to fulfill by CAS'ing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
             *    item field of waiting node and dequeuing it, and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
             *    returning matching item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
             * In each case, along the way, check for and try to help
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
             * advance head and tail on behalf of other stalled/slow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
             * threads.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
             * The loop starts off with a null check guarding against
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
             * seeing uninitialized head or tail values. This never
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
             * happens in current SynchronousQueue, but could if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
             * callers held non-volatile/final ref to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
             * transferer. The check is here anyway because it places
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
             * null checks at top of loop, which is usually faster
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
             * than having them implicitly interspersed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            QNode s = null; // constructed/reused as needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
            boolean isData = (e != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                QNode t = tail;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                QNode h = head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                if (t == null || h == null)         // saw uninitialized value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                    continue;                       // spin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                if (h == t || t.isData == isData) { // empty or same-mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                    QNode tn = t.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                    if (t != tail)                  // inconsistent read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                    if (tn != null) {               // lagging tail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                        advanceTail(t, tn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                    if (timed && nanos <= 0)        // can't wait
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                    if (s == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                        s = new QNode(e, isData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                    if (!t.casNext(null, s))        // failed to link in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                    advanceTail(t, s);              // swing tail and wait
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    Object x = awaitFulfill(s, e, timed, nanos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                    if (x == s) {                   // wait was cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                        clean(t, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                    if (!s.isOffList()) {           // not already unlinked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                        advanceHead(t, s);          // unlink if head
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                        if (x != null)              // and forget fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                            s.item = s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
                        s.waiter = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                    }
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   707
                    return (x != null) ? (E)x : e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                } else {                            // complementary-mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                    QNode m = h.next;               // node to fulfill
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                    if (t != tail || m == null || h != head)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                        continue;                   // inconsistent read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                    Object x = m.item;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                    if (isData == (x != null) ||    // m already fulfilled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                        x == m ||                   // m cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                        !m.casItem(x, e)) {         // lost CAS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                        advanceHead(h, m);          // dequeue and retry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                    advanceHead(h, m);              // successfully fulfilled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                    LockSupport.unpark(m.waiter);
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   724
                    return (x != null) ? (E)x : e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
         * Spins/blocks until node s is fulfilled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
         * @param s the waiting node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
         * @param e the comparison value for checking match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
         * @param timed true if timed wait
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
         * @param nanos timeout value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
         * @return matched item, or s if cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
         */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   738
        Object awaitFulfill(QNode s, E e, boolean timed, long nanos) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            /* Same idea as TransferStack.awaitFulfill */
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   740
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            Thread w = Thread.currentThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            int spins = ((head.next == s) ?
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   743
                         (timed ? maxTimedSpins : maxUntimedSpins) : 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                if (w.isInterrupted())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                    s.tryCancel(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                Object x = s.item;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                if (x != e)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                    return x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                if (timed) {
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   751
                    nanos = deadline - System.nanoTime();
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   752
                    if (nanos <= 0L) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                        s.tryCancel(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                if (spins > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    --spins;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                else if (s.waiter == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                    s.waiter = w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                else if (!timed)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                    LockSupport.park(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                else if (nanos > spinForTimeoutThreshold)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                    LockSupport.parkNanos(this, nanos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
         * Gets rid of cancelled node s with original predecessor pred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        void clean(QNode pred, QNode s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            s.waiter = null; // forget thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
             * At any given time, exactly one node on list cannot be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
             * deleted -- the last inserted node. To accommodate this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
             * if we cannot delete s, we save its predecessor as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
             * "cleanMe", deleting the previously saved version
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
             * first. At least one of node s or the node previously
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
             * saved can always be deleted, so this always terminates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            while (pred.next == s) { // Return early if already unlinked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                QNode h = head;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                QNode hn = h.next;   // Absorb cancelled first node as head
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                if (hn != null && hn.isCancelled()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                    advanceHead(h, hn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                QNode t = tail;      // Ensure consistent read for tail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                if (t == h)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                    return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                QNode tn = t.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                if (t != tail)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                if (tn != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                    advanceTail(t, tn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                if (s != t) {        // If not tail, try to unsplice
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                    QNode sn = s.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                    if (sn == s || pred.casNext(s, sn))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                QNode dp = cleanMe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                if (dp != null) {    // Try unlinking previous cancelled node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                    QNode d = dp.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                    QNode dn;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                    if (d == null ||               // d is gone or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                        d == dp ||                 // d is off list or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                        !d.isCancelled() ||        // d not cancelled or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                        (d != t &&                 // d not tail and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                         (dn = d.next) != null &&  //   has successor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                         dn != d &&                //   that is on list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                         dp.casNext(d, dn)))       // d unspliced
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                        casCleanMe(dp, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                    if (dp == pred)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                        return;      // s is already saved node
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                } else if (casCleanMe(null, pred))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                    return;          // Postpone cleaning s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        }
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
   821
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   822
        private static final sun.misc.Unsafe UNSAFE;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   823
        private static final long headOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   824
        private static final long tailOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   825
        private static final long cleanMeOffset;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   826
        static {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   827
            try {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   828
                UNSAFE = sun.misc.Unsafe.getUnsafe();
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   829
                Class<?> k = TransferQueue.class;
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   830
                headOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   831
                    (k.getDeclaredField("head"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   832
                tailOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   833
                    (k.getDeclaredField("tail"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   834
                cleanMeOffset = UNSAFE.objectFieldOffset
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   835
                    (k.getDeclaredField("cleanMe"));
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   836
            } catch (Exception e) {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   837
                throw new Error(e);
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   838
            }
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   839
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     * The transferer. Set only in constructor, but cannot be declared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
     * as final without further complicating serialization.  Since
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
     * this is accessed only at most once per public method, there
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
     * isn't a noticeable performance penalty for using volatile
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
     * instead of final here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
     */
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   849
    private transient volatile Transferer<E> transferer;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   852
     * Creates a {@code SynchronousQueue} with nonfair access policy.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
    public SynchronousQueue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        this(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   859
     * Creates a {@code SynchronousQueue} with the specified fairness policy.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
     * @param fair if true, waiting threads contend in FIFO order for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
     *        access; otherwise the order is unspecified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
    public SynchronousQueue(boolean fair) {
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   865
        transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
     * Adds the specified element to this queue, waiting if necessary for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
     * another thread to receive it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
     * @throws InterruptedException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
     * @throws NullPointerException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     */
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   875
    public void put(E e) throws InterruptedException {
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   876
        if (e == null) throw new NullPointerException();
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   877
        if (transferer.transfer(e, false, 0) == null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
            Thread.interrupted();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
            throw new InterruptedException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
     * Inserts the specified element into this queue, waiting if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
     * up to the specified wait time for another thread to receive it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   887
     * @return {@code true} if successful, or {@code false} if the
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   888
     *         specified waiting time elapses before a consumer appears
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
     * @throws InterruptedException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
     * @throws NullPointerException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
     */
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   892
    public boolean offer(E e, long timeout, TimeUnit unit)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        throws InterruptedException {
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   894
        if (e == null) throw new NullPointerException();
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   895
        if (transferer.transfer(e, true, unit.toNanos(timeout)) != null)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        if (!Thread.interrupted())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        throw new InterruptedException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
     * Inserts the specified element into this queue, if another thread is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
     * waiting to receive it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
     * @param e the element to add
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   907
     * @return {@code true} if the element was added to this queue, else
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   908
     *         {@code false}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
     * @throws NullPointerException if the specified element is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    public boolean offer(E e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
        if (e == null) throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
        return transferer.transfer(e, true, 0) != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     * Retrieves and removes the head of this queue, waiting if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     * for another thread to insert it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     * @return the head of this queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
     * @throws InterruptedException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    public E take() throws InterruptedException {
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   924
        E e = transferer.transfer(null, false, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        if (e != null)
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   926
            return e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
        Thread.interrupted();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
        throw new InterruptedException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
     * Retrieves and removes the head of this queue, waiting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
     * if necessary up to the specified wait time, for another thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
     * to insert it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   936
     * @return the head of this queue, or {@code null} if the
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   937
     *         specified waiting time elapses before an element is present
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
     * @throws InterruptedException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   941
        E e = transferer.transfer(null, true, unit.toNanos(timeout));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
        if (e != null || !Thread.interrupted())
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   943
            return e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        throw new InterruptedException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
     * Retrieves and removes the head of this queue, if another thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     * is currently making an element available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   951
     * @return the head of this queue, or {@code null} if no
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   952
     *         element is available
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
    public E poll() {
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
   955
        return transferer.transfer(null, true, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   959
     * Always returns {@code true}.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   960
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   962
     * @return {@code true}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    public boolean isEmpty() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
     * Always returns zero.
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   970
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   972
     * @return zero
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    public int size() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
     * Always returns zero.
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   980
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   982
     * @return zero
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    public int remainingCapacity() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
     * Does nothing.
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   990
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   996
     * Always returns {@code false}.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   997
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
     * @param o the element
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1000
     * @return {@code false}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
    public boolean contains(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1007
     * Always returns {@code false}.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1008
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
     * @param o the element to remove
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1011
     * @return {@code false}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
    public boolean remove(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1018
     * Returns {@code false} unless the given collection is empty.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1019
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
     * @param c the collection
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1022
     * @return {@code false} unless given collection is empty
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    public boolean containsAll(Collection<?> c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        return c.isEmpty();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1029
     * Always returns {@code false}.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1030
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
     * @param c the collection
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1033
     * @return {@code false}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
    public boolean removeAll(Collection<?> c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1040
     * Always returns {@code false}.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1041
     * A {@code SynchronousQueue} has no internal capacity.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
     * @param c the collection
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1044
     * @return {@code false}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
    public boolean retainAll(Collection<?> c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1051
     * Always returns {@code null}.
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1052
     * A {@code SynchronousQueue} does not return elements
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
     * unless actively waited on.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
     *
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1055
     * @return {@code null}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
    public E peek() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1062
     * Returns an empty iterator in which {@code hasNext} always returns
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1063
     * {@code false}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
     * @return an empty iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
    public Iterator<E> iterator() {
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1068
        return Collections.emptyIterator();
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1069
    }
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1070
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1071
    /**
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1072
     * Returns an empty spliterator in which calls to
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1073
     * {@link java.util.Spliterator#trySplit()} always return {@code null}.
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1074
     *
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1075
     * @return an empty spliterator
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1076
     * @since 1.8
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1077
     */
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1078
    public Spliterator<E> spliterator() {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1079
        return Spliterators.emptySpliterator();
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1080
    }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1081
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
     * Returns a zero-length array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
     * @return a zero-length array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
    public Object[] toArray() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
        return new Object[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
    /**
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1091
     * Sets the zeroeth element of the specified array to {@code null}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
     * (if the array has non-zero length) and returns it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
     * @param a the array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
     * @return the specified array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
     * @throws NullPointerException if the specified array is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
    public <T> T[] toArray(T[] a) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        if (a.length > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            a[0] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        return a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
     * @throws UnsupportedOperationException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
     * @throws ClassCastException            {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
     * @throws NullPointerException          {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
     * @throws IllegalArgumentException      {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
    public int drainTo(Collection<? super E> c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
        if (c == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        if (c == this)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        int n = 0;
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1116
        for (E e; (e = poll()) != null;) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
            c.add(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
            ++n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
     * @throws UnsupportedOperationException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
     * @throws ClassCastException            {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
     * @throws NullPointerException          {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
     * @throws IllegalArgumentException      {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
    public int drainTo(Collection<? super E> c, int maxElements) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
        if (c == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        if (c == this)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
        int n = 0;
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1135
        for (E e; n < maxElements && (e = poll()) != null;) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            c.add(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
            ++n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
        return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
     * To cope with serialization strategy in the 1.5 version of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
     * SynchronousQueue, we declare some unused classes and fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
     * that exist solely to enable serializability across versions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
     * These fields are never used, so are initialized only if this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
     * object is ever serialized or deserialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1150
    @SuppressWarnings("serial")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
    static class WaitQueue implements java.io.Serializable { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
    static class LifoWaitQueue extends WaitQueue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
        private static final long serialVersionUID = -3633113410248163686L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
    static class FifoWaitQueue extends WaitQueue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
        private static final long serialVersionUID = -3623113410248163686L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
    private ReentrantLock qlock;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
    private WaitQueue waitingProducers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
    private WaitQueue waitingConsumers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    /**
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
  1163
     * Saves this queue to a stream (that is, serializes it).
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1164
     * @param s the stream
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1165
     * @throws java.io.IOException if an I/O error occurs
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
    private void writeObject(java.io.ObjectOutputStream s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
        throws java.io.IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
        boolean fair = transferer instanceof TransferQueue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
        if (fair) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
            qlock = new ReentrantLock(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
            waitingProducers = new FifoWaitQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
            waitingConsumers = new FifoWaitQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
            qlock = new ReentrantLock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
            waitingProducers = new LifoWaitQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
            waitingConsumers = new LifoWaitQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        s.defaultWriteObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
  1183
    /**
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
  1184
     * Reconstitutes this queue from a stream (that is, deserializes it).
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1185
     * @param s the stream
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1186
     * @throws ClassNotFoundException if the class of a serialized object
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1187
     *         could not be found
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1188
     * @throws java.io.IOException if an I/O error occurs
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
  1189
     */
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1190
    private void readObject(java.io.ObjectInputStream s)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
        throws java.io.IOException, ClassNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
        s.defaultReadObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
        if (waitingProducers instanceof FifoWaitQueue)
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1194
            transferer = new TransferQueue<E>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
        else
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9242
diff changeset
  1196
            transferer = new TransferStack<E>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1199
    // Unsafe mechanics
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1200
    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1201
                                  String field, Class<?> klazz) {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1202
        try {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1203
            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1204
        } catch (NoSuchFieldException e) {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1205
            // Convert Exception to corresponding Error
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1206
            NoSuchFieldError error = new NoSuchFieldError(field);
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1207
            error.initCause(e);
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1208
            throw error;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1209
        }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1210
    }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 5506
diff changeset
  1211
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
}