jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java
author chegar
Wed, 11 Nov 2015 09:19:12 +0000
changeset 33674 566777f73c32
parent 32991 b27c76b82713
child 39040 a6f5ef42ecda
permissions -rw-r--r--
8140606: Update library code to use internal Unsafe Reviewed-by: alanb, mchung, psandoz, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
     1
/*
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
     3
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
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: 4110
diff changeset
     6
 * published by the Free Software Foundation.  Oracle designates this
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4110
diff changeset
     8
 * by Oracle in the LICENSE file that accompanied this code.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
     9
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    14
 * accompanied this code).
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    15
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    19
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4110
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4110
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4110
diff changeset
    22
 * questions.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    23
 */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    24
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    25
/*
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    26
 * This file is available under and governed by the GNU General Public
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    27
 * License version 2 only, as published by the Free Software Foundation.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    28
 * However, the following notice accompanied the original version of this
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    29
 * file:
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    30
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    31
 * Written by Doug Lea with assistance from members of JCP JSR-166
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    32
 * Expert Group and released to the public domain, as explained at
9242
ef138d47df58 7034657: Update Creative Commons license URL in legal notices
dl
parents: 8544
diff changeset
    33
 * http://creativecommons.org/publicdomain/zero/1.0/
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    34
 */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    35
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    36
package java.util.concurrent;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    37
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    38
import java.util.AbstractQueue;
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
    39
import java.util.Arrays;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    40
import java.util.Collection;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    41
import java.util.Iterator;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    42
import java.util.NoSuchElementException;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    43
import java.util.Queue;
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    44
import java.util.Spliterator;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    45
import java.util.Spliterators;
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
    46
import java.util.concurrent.locks.LockSupport;
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
    47
import java.util.function.Consumer;
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
    48
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    49
/**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    50
 * An unbounded {@link TransferQueue} based on linked nodes.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    51
 * This queue orders elements FIFO (first-in-first-out) with respect
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    52
 * to any given producer.  The <em>head</em> of the queue is that
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    53
 * element that has been on the queue the longest time for some
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    54
 * producer.  The <em>tail</em> of the queue is that element that has
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    55
 * been on the queue the shortest time for some producer.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    56
 *
9515
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    57
 * <p>Beware that, unlike in most collections, the {@code size} method
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    58
 * is <em>NOT</em> a constant-time operation. Because of the
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    59
 * asynchronous nature of these queues, determining the current number
9515
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    60
 * of elements requires a traversal of the elements, and so may report
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    61
 * inaccurate results if this collection is modified during traversal.
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    62
 * Additionally, the bulk operations {@code addAll},
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    63
 * {@code removeAll}, {@code retainAll}, {@code containsAll},
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    64
 * {@code equals}, and {@code toArray} are <em>not</em> guaranteed
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    65
 * to be performed atomically. For example, an iterator operating
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    66
 * concurrently with an {@code addAll} operation might view only some
04056ec0f477 7038885: Improved bulk operation disclaimers for concurrent collections
dl
parents: 9242
diff changeset
    67
 * of the added elements.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    68
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    69
 * <p>This class and its iterator implement all of the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    70
 * <em>optional</em> methods of the {@link Collection} and {@link
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    71
 * Iterator} interfaces.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    72
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    73
 * <p>Memory consistency effects: As with other concurrent
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    74
 * collections, actions in a thread prior to placing an object into a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    75
 * {@code LinkedTransferQueue}
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    76
 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    77
 * actions subsequent to the access or removal of that element from
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    78
 * the {@code LinkedTransferQueue} in another thread.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    79
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    80
 * <p>This class is a member of the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    81
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    82
 * Java Collections Framework</a>.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    83
 *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    84
 * @since 1.7
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    85
 * @author Doug Lea
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
    86
 * @param <E> the type of elements held in this queue
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    87
 */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    88
public class LinkedTransferQueue<E> extends AbstractQueue<E>
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    89
    implements TransferQueue<E>, java.io.Serializable {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    90
    private static final long serialVersionUID = -3223113410248163686L;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    91
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    92
    /*
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    93
     * *** Overview of Dual Queues with Slack ***
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    94
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    95
     * Dual Queues, introduced by Scherer and Scott
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    96
     * (http://www.cs.rice.edu/~wns1/papers/2004-DISC-DDS.pdf) are
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    97
     * (linked) queues in which nodes may represent either data or
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    98
     * requests.  When a thread tries to enqueue a data node, but
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
    99
     * encounters a request node, it instead "matches" and removes it;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   100
     * and vice versa for enqueuing requests. Blocking Dual Queues
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   101
     * arrange that threads enqueuing unmatched requests block until
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   102
     * other threads provide the match. Dual Synchronous Queues (see
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   103
     * Scherer, Lea, & Scott
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   104
     * http://www.cs.rochester.edu/u/scott/papers/2009_Scherer_CACM_SSQ.pdf)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   105
     * additionally arrange that threads enqueuing unmatched data also
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   106
     * block.  Dual Transfer Queues support all of these modes, as
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   107
     * dictated by callers.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   108
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   109
     * A FIFO dual queue may be implemented using a variation of the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   110
     * Michael & Scott (M&S) lock-free queue algorithm
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   111
     * (http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf).
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   112
     * It maintains two pointer fields, "head", pointing to a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   113
     * (matched) node that in turn points to the first actual
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   114
     * (unmatched) queue node (or null if empty); and "tail" that
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   115
     * points to the last node on the queue (or again null if
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   116
     * empty). For example, here is a possible queue with four data
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   117
     * elements:
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   118
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   119
     *  head                tail
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   120
     *    |                   |
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   121
     *    v                   v
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   122
     *    M -> U -> U -> U -> U
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   123
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   124
     * The M&S queue algorithm is known to be prone to scalability and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   125
     * overhead limitations when maintaining (via CAS) these head and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   126
     * tail pointers. This has led to the development of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   127
     * contention-reducing variants such as elimination arrays (see
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   128
     * Moir et al http://portal.acm.org/citation.cfm?id=1074013) and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   129
     * optimistic back pointers (see Ladan-Mozes & Shavit
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   130
     * http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf).
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   131
     * However, the nature of dual queues enables a simpler tactic for
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   132
     * improving M&S-style implementations when dual-ness is needed.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   133
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   134
     * In a dual queue, each node must atomically maintain its match
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   135
     * status. While there are other possible variants, we implement
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   136
     * this here as: for a data-mode node, matching entails CASing an
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   137
     * "item" field from a non-null data value to null upon match, and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   138
     * vice-versa for request nodes, CASing from null to a data
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   139
     * value. (Note that the linearization properties of this style of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   140
     * queue are easy to verify -- elements are made available by
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   141
     * linking, and unavailable by matching.) Compared to plain M&S
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   142
     * queues, this property of dual queues requires one additional
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   143
     * successful atomic operation per enq/deq pair. But it also
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   144
     * enables lower cost variants of queue maintenance mechanics. (A
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   145
     * variation of this idea applies even for non-dual queues that
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   146
     * support deletion of interior elements, such as
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   147
     * j.u.c.ConcurrentLinkedQueue.)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   148
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   149
     * Once a node is matched, its match status can never again
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   150
     * change.  We may thus arrange that the linked list of them
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   151
     * contain a prefix of zero or more matched nodes, followed by a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   152
     * suffix of zero or more unmatched nodes. (Note that we allow
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   153
     * both the prefix and suffix to be zero length, which in turn
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   154
     * means that we do not use a dummy header.)  If we were not
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   155
     * concerned with either time or space efficiency, we could
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   156
     * correctly perform enqueue and dequeue operations by traversing
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   157
     * from a pointer to the initial node; CASing the item of the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   158
     * first unmatched node on match and CASing the next field of the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   159
     * trailing node on appends. (Plus some special-casing when
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   160
     * initially empty).  While this would be a terrible idea in
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   161
     * itself, it does have the benefit of not requiring ANY atomic
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   162
     * updates on head/tail fields.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   163
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   164
     * We introduce here an approach that lies between the extremes of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   165
     * never versus always updating queue (head and tail) pointers.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   166
     * This offers a tradeoff between sometimes requiring extra
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   167
     * traversal steps to locate the first and/or last unmatched
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   168
     * nodes, versus the reduced overhead and contention of fewer
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   169
     * updates to queue pointers. For example, a possible snapshot of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   170
     * a queue is:
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   171
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   172
     *  head           tail
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   173
     *    |              |
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   174
     *    v              v
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   175
     *    M -> M -> U -> U -> U -> U
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   176
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   177
     * The best value for this "slack" (the targeted maximum distance
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   178
     * between the value of "head" and the first unmatched node, and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   179
     * similarly for "tail") is an empirical matter. We have found
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   180
     * that using very small constants in the range of 1-3 work best
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   181
     * over a range of platforms. Larger values introduce increasing
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   182
     * costs of cache misses and risks of long traversal chains, while
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   183
     * smaller values increase CAS contention and overhead.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   184
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   185
     * Dual queues with slack differ from plain M&S dual queues by
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   186
     * virtue of only sometimes updating head or tail pointers when
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   187
     * matching, appending, or even traversing nodes; in order to
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   188
     * maintain a targeted slack.  The idea of "sometimes" may be
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   189
     * operationalized in several ways. The simplest is to use a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   190
     * per-operation counter incremented on each traversal step, and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   191
     * to try (via CAS) to update the associated queue pointer
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   192
     * whenever the count exceeds a threshold. Another, that requires
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   193
     * more overhead, is to use random number generators to update
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   194
     * with a given probability per traversal step.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   195
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   196
     * In any strategy along these lines, because CASes updating
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   197
     * fields may fail, the actual slack may exceed targeted
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   198
     * slack. However, they may be retried at any time to maintain
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   199
     * targets.  Even when using very small slack values, this
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   200
     * approach works well for dual queues because it allows all
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   201
     * operations up to the point of matching or appending an item
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   202
     * (hence potentially allowing progress by another thread) to be
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   203
     * read-only, thus not introducing any further contention. As
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   204
     * described below, we implement this by performing slack
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   205
     * maintenance retries only after these points.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   206
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   207
     * As an accompaniment to such techniques, traversal overhead can
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   208
     * be further reduced without increasing contention of head
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   209
     * pointer updates: Threads may sometimes shortcut the "next" link
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   210
     * path from the current "head" node to be closer to the currently
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   211
     * known first unmatched node, and similarly for tail. Again, this
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   212
     * may be triggered with using thresholds or randomization.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   213
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   214
     * These ideas must be further extended to avoid unbounded amounts
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   215
     * of costly-to-reclaim garbage caused by the sequential "next"
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   216
     * links of nodes starting at old forgotten head nodes: As first
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   217
     * described in detail by Boehm
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   218
     * (http://portal.acm.org/citation.cfm?doid=503272.503282), if a GC
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   219
     * delays noticing that any arbitrarily old node has become
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   220
     * garbage, all newer dead nodes will also be unreclaimed.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   221
     * (Similar issues arise in non-GC environments.)  To cope with
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   222
     * this in our implementation, upon CASing to advance the head
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   223
     * pointer, we set the "next" link of the previous head to point
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   224
     * only to itself; thus limiting the length of connected dead lists.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   225
     * (We also take similar care to wipe out possibly garbage
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   226
     * retaining values held in other Node fields.)  However, doing so
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   227
     * adds some further complexity to traversal: If any "next"
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   228
     * pointer links to itself, it indicates that the current thread
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   229
     * has lagged behind a head-update, and so the traversal must
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   230
     * continue from the "head".  Traversals trying to find the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   231
     * current tail starting from "tail" may also encounter
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   232
     * self-links, in which case they also continue at "head".
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   233
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   234
     * It is tempting in slack-based scheme to not even use CAS for
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   235
     * updates (similarly to Ladan-Mozes & Shavit). However, this
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   236
     * cannot be done for head updates under the above link-forgetting
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   237
     * mechanics because an update may leave head at a detached node.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   238
     * And while direct writes are possible for tail updates, they
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   239
     * increase the risk of long retraversals, and hence long garbage
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   240
     * chains, which can be much more costly than is worthwhile
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   241
     * considering that the cost difference of performing a CAS vs
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   242
     * write is smaller when they are not triggered on each operation
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   243
     * (especially considering that writes and CASes equally require
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   244
     * additional GC bookkeeping ("write barriers") that are sometimes
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   245
     * more costly than the writes themselves because of contention).
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   246
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   247
     * *** Overview of implementation ***
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   248
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   249
     * We use a threshold-based approach to updates, with a slack
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   250
     * threshold of two -- that is, we update head/tail when the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   251
     * current pointer appears to be two or more steps away from the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   252
     * first/last node. The slack value is hard-wired: a path greater
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   253
     * than one is naturally implemented by checking equality of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   254
     * traversal pointers except when the list has only one element,
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   255
     * in which case we keep slack threshold at one. Avoiding tracking
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   256
     * explicit counts across method calls slightly simplifies an
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   257
     * already-messy implementation. Using randomization would
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   258
     * probably work better if there were a low-quality dirt-cheap
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   259
     * per-thread one available, but even ThreadLocalRandom is too
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   260
     * heavy for these purposes.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   261
     *
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   262
     * With such a small slack threshold value, it is not worthwhile
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   263
     * to augment this with path short-circuiting (i.e., unsplicing
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   264
     * interior nodes) except in the case of cancellation/removal (see
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   265
     * below).
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   266
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   267
     * We allow both the head and tail fields to be null before any
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   268
     * nodes are enqueued; initializing upon first append.  This
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   269
     * simplifies some other logic, as well as providing more
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   270
     * efficient explicit control paths instead of letting JVMs insert
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   271
     * implicit NullPointerExceptions when they are null.  While not
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   272
     * currently fully implemented, we also leave open the possibility
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   273
     * of re-nulling these fields when empty (which is complicated to
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   274
     * arrange, for little benefit.)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   275
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   276
     * All enqueue/dequeue operations are handled by the single method
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   277
     * "xfer" with parameters indicating whether to act as some form
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   278
     * of offer, put, poll, take, or transfer (each possibly with
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   279
     * timeout). The relative complexity of using one monolithic
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   280
     * method outweighs the code bulk and maintenance problems of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   281
     * using separate methods for each case.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   282
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   283
     * Operation consists of up to three phases. The first is
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   284
     * implemented within method xfer, the second in tryAppend, and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   285
     * the third in method awaitMatch.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   286
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   287
     * 1. Try to match an existing node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   288
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   289
     *    Starting at head, skip already-matched nodes until finding
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   290
     *    an unmatched node of opposite mode, if one exists, in which
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   291
     *    case matching it and returning, also if necessary updating
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   292
     *    head to one past the matched node (or the node itself if the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   293
     *    list has no other unmatched nodes). If the CAS misses, then
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   294
     *    a loop retries advancing head by two steps until either
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   295
     *    success or the slack is at most two. By requiring that each
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   296
     *    attempt advances head by two (if applicable), we ensure that
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   297
     *    the slack does not grow without bound. Traversals also check
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   298
     *    if the initial head is now off-list, in which case they
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   299
     *    start at the new head.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   300
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   301
     *    If no candidates are found and the call was untimed
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   302
     *    poll/offer, (argument "how" is NOW) return.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   303
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   304
     * 2. Try to append a new node (method tryAppend)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   305
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   306
     *    Starting at current tail pointer, find the actual last node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   307
     *    and try to append a new node (or if head was null, establish
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   308
     *    the first node). Nodes can be appended only if their
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   309
     *    predecessors are either already matched or are of the same
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   310
     *    mode. If we detect otherwise, then a new node with opposite
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   311
     *    mode must have been appended during traversal, so we must
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   312
     *    restart at phase 1. The traversal and update steps are
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   313
     *    otherwise similar to phase 1: Retrying upon CAS misses and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   314
     *    checking for staleness.  In particular, if a self-link is
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   315
     *    encountered, then we can safely jump to a node on the list
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   316
     *    by continuing the traversal at current head.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   317
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   318
     *    On successful append, if the call was ASYNC, return.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   319
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   320
     * 3. Await match or cancellation (method awaitMatch)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   321
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   322
     *    Wait for another thread to match node; instead cancelling if
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   323
     *    the current thread was interrupted or the wait timed out. On
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   324
     *    multiprocessors, we use front-of-queue spinning: If a node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   325
     *    appears to be the first unmatched node in the queue, it
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   326
     *    spins a bit before blocking. In either case, before blocking
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   327
     *    it tries to unsplice any nodes between the current "head"
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   328
     *    and the first unmatched node.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   329
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   330
     *    Front-of-queue spinning vastly improves performance of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   331
     *    heavily contended queues. And so long as it is relatively
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   332
     *    brief and "quiet", spinning does not much impact performance
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   333
     *    of less-contended queues.  During spins threads check their
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   334
     *    interrupt status and generate a thread-local random number
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   335
     *    to decide to occasionally perform a Thread.yield. While
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
   336
     *    yield has underdefined specs, we assume that it might help,
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
   337
     *    and will not hurt, in limiting impact of spinning on busy
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   338
     *    systems.  We also use smaller (1/2) spins for nodes that are
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   339
     *    not known to be front but whose predecessors have not
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   340
     *    blocked -- these "chained" spins avoid artifacts of
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   341
     *    front-of-queue rules which otherwise lead to alternating
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   342
     *    nodes spinning vs blocking. Further, front threads that
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   343
     *    represent phase changes (from data to request node or vice
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   344
     *    versa) compared to their predecessors receive additional
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   345
     *    chained spins, reflecting longer paths typically required to
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   346
     *    unblock threads during phase changes.
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   347
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   348
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   349
     * ** Unlinking removed interior nodes **
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   350
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   351
     * In addition to minimizing garbage retention via self-linking
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   352
     * described above, we also unlink removed interior nodes. These
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   353
     * may arise due to timed out or interrupted waits, or calls to
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   354
     * remove(x) or Iterator.remove.  Normally, given a node that was
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   355
     * at one time known to be the predecessor of some node s that is
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   356
     * to be removed, we can unsplice s by CASing the next field of
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   357
     * its predecessor if it still points to s (otherwise s must
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   358
     * already have been removed or is now offlist). But there are two
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   359
     * situations in which we cannot guarantee to make node s
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   360
     * unreachable in this way: (1) If s is the trailing node of list
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   361
     * (i.e., with null next), then it is pinned as the target node
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   362
     * for appends, so can only be removed later after other nodes are
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   363
     * appended. (2) We cannot necessarily unlink s given a
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   364
     * predecessor node that is matched (including the case of being
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   365
     * cancelled): the predecessor may already be unspliced, in which
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   366
     * case some previous reachable node may still point to s.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   367
     * (For further explanation see Herlihy & Shavit "The Art of
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   368
     * Multiprocessor Programming" chapter 9).  Although, in both
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   369
     * cases, we can rule out the need for further action if either s
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   370
     * or its predecessor are (or can be made to be) at, or fall off
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   371
     * from, the head of list.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   372
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   373
     * Without taking these into account, it would be possible for an
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   374
     * unbounded number of supposedly removed nodes to remain
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   375
     * reachable.  Situations leading to such buildup are uncommon but
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   376
     * can occur in practice; for example when a series of short timed
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   377
     * calls to poll repeatedly time out but never otherwise fall off
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   378
     * the list because of an untimed call to take at the front of the
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   379
     * queue.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   380
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   381
     * When these cases arise, rather than always retraversing the
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   382
     * entire list to find an actual predecessor to unlink (which
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   383
     * won't help for case (1) anyway), we record a conservative
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   384
     * estimate of possible unsplice failures (in "sweepVotes").
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   385
     * We trigger a full sweep when the estimate exceeds a threshold
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   386
     * ("SWEEP_THRESHOLD") indicating the maximum number of estimated
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   387
     * removal failures to tolerate before sweeping through, unlinking
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   388
     * cancelled nodes that were not unlinked upon initial removal.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   389
     * We perform sweeps by the thread hitting threshold (rather than
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   390
     * background threads or by spreading work to other threads)
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   391
     * because in the main contexts in which removal occurs, the
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   392
     * caller is already timed-out, cancelled, or performing a
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   393
     * potentially O(n) operation (e.g. remove(x)), none of which are
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   394
     * time-critical enough to warrant the overhead that alternatives
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   395
     * would impose on other threads.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   396
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   397
     * Because the sweepVotes estimate is conservative, and because
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   398
     * nodes become unlinked "naturally" as they fall off the head of
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   399
     * the queue, and because we allow votes to accumulate even while
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   400
     * sweeps are in progress, there are typically significantly fewer
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   401
     * such nodes than estimated.  Choice of a threshold value
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   402
     * balances the likelihood of wasted effort and contention, versus
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   403
     * providing a worst-case bound on retention of interior nodes in
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   404
     * quiescent queues. The value defined below was chosen
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   405
     * empirically to balance these under various timeout scenarios.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   406
     *
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   407
     * Note that we cannot self-link unlinked interior nodes during
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   408
     * sweeps. However, the associated garbage chains terminate when
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   409
     * some successor ultimately falls off the head of the list and is
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   410
     * self-linked.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   411
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   412
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   413
    /** True if on multiprocessor */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   414
    private static final boolean MP =
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   415
        Runtime.getRuntime().availableProcessors() > 1;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   416
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   417
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   418
     * The number of times to spin (with randomly interspersed calls
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   419
     * to Thread.yield) on multiprocessor before blocking when a node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   420
     * is apparently the first waiter in the queue.  See above for
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   421
     * explanation. Must be a power of two. The value is empirically
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   422
     * derived -- it works pretty well across a variety of processors,
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   423
     * numbers of CPUs, and OSes.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   424
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   425
    private static final int FRONT_SPINS   = 1 << 7;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   426
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   427
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   428
     * The number of times to spin before blocking when a node is
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   429
     * preceded by another node that is apparently spinning.  Also
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   430
     * serves as an increment to FRONT_SPINS on phase changes, and as
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   431
     * base average frequency for yielding during spins. Must be a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   432
     * power of two.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   433
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   434
    private static final int CHAINED_SPINS = FRONT_SPINS >>> 1;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   435
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   436
    /**
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   437
     * The maximum number of estimated removal failures (sweepVotes)
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   438
     * to tolerate before sweeping through the queue unlinking
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   439
     * cancelled nodes that were not unlinked upon initial
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   440
     * removal. See above for explanation. The value must be at least
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   441
     * two to avoid useless sweeps when removing trailing nodes.
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   442
     */
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   443
    static final int SWEEP_THRESHOLD = 32;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   444
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   445
    /**
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   446
     * Queue nodes. Uses Object, not E, for items to allow forgetting
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   447
     * them after use.  Relies heavily on Unsafe mechanics to minimize
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   448
     * unnecessary ordering constraints: Writes that are intrinsically
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   449
     * ordered wrt other accesses or CASes use simple relaxed forms.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   450
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   451
    static final class Node {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   452
        final boolean isData;   // false if this is a request node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   453
        volatile Object item;   // initially non-null if isData; CASed to match
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   454
        volatile Node next;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   455
        volatile Thread waiter; // null until waiting
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   456
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   457
        // CAS methods for fields
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   458
        final boolean casNext(Node cmp, Node val) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   459
            return U.compareAndSwapObject(this, NEXT, cmp, val);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   460
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   461
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   462
        final boolean casItem(Object cmp, Object val) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   463
            // assert cmp == null || cmp.getClass() != Node.class;
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   464
            return U.compareAndSwapObject(this, ITEM, cmp, val);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   465
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   466
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   467
        /**
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   468
         * Constructs a new node.  Uses relaxed write because item can
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   469
         * only be seen after publication via casNext.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   470
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   471
        Node(Object item, boolean isData) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   472
            U.putObject(this, ITEM, item); // relaxed write
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   473
            this.isData = isData;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   474
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   475
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   476
        /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   477
         * Links node to itself to avoid garbage retention.  Called
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   478
         * only after CASing head field, so uses relaxed write.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   479
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   480
        final void forgetNext() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   481
            U.putObject(this, NEXT, this);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   482
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   483
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   484
        /**
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   485
         * Sets item to self and waiter to null, to avoid garbage
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   486
         * retention after matching or cancelling. Uses relaxed writes
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   487
         * because order is already constrained in the only calling
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   488
         * contexts: item is forgotten only after volatile/atomic
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   489
         * mechanics that extract items.  Similarly, clearing waiter
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   490
         * follows either CAS or return from park (if ever parked;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   491
         * else we don't care).
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   492
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   493
        final void forgetContents() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   494
            U.putObject(this, ITEM, this);
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   495
            U.putObject(this, WAITER, null);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   496
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   497
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   498
        /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   499
         * Returns true if this node has been matched, including the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   500
         * case of artificial matches due to cancellation.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   501
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   502
        final boolean isMatched() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   503
            Object x = item;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   504
            return (x == this) || ((x == null) == isData);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   505
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   506
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   507
        /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   508
         * Returns true if this is an unmatched request node.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   509
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   510
        final boolean isUnmatchedRequest() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   511
            return !isData && item == null;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   512
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   513
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   514
        /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   515
         * Returns true if a node with the given mode cannot be
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   516
         * appended to this node because this node is unmatched and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   517
         * has opposite data mode.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   518
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   519
        final boolean cannotPrecede(boolean haveData) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   520
            boolean d = isData;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   521
            Object x;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   522
            return d != haveData && (x = item) != this && (x != null) == d;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   523
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   524
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   525
        /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   526
         * Tries to artificially match a data node -- used by remove.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   527
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   528
        final boolean tryMatchData() {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   529
            // assert isData;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   530
            Object x = item;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   531
            if (x != null && x != this && casItem(x, null)) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   532
                LockSupport.unpark(waiter);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   533
                return true;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   534
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   535
            return false;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   536
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   537
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   538
        private static final long serialVersionUID = -3375979862319811754L;
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   539
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   540
        // Unsafe mechanics
33674
566777f73c32 8140606: Update library code to use internal Unsafe
chegar
parents: 32991
diff changeset
   541
        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   542
        private static final long ITEM;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   543
        private static final long NEXT;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   544
        private static final long WAITER;
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   545
        static {
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   546
            try {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   547
                ITEM = U.objectFieldOffset
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   548
                    (Node.class.getDeclaredField("item"));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   549
                NEXT = U.objectFieldOffset
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   550
                    (Node.class.getDeclaredField("next"));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   551
                WAITER = U.objectFieldOffset
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   552
                    (Node.class.getDeclaredField("waiter"));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   553
            } catch (ReflectiveOperationException e) {
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   554
                throw new Error(e);
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   555
            }
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
   556
        }
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   557
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   558
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   559
    /** head of the queue; null until first enqueue */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   560
    transient volatile Node head;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   561
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   562
    /** tail of the queue; null until first append */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   563
    private transient volatile Node tail;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   564
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   565
    /** The number of apparent failures to unsplice removed nodes */
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   566
    private transient volatile int sweepVotes;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   567
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   568
    // CAS methods for fields
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   569
    private boolean casTail(Node cmp, Node val) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   570
        return U.compareAndSwapObject(this, TAIL, cmp, val);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   571
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   572
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   573
    private boolean casHead(Node cmp, Node val) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   574
        return U.compareAndSwapObject(this, HEAD, cmp, val);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   575
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   576
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   577
    private boolean casSweepVotes(int cmp, int val) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   578
        return U.compareAndSwapInt(this, SWEEPVOTES, cmp, val);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   579
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   580
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   581
    /*
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   582
     * Possible values for "how" argument in xfer method.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   583
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   584
    private static final int NOW   = 0; // for untimed poll, tryTransfer
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   585
    private static final int ASYNC = 1; // for offer, put, add
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   586
    private static final int SYNC  = 2; // for transfer, take
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   587
    private static final int TIMED = 3; // for timed poll, tryTransfer
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   588
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   589
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   590
     * Implements all queuing methods. See above for explanation.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   591
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   592
     * @param e the item or null for take
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   593
     * @param haveData true if this is a put, else a take
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   594
     * @param how NOW, ASYNC, SYNC, or TIMED
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   595
     * @param nanos timeout in nanosecs, used only if mode is TIMED
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   596
     * @return an item if matched, else e
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   597
     * @throws NullPointerException if haveData mode but e is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   598
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   599
    private E xfer(E e, boolean haveData, int how, long nanos) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   600
        if (haveData && (e == null))
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   601
            throw new NullPointerException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   602
        Node s = null;                        // the node to append, if needed
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   603
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   604
        retry:
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   605
        for (;;) {                            // restart on append race
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   606
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   607
            for (Node h = head, p = h; p != null;) { // find & match first node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   608
                boolean isData = p.isData;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   609
                Object item = p.item;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   610
                if (item != p && (item != null) == isData) { // unmatched
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   611
                    if (isData == haveData)   // can't match
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   612
                        break;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   613
                    if (p.casItem(item, e)) { // match
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   614
                        for (Node q = p; q != h;) {
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   615
                            Node n = q.next;  // update by 2 unless singleton
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   616
                            if (head == h && casHead(h, n == null ? q : n)) {
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   617
                                h.forgetNext();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   618
                                break;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   619
                            }                 // advance and retry
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   620
                            if ((h = head)   == null ||
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   621
                                (q = h.next) == null || !q.isMatched())
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   622
                                break;        // unless slack < 2
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   623
                        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   624
                        LockSupport.unpark(p.waiter);
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   625
                        @SuppressWarnings("unchecked") E itemE = (E) item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   626
                        return itemE;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   627
                    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   628
                }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   629
                Node n = p.next;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   630
                p = (p != n) ? n : (h = head); // Use head if p offlist
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   631
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   632
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   633
            if (how != NOW) {                 // No matches available
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   634
                if (s == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   635
                    s = new Node(e, haveData);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   636
                Node pred = tryAppend(s, haveData);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   637
                if (pred == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   638
                    continue retry;           // lost race vs opposite mode
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   639
                if (how != ASYNC)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   640
                    return awaitMatch(s, pred, e, (how == TIMED), nanos);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   641
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   642
            return e; // not waiting
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   643
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   644
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   645
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   646
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   647
     * Tries to append node s as tail.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   648
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   649
     * @param s the node to append
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   650
     * @param haveData true if appending in data mode
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   651
     * @return null on failure due to losing race with append in
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   652
     * different mode, else s's predecessor, or s itself if no
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   653
     * predecessor
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   654
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   655
    private Node tryAppend(Node s, boolean haveData) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   656
        for (Node t = tail, p = t;;) {        // move p to last node and append
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   657
            Node n, u;                        // temps for reads of next & tail
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   658
            if (p == null && (p = head) == null) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   659
                if (casHead(null, s))
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   660
                    return s;                 // initialize
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   661
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   662
            else if (p.cannotPrecede(haveData))
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   663
                return null;                  // lost race vs opposite mode
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   664
            else if ((n = p.next) != null)    // not last; keep traversing
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   665
                p = p != t && t != (u = tail) ? (t = u) : // stale tail
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   666
                    (p != n) ? n : null;      // restart if off list
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   667
            else if (!p.casNext(null, s))
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   668
                p = p.next;                   // re-read on CAS failure
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   669
            else {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   670
                if (p != t) {                 // update if slack now >= 2
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   671
                    while ((tail != t || !casTail(t, s)) &&
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   672
                           (t = tail)   != null &&
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   673
                           (s = t.next) != null && // advance and retry
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   674
                           (s = s.next) != null && s != t);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   675
                }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   676
                return p;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   677
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   678
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   679
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   680
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   681
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   682
     * Spins/yields/blocks until node s is matched or caller gives up.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   683
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   684
     * @param s the waiting node
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   685
     * @param pred the predecessor of s, or s itself if it has no
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   686
     * predecessor, or null if unknown (the null case does not occur
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   687
     * in any current calls but may in possible future extensions)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   688
     * @param e the comparison value for checking match
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   689
     * @param timed if true, wait only until timeout elapses
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   690
     * @param nanos timeout in nanosecs, used only if timed is true
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   691
     * @return matched item, or e if unmatched on interrupt or timeout
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   692
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   693
    private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) {
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   694
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   695
        Thread w = Thread.currentThread();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   696
        int spins = -1; // initialized after first item and cancel checks
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   697
        ThreadLocalRandom randomYields = null; // bound if needed
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   698
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   699
        for (;;) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   700
            Object item = s.item;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   701
            if (item != e) {                  // matched
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   702
                // assert item != s;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   703
                s.forgetContents();           // avoid garbage
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   704
                @SuppressWarnings("unchecked") E itemE = (E) item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   705
                return itemE;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   706
            }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   707
            else if (w.isInterrupted() || (timed && nanos <= 0L)) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   708
                unsplice(pred, s);           // try to unlink and cancel
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   709
                if (s.casItem(e, s))         // return normally if lost CAS
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   710
                    return e;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   711
            }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   712
            else if (spins < 0) {            // establish spins at/near front
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   713
                if ((spins = spinsFor(pred, s.isData)) > 0)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   714
                    randomYields = ThreadLocalRandom.current();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   715
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   716
            else if (spins > 0) {             // spin
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   717
                --spins;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
   718
                if (randomYields.nextInt(CHAINED_SPINS) == 0)
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   719
                    Thread.yield();           // occasionally yield
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   720
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   721
            else if (s.waiter == null) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   722
                s.waiter = w;                 // request unpark then recheck
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   723
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   724
            else if (timed) {
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   725
                nanos = deadline - System.nanoTime();
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
   726
                if (nanos > 0L)
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   727
                    LockSupport.parkNanos(this, nanos);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   728
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   729
            else {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   730
                LockSupport.park(this);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   731
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   732
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   733
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   734
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   735
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   736
     * Returns spin/yield value for a node with given predecessor and
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   737
     * data mode. See above for explanation.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   738
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   739
    private static int spinsFor(Node pred, boolean haveData) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   740
        if (MP && pred != null) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   741
            if (pred.isData != haveData)      // phase change
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   742
                return FRONT_SPINS + CHAINED_SPINS;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   743
            if (pred.isMatched())             // probably at front
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   744
                return FRONT_SPINS;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   745
            if (pred.waiter == null)          // pred apparently spinning
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   746
                return CHAINED_SPINS;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   747
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   748
        return 0;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   749
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   750
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   751
    /* -------------- Traversal methods -------------- */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   752
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   753
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   754
     * Returns the successor of p, or the head node if p.next has been
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   755
     * linked to self, which will only be true if traversing with a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   756
     * stale pointer that is now off the list.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   757
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   758
    final Node succ(Node p) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   759
        Node next = p.next;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   760
        return (p == next) ? head : next;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   761
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   762
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   763
    /**
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   764
     * Returns the first unmatched data node, or null if none.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   765
     * Callers must recheck if the returned node's item field is null
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   766
     * or self-linked before using.
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   767
     */
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   768
    final Node firstDataNode() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   769
        restartFromHead: for (;;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   770
            for (Node p = head; p != null;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   771
                Object item = p.item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   772
                if (p.isData) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   773
                    if (item != null && item != p)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   774
                        return p;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   775
                }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   776
                else if (item == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   777
                    break;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   778
                if (p == (p = p.next))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   779
                    continue restartFromHead;
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   780
            }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   781
            return null;
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
   782
        }
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   783
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   784
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   785
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   786
     * Traverses and counts unmatched nodes of the given mode.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   787
     * Used by methods size and getWaitingConsumerCount.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   788
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   789
    private int countOfMode(boolean data) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   790
        restartFromHead: for (;;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   791
            int count = 0;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   792
            for (Node p = head; p != null;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   793
                if (!p.isMatched()) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   794
                    if (p.isData != data)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   795
                        return 0;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   796
                    if (++count == Integer.MAX_VALUE)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   797
                        break;  // @see Collection.size()
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   798
                }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   799
                if (p == (p = p.next))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   800
                    continue restartFromHead;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   801
            }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   802
            return count;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   803
        }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   804
    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   805
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   806
    public String toString() {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   807
        String[] a = null;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   808
        restartFromHead: for (;;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   809
            int charLength = 0;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   810
            int size = 0;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   811
            for (Node p = head; p != null;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   812
                Object item = p.item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   813
                if (p.isData) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   814
                    if (item != null && item != p) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   815
                        if (a == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   816
                            a = new String[4];
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   817
                        else if (size == a.length)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   818
                            a = Arrays.copyOf(a, 2 * size);
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   819
                        String s = item.toString();
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   820
                        a[size++] = s;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   821
                        charLength += s.length();
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   822
                    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   823
                } else if (item == null)
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   824
                    break;
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   825
                if (p == (p = p.next))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   826
                    continue restartFromHead;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   827
            }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   828
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   829
            if (size == 0)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   830
                return "[]";
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   831
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   832
            return Helpers.toString(a, size, charLength);
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   833
        }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   834
    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   835
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   836
    private Object[] toArrayInternal(Object[] a) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   837
        Object[] x = a;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   838
        restartFromHead: for (;;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   839
            int size = 0;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   840
            for (Node p = head; p != null;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   841
                Object item = p.item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   842
                if (p.isData) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   843
                    if (item != null && item != p) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   844
                        if (x == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   845
                            x = new Object[4];
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   846
                        else if (size == x.length)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   847
                            x = Arrays.copyOf(x, 2 * (size + 4));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   848
                        x[size++] = item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   849
                    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   850
                } else if (item == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   851
                    break;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   852
                if (p == (p = p.next))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   853
                    continue restartFromHead;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   854
            }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   855
            if (x == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   856
                return new Object[0];
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   857
            else if (a != null && size <= a.length) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   858
                if (a != x)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   859
                    System.arraycopy(x, 0, a, 0, size);
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   860
                if (size < a.length)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   861
                    a[size] = null;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   862
                return a;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   863
            }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   864
            return (size == x.length) ? x : Arrays.copyOf(x, size);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   865
        }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   866
    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   867
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   868
    /**
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   869
     * Returns an array containing all of the elements in this queue, in
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   870
     * proper sequence.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   871
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   872
     * <p>The returned array will be "safe" in that no references to it are
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   873
     * maintained by this queue.  (In other words, this method must allocate
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   874
     * a new array).  The caller is thus free to modify the returned array.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   875
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   876
     * <p>This method acts as bridge between array-based and collection-based
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   877
     * APIs.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   878
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   879
     * @return an array containing all of the elements in this queue
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   880
     */
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   881
    public Object[] toArray() {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   882
        return toArrayInternal(null);
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   883
    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   884
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   885
    /**
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   886
     * Returns an array containing all of the elements in this queue, in
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   887
     * proper sequence; the runtime type of the returned array is that of
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   888
     * the specified array.  If the queue fits in the specified array, it
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   889
     * is returned therein.  Otherwise, a new array is allocated with the
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   890
     * runtime type of the specified array and the size of this queue.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   891
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   892
     * <p>If this queue fits in the specified array with room to spare
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   893
     * (i.e., the array has more elements than this queue), the element in
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   894
     * the array immediately following the end of the queue is set to
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   895
     * {@code null}.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   896
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   897
     * <p>Like the {@link #toArray()} method, this method acts as bridge between
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   898
     * array-based and collection-based APIs.  Further, this method allows
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   899
     * precise control over the runtime type of the output array, and may,
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   900
     * under certain circumstances, be used to save allocation costs.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   901
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   902
     * <p>Suppose {@code x} is a queue known to contain only strings.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   903
     * The following code can be used to dump the queue into a newly
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   904
     * allocated array of {@code String}:
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   905
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   906
     * <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   907
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   908
     * Note that {@code toArray(new Object[0])} is identical in function to
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   909
     * {@code toArray()}.
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   910
     *
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   911
     * @param a the array into which the elements of the queue are to
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   912
     *          be stored, if it is big enough; otherwise, a new array of the
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   913
     *          same runtime type is allocated for this purpose
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   914
     * @return an array containing all of the elements in this queue
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   915
     * @throws ArrayStoreException if the runtime type of the specified array
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   916
     *         is not a supertype of the runtime type of every element in
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   917
     *         this queue
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   918
     * @throws NullPointerException if the specified array is null
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   919
     */
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   920
    @SuppressWarnings("unchecked")
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   921
    public <T> T[] toArray(T[] a) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   922
        if (a == null) throw new NullPointerException();
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   923
        return (T[]) toArrayInternal(a);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   924
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   925
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   926
    final class Itr implements Iterator<E> {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   927
        private Node nextNode;   // next node to return item for
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   928
        private E nextItem;      // the corresponding item
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   929
        private Node lastRet;    // last returned node, to support remove
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   930
        private Node lastPred;   // predecessor to unlink lastRet
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   931
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   932
        /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   933
         * Moves to next node after prev, or first node if prev null.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   934
         */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   935
        private void advance(Node prev) {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   936
            /*
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   937
             * To track and avoid buildup of deleted nodes in the face
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   938
             * of calls to both Queue.remove and Itr.remove, we must
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   939
             * include variants of unsplice and sweep upon each
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   940
             * advance: Upon Itr.remove, we may need to catch up links
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   941
             * from lastPred, and upon other removes, we might need to
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   942
             * skip ahead from stale nodes and unsplice deleted ones
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   943
             * found while advancing.
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   944
             */
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   945
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   946
            Node r, b; // reset lastPred upon possible deletion of lastRet
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   947
            if ((r = lastRet) != null && !r.isMatched())
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   948
                lastPred = r;    // next lastPred is old lastRet
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   949
            else if ((b = lastPred) == null || b.isMatched())
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   950
                lastPred = null; // at start of list
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   951
            else {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   952
                Node s, n;       // help with removal of lastPred.next
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   953
                while ((s = b.next) != null &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   954
                       s != b && s.isMatched() &&
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   955
                       (n = s.next) != null && n != s)
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   956
                    b.casNext(s, n);
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   957
            }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   958
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   959
            this.lastRet = prev;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   960
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   961
            for (Node p = prev, s, n;;) {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   962
                s = (p == null) ? head : p.next;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   963
                if (s == null)
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   964
                    break;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   965
                else if (s == p) {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   966
                    p = null;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   967
                    continue;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   968
                }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   969
                Object item = s.item;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   970
                if (s.isData) {
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   971
                    if (item != null && item != s) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   972
                        @SuppressWarnings("unchecked") E itemE = (E) item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
   973
                        nextItem = itemE;
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   974
                        nextNode = s;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   975
                        return;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   976
                    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   977
                }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   978
                else if (item == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   979
                    break;
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   980
                // assert s.isMatched();
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   981
                if (p == null)
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   982
                    p = s;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   983
                else if ((n = s.next) == null)
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   984
                    break;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   985
                else if (s == n)
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   986
                    p = null;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   987
                else
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   988
                    p.casNext(s, n);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   989
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   990
            nextNode = null;
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
   991
            nextItem = null;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   992
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   993
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   994
        Itr() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   995
            advance(null);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   996
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   997
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   998
        public final boolean hasNext() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
   999
            return nextNode != null;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1000
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1001
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1002
        public final E next() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1003
            Node p = nextNode;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1004
            if (p == null) throw new NoSuchElementException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1005
            E e = nextItem;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1006
            advance(p);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1007
            return e;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1008
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1009
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1010
        public final void remove() {
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1011
            final Node lastRet = this.lastRet;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1012
            if (lastRet == null)
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1013
                throw new IllegalStateException();
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1014
            this.lastRet = null;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1015
            if (lastRet.tryMatchData())
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1016
                unsplice(lastPred, lastRet);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1017
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1018
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1019
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1020
    /** A customized variant of Spliterators.IteratorSpliterator */
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1021
    final class LTQSpliterator<E> implements Spliterator<E> {
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1022
        static final int MAX_BATCH = 1 << 25;  // max batch array size;
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1023
        Node current;       // current node; null until initialized
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1024
        int batch;          // batch size for splits
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1025
        boolean exhausted;  // true when no more nodes
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1026
        LTQSpliterator() {}
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1027
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1028
        public Spliterator<E> trySplit() {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1029
            Node p;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1030
            int b = batch;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1031
            int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1032
            if (!exhausted &&
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1033
                ((p = current) != null || (p = firstDataNode()) != null) &&
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1034
                p.next != null) {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1035
                Object[] a = new Object[n];
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1036
                int i = 0;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1037
                do {
31151
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1038
                    Object e = p.item;
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1039
                    if (e != p && (a[i] = e) != null)
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1040
                        ++i;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1041
                    if (p == (p = p.next))
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1042
                        p = firstDataNode();
31151
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1043
                } while (p != null && i < n && p.isData);
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1044
                if ((current = p) == null)
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1045
                    exhausted = true;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1046
                if (i > 0) {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1047
                    batch = i;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1048
                    return Spliterators.spliterator
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1049
                        (a, 0, i, (Spliterator.ORDERED |
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1050
                                   Spliterator.NONNULL |
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1051
                                   Spliterator.CONCURRENT));
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1052
                }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1053
            }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1054
            return null;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1055
        }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1056
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1057
        @SuppressWarnings("unchecked")
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1058
        public void forEachRemaining(Consumer<? super E> action) {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1059
            Node p;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1060
            if (action == null) throw new NullPointerException();
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1061
            if (!exhausted &&
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1062
                ((p = current) != null || (p = firstDataNode()) != null)) {
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1063
                exhausted = true;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1064
                do {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1065
                    Object e = p.item;
31151
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1066
                    if (e != null && e != p)
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1067
                        action.accept((E)e);
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1068
                    if (p == (p = p.next))
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1069
                        p = firstDataNode();
31151
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1070
                } while (p != null && p.isData);
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1071
            }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1072
        }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1073
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1074
        @SuppressWarnings("unchecked")
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1075
        public boolean tryAdvance(Consumer<? super E> action) {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1076
            Node p;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1077
            if (action == null) throw new NullPointerException();
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1078
            if (!exhausted &&
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1079
                ((p = current) != null || (p = firstDataNode()) != null)) {
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1080
                Object e;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1081
                do {
31151
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1082
                    if ((e = p.item) == p)
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1083
                        e = null;
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1084
                    if (p == (p = p.next))
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1085
                        p = firstDataNode();
31151
5535c077def0 8085978: LinkedTransferQueue<T>.spliterator can report LTQ.Node object, not T
dl
parents: 25859
diff changeset
  1086
                } while (e == null && p != null && p.isData);
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1087
                if ((current = p) == null)
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1088
                    exhausted = true;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1089
                if (e != null) {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1090
                    action.accept((E)e);
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1091
                    return true;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1092
                }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1093
            }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1094
            return false;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1095
        }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1096
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1097
        public long estimateSize() { return Long.MAX_VALUE; }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1098
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1099
        public int characteristics() {
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1100
            return Spliterator.ORDERED | Spliterator.NONNULL |
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1101
                Spliterator.CONCURRENT;
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1102
        }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1103
    }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1104
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1105
    /**
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1106
     * Returns a {@link Spliterator} over the elements in this queue.
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1107
     *
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1108
     * <p>The returned spliterator is
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1109
     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1110
     *
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1111
     * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT},
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1112
     * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}.
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1113
     *
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1114
     * @implNote
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1115
     * The {@code Spliterator} implements {@code trySplit} to permit limited
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1116
     * parallelism.
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1117
     *
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1118
     * @return a {@code Spliterator} over the elements in this queue
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1119
     * @since 1.8
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1120
     */
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1121
    public Spliterator<E> spliterator() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1122
        return new LTQSpliterator<E>();
18767
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1123
    }
6214297bf27d 8011427: java.util.concurrent collection Spliterator implementations
psandoz
parents: 14325
diff changeset
  1124
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1125
    /* -------------- Removal methods -------------- */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1126
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1127
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1128
     * Unsplices (now or later) the given deleted/cancelled node with
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1129
     * the given predecessor.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1130
     *
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1131
     * @param pred a node that was at one time known to be the
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1132
     * predecessor of s, or null or s itself if s is/was at head
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1133
     * @param s the node to be unspliced
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1134
     */
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1135
    final void unsplice(Node pred, Node s) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1136
        s.waiter = null; // disable signals
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1137
        /*
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1138
         * See above for rationale. Briefly: if pred still points to
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1139
         * s, try to unlink s.  If s cannot be unlinked, because it is
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1140
         * trailing node or pred might be unlinked, and neither pred
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1141
         * nor s are head or offlist, add to sweepVotes, and if enough
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1142
         * votes have accumulated, sweep.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1143
         */
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1144
        if (pred != null && pred != s && pred.next == s) {
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1145
            Node n = s.next;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1146
            if (n == null ||
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1147
                (n != s && pred.casNext(s, n) && pred.isMatched())) {
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1148
                for (;;) {               // check if at, or could be, head
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1149
                    Node h = head;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1150
                    if (h == pred || h == s || h == null)
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1151
                        return;          // at head or list empty
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1152
                    if (!h.isMatched())
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1153
                        break;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1154
                    Node hn = h.next;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1155
                    if (hn == null)
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1156
                        return;          // now empty
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1157
                    if (hn != h && casHead(h, hn))
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1158
                        h.forgetNext();  // advance head
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1159
                }
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1160
                if (pred.next != pred && s.next != s) { // recheck if offlist
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1161
                    for (;;) {           // sweep now if enough votes
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1162
                        int v = sweepVotes;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1163
                        if (v < SWEEP_THRESHOLD) {
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1164
                            if (casSweepVotes(v, v + 1))
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1165
                                break;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1166
                        }
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1167
                        else if (casSweepVotes(v, 0)) {
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1168
                            sweep();
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1169
                            break;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1170
                        }
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1171
                    }
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1172
                }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1173
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1174
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1175
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1176
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1177
    /**
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1178
     * Unlinks matched (typically cancelled) nodes encountered in a
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1179
     * traversal from head.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1180
     */
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1181
    private void sweep() {
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1182
        for (Node p = head, s, n; p != null && (s = p.next) != null; ) {
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1183
            if (!s.isMatched())
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1184
                // Unmatched nodes are never self-linked
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1185
                p = s;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1186
            else if ((n = s.next) == null) // trailing node is pinned
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1187
                break;
6543
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1188
            else if (s == n)    // stale
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1189
                // No need to also check for p == s, since that implies s == n
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1190
                p = head;
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1191
            else
c06e5f2c6bb1 6978087: jsr166y Updates
dl
parents: 5506
diff changeset
  1192
                p.casNext(s, n);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1193
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1194
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1195
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1196
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1197
     * Main implementation of remove(Object)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1198
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1199
    private boolean findAndRemove(Object e) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1200
        if (e != null) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1201
            for (Node pred = null, p = head; p != null; ) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1202
                Object item = p.item;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1203
                if (p.isData) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1204
                    if (item != null && item != p && e.equals(item) &&
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1205
                        p.tryMatchData()) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1206
                        unsplice(pred, p);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1207
                        return true;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1208
                    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1209
                }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1210
                else if (item == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1211
                    break;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1212
                pred = p;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1213
                if ((p = p.next) == pred) { // stale
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1214
                    pred = null;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1215
                    p = head;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1216
                }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1217
            }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1218
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1219
        return false;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1220
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1221
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1222
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1223
     * Creates an initially empty {@code LinkedTransferQueue}.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1224
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1225
    public LinkedTransferQueue() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1226
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1227
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1228
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1229
     * Creates a {@code LinkedTransferQueue}
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1230
     * initially containing the elements of the given collection,
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1231
     * added in traversal order of the collection's iterator.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1232
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1233
     * @param c the collection of elements to initially contain
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1234
     * @throws NullPointerException if the specified collection or any
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1235
     *         of its elements are null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1236
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1237
    public LinkedTransferQueue(Collection<? extends E> c) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1238
        this();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1239
        addAll(c);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1240
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1241
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1242
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1243
     * Inserts the specified element at the tail of this queue.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1244
     * As the queue is unbounded, this method will never block.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1245
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1246
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1247
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1248
    public void put(E e) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1249
        xfer(e, true, ASYNC, 0);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1250
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1251
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1252
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1253
     * Inserts the specified element at the tail of this queue.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1254
     * As the queue is unbounded, this method will never block or
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1255
     * return {@code false}.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1256
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1257
     * @return {@code true} (as specified by
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1258
     *  {@link java.util.concurrent.BlockingQueue#offer(Object,long,TimeUnit)
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1259
     *  BlockingQueue.offer})
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1260
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1261
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1262
    public boolean offer(E e, long timeout, TimeUnit unit) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1263
        xfer(e, true, ASYNC, 0);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1264
        return true;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1265
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1266
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1267
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1268
     * Inserts the specified element at the tail of this queue.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1269
     * As the queue is unbounded, this method will never return {@code false}.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1270
     *
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1271
     * @return {@code true} (as specified by {@link Queue#offer})
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1272
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1273
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1274
    public boolean offer(E e) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1275
        xfer(e, true, ASYNC, 0);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1276
        return true;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1277
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1278
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1279
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1280
     * Inserts the specified element at the tail of this queue.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1281
     * As the queue is unbounded, this method will never throw
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1282
     * {@link IllegalStateException} or return {@code false}.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1283
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1284
     * @return {@code true} (as specified by {@link Collection#add})
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1285
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1286
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1287
    public boolean add(E e) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1288
        xfer(e, true, ASYNC, 0);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1289
        return true;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1290
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1291
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1292
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1293
     * Transfers the element to a waiting consumer immediately, if possible.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1294
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1295
     * <p>More precisely, transfers the specified element immediately
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1296
     * if there exists a consumer already waiting to receive it (in
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1297
     * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1298
     * otherwise returning {@code false} without enqueuing the element.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1299
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1300
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1301
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1302
    public boolean tryTransfer(E e) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1303
        return xfer(e, true, NOW, 0) == null;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1304
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1305
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1306
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1307
     * Transfers the element to a consumer, waiting if necessary to do so.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1308
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1309
     * <p>More precisely, transfers the specified element immediately
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1310
     * if there exists a consumer already waiting to receive it (in
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1311
     * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1312
     * else inserts the specified element at the tail of this queue
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1313
     * and waits until the element is received by a consumer.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1314
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1315
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1316
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1317
    public void transfer(E e) throws InterruptedException {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1318
        if (xfer(e, true, SYNC, 0) != null) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1319
            Thread.interrupted(); // failure possible only due to interrupt
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1320
            throw new InterruptedException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1321
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1322
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1323
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1324
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1325
     * Transfers the element to a consumer if it is possible to do so
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1326
     * before the timeout elapses.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1327
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1328
     * <p>More precisely, transfers the specified element immediately
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1329
     * if there exists a consumer already waiting to receive it (in
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1330
     * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1331
     * else inserts the specified element at the tail of this queue
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1332
     * and waits until the element is received by a consumer,
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1333
     * returning {@code false} if the specified wait time elapses
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1334
     * before the element can be transferred.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1335
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1336
     * @throws NullPointerException if the specified element is null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1337
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1338
    public boolean tryTransfer(E e, long timeout, TimeUnit unit)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1339
        throws InterruptedException {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1340
        if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1341
            return true;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1342
        if (!Thread.interrupted())
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1343
            return false;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1344
        throw new InterruptedException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1345
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1346
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1347
    public E take() throws InterruptedException {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1348
        E e = xfer(null, false, SYNC, 0);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1349
        if (e != null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1350
            return e;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1351
        Thread.interrupted();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1352
        throw new InterruptedException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1353
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1354
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1355
    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1356
        E e = xfer(null, false, TIMED, unit.toNanos(timeout));
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1357
        if (e != null || !Thread.interrupted())
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1358
            return e;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1359
        throw new InterruptedException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1360
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1361
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1362
    public E poll() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1363
        return xfer(null, false, NOW, 0);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1364
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1365
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1366
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1367
     * @throws NullPointerException     {@inheritDoc}
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1368
     * @throws IllegalArgumentException {@inheritDoc}
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1369
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1370
    public int drainTo(Collection<? super E> c) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1371
        if (c == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1372
            throw new NullPointerException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1373
        if (c == this)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1374
            throw new IllegalArgumentException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1375
        int n = 0;
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1376
        for (E e; (e = poll()) != null;) {
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1377
            c.add(e);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1378
            ++n;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1379
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1380
        return n;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1381
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1382
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1383
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1384
     * @throws NullPointerException     {@inheritDoc}
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1385
     * @throws IllegalArgumentException {@inheritDoc}
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1386
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1387
    public int drainTo(Collection<? super E> c, int maxElements) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1388
        if (c == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1389
            throw new NullPointerException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1390
        if (c == this)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1391
            throw new IllegalArgumentException();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1392
        int n = 0;
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1393
        for (E e; n < maxElements && (e = poll()) != null;) {
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1394
            c.add(e);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1395
            ++n;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1396
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1397
        return n;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1398
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1399
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1400
    /**
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1401
     * Returns an iterator over the elements in this queue in proper sequence.
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1402
     * The elements will be returned in order from first (head) to last (tail).
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1403
     *
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1404
     * <p>The returned iterator is
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1405
     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1406
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1407
     * @return an iterator over the elements in this queue in proper sequence
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1408
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1409
    public Iterator<E> iterator() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1410
        return new Itr();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1411
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1412
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1413
    public E peek() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1414
        restartFromHead: for (;;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1415
            for (Node p = head; p != null;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1416
                Object item = p.item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1417
                if (p.isData) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1418
                    if (item != null && item != p) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1419
                        @SuppressWarnings("unchecked") E e = (E) item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1420
                        return e;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1421
                    }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1422
                }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1423
                else if (item == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1424
                    break;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1425
                if (p == (p = p.next))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1426
                    continue restartFromHead;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1427
            }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1428
            return null;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1429
        }
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1430
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1431
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1432
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1433
     * Returns {@code true} if this queue contains no elements.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1434
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1435
     * @return {@code true} if this queue contains no elements
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1436
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1437
    public boolean isEmpty() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1438
        return firstDataNode() == null;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1439
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1440
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1441
    public boolean hasWaitingConsumer() {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1442
        restartFromHead: for (;;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1443
            for (Node p = head; p != null;) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1444
                Object item = p.item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1445
                if (p.isData) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1446
                    if (item != null && item != p)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1447
                        break;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1448
                }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1449
                else if (item == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1450
                    return true;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1451
                if (p == (p = p.next))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1452
                    continue restartFromHead;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1453
            }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1454
            return false;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1455
        }
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1456
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1457
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1458
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1459
     * Returns the number of elements in this queue.  If this queue
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1460
     * contains more than {@code Integer.MAX_VALUE} elements, returns
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1461
     * {@code Integer.MAX_VALUE}.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1462
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1463
     * <p>Beware that, unlike in most collections, this method is
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1464
     * <em>NOT</em> a constant-time operation. Because of the
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1465
     * asynchronous nature of these queues, determining the current
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1466
     * number of elements requires an O(n) traversal.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1467
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1468
     * @return the number of elements in this queue
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1469
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1470
    public int size() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1471
        return countOfMode(true);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1472
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1473
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1474
    public int getWaitingConsumerCount() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1475
        return countOfMode(false);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1476
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1477
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1478
    /**
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1479
     * Removes a single instance of the specified element from this queue,
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1480
     * if it is present.  More formally, removes an element {@code e} such
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1481
     * that {@code o.equals(e)}, if this queue contains one or more such
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1482
     * elements.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1483
     * Returns {@code true} if this queue contained the specified element
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1484
     * (or equivalently, if this queue changed as a result of the call).
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1485
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1486
     * @param o element to be removed from this queue, if present
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1487
     * @return {@code true} if this queue changed as a result of the call
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1488
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1489
    public boolean remove(Object o) {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1490
        return findAndRemove(o);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1491
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1492
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1493
    /**
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1494
     * Returns {@code true} if this queue contains the specified element.
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1495
     * More formally, returns {@code true} if and only if this queue contains
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1496
     * at least one element {@code e} such that {@code o.equals(e)}.
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1497
     *
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1498
     * @param o object to be checked for containment in this queue
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1499
     * @return {@code true} if this queue contains the specified element
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1500
     */
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1501
    public boolean contains(Object o) {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1502
        if (o != null) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1503
            for (Node p = head; p != null; p = succ(p)) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1504
                Object item = p.item;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1505
                if (p.isData) {
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1506
                    if (item != null && item != p && o.equals(item))
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1507
                        return true;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1508
                }
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1509
                else if (item == null)
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1510
                    break;
7976
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1511
            }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1512
        }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1513
        return false;
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1514
    }
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1515
f273c0d04215 7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011
dl
parents: 6543
diff changeset
  1516
    /**
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1517
     * Always returns {@code Integer.MAX_VALUE} because a
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1518
     * {@code LinkedTransferQueue} is not capacity constrained.
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1519
     *
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1520
     * @return {@code Integer.MAX_VALUE} (as specified by
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1521
     *         {@link java.util.concurrent.BlockingQueue#remainingCapacity()
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1522
     *         BlockingQueue.remainingCapacity})
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1523
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1524
    public int remainingCapacity() {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1525
        return Integer.MAX_VALUE;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1526
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1527
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1528
    /**
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
  1529
     * Saves this queue to a stream (that is, serializes it).
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1530
     *
19428
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1531
     * @param s the stream
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1532
     * @throws java.io.IOException if an I/O error occurs
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1533
     * @serialData All of the elements (each an {@code E}) in
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1534
     * the proper order, followed by a null
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1535
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1536
    private void writeObject(java.io.ObjectOutputStream s)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1537
        throws java.io.IOException {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1538
        s.defaultWriteObject();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1539
        for (E e : this)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1540
            s.writeObject(e);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1541
        // Use trailing null as sentinel
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1542
        s.writeObject(null);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1543
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1544
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1545
    /**
14325
622c473a21aa 8001575: Minor/sync/cleanup j.u.c with Dougs CVS - Oct 2012
dl
parents: 11279
diff changeset
  1546
     * 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
  1547
     * @param s the stream
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1548
     * @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
  1549
     *         could not be found
83f87aff7b07 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls
psandoz
parents: 18767
diff changeset
  1550
     * @throws java.io.IOException if an I/O error occurs
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1551
     */
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1552
    private void readObject(java.io.ObjectInputStream s)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1553
        throws java.io.IOException, ClassNotFoundException {
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1554
        s.defaultReadObject();
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1555
        for (;;) {
11279
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1556
            @SuppressWarnings("unchecked")
d9dab5ec5044 7118066: Warnings in java.util.concurrent package
dl
parents: 9515
diff changeset
  1557
            E item = (E) s.readObject();
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1558
            if (item == null)
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1559
                break;
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1560
            else
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1561
                offer(item);
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1562
        }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1563
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1564
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1565
    // Unsafe mechanics
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1566
33674
566777f73c32 8140606: Update library code to use internal Unsafe
chegar
parents: 32991
diff changeset
  1567
    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1568
    private static final long HEAD;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1569
    private static final long TAIL;
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1570
    private static final long SWEEPVOTES;
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
  1571
    static {
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1572
        try {
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1573
            HEAD = U.objectFieldOffset
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1574
                (LinkedTransferQueue.class.getDeclaredField("head"));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1575
            TAIL = U.objectFieldOffset
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1576
                (LinkedTransferQueue.class.getDeclaredField("tail"));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1577
            SWEEPVOTES = U.objectFieldOffset
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1578
                (LinkedTransferQueue.class.getDeclaredField("sweepVotes"));
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1579
        } catch (ReflectiveOperationException e) {
8544
225896f7b33c 7017493: ConcurrentLinkedDeque: Unexpected initialization order can lead to crash due to use of Unsafe
dl
parents: 7976
diff changeset
  1580
            throw new Error(e);
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1581
        }
32991
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1582
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1583
        // Reduce the risk of rare disastrous classloading in first call to
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1584
        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
b27c76b82713 8134853: Bulk integration of java.util.concurrent classes
dl
parents: 31151
diff changeset
  1585
        Class<?> ensureLoaded = LockSupport.class;
4110
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1586
    }
ac033ba6ede4 6865582: jsr166y - jsr166 maintenance update
dl
parents:
diff changeset
  1587
}