1.1 --- a/make/java/java/FILES_java.gmk Wed Nov 04 11:19:42 2009 -0800
1.2 +++ b/make/java/java/FILES_java.gmk Sun Nov 08 14:49:18 2009 -0800
1.3 @@ -286,11 +286,18 @@
1.4 java/util/concurrent/ExecutorService.java \
1.5 java/util/concurrent/ExecutorCompletionService.java \
1.6 java/util/concurrent/Executors.java \
1.7 + java/util/concurrent/ForkJoinPool.java \
1.8 + java/util/concurrent/ForkJoinTask.java \
1.9 + java/util/concurrent/ForkJoinWorkerThread.java \
1.10 java/util/concurrent/Future.java \
1.11 java/util/concurrent/FutureTask.java \
1.12 java/util/concurrent/LinkedBlockingDeque.java \
1.13 java/util/concurrent/LinkedBlockingQueue.java \
1.14 + java/util/concurrent/LinkedTransferQueue.java \
1.15 + java/util/concurrent/Phaser.java \
1.16 java/util/concurrent/PriorityBlockingQueue.java \
1.17 + java/util/concurrent/RecursiveAction.java \
1.18 + java/util/concurrent/RecursiveTask.java \
1.19 java/util/concurrent/RejectedExecutionException.java \
1.20 java/util/concurrent/RejectedExecutionHandler.java \
1.21 java/util/concurrent/RunnableFuture.java \
1.22 @@ -301,9 +308,11 @@
1.23 java/util/concurrent/Semaphore.java \
1.24 java/util/concurrent/SynchronousQueue.java \
1.25 java/util/concurrent/ThreadFactory.java \
1.26 + java/util/concurrent/ThreadLocalRandom.java \
1.27 java/util/concurrent/ThreadPoolExecutor.java \
1.28 java/util/concurrent/TimeUnit.java \
1.29 java/util/concurrent/TimeoutException.java \
1.30 + java/util/concurrent/TransferQueue.java \
1.31 java/util/concurrent/atomic/AtomicBoolean.java \
1.32 java/util/concurrent/atomic/AtomicInteger.java \
1.33 java/util/concurrent/atomic/AtomicIntegerArray.java \
2.1 --- a/src/share/classes/java/util/AbstractList.java Wed Nov 04 11:19:42 2009 -0800
2.2 +++ b/src/share/classes/java/util/AbstractList.java Sun Nov 08 14:49:18 2009 -0800
2.3 @@ -256,9 +256,8 @@
2.4 public boolean addAll(int index, Collection<? extends E> c) {
2.5 rangeCheckForAdd(index);
2.6 boolean modified = false;
2.7 - Iterator<? extends E> e = c.iterator();
2.8 - while (e.hasNext()) {
2.9 - add(index++, e.next());
2.10 + for (E e : c) {
2.11 + add(index++, e);
2.12 modified = true;
2.13 }
2.14 return modified;
3.1 --- a/src/share/classes/java/util/AbstractQueue.java Wed Nov 04 11:19:42 2009 -0800
3.2 +++ b/src/share/classes/java/util/AbstractQueue.java Sun Nov 08 14:49:18 2009 -0800
3.3 @@ -183,11 +183,9 @@
3.4 if (c == this)
3.5 throw new IllegalArgumentException();
3.6 boolean modified = false;
3.7 - Iterator<? extends E> e = c.iterator();
3.8 - while (e.hasNext()) {
3.9 - if (add(e.next()))
3.10 + for (E e : c)
3.11 + if (add(e))
3.12 modified = true;
3.13 - }
3.14 return modified;
3.15 }
3.16
4.1 --- a/src/share/classes/java/util/HashMap.java Wed Nov 04 11:19:42 2009 -0800
4.2 +++ b/src/share/classes/java/util/HashMap.java Sun Nov 08 14:49:18 2009 -0800
4.3 @@ -448,10 +448,8 @@
4.4 }
4.5
4.6 private void putAllForCreate(Map<? extends K, ? extends V> m) {
4.7 - for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
4.8 - Map.Entry<? extends K, ? extends V> e = i.next();
4.9 + for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
4.10 putForCreate(e.getKey(), e.getValue());
4.11 - }
4.12 }
4.13
4.14 /**
4.15 @@ -536,10 +534,8 @@
4.16 resize(newCapacity);
4.17 }
4.18
4.19 - for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
4.20 - Map.Entry<? extends K, ? extends V> e = i.next();
4.21 + for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
4.22 put(e.getKey(), e.getValue());
4.23 - }
4.24 }
4.25
4.26 /**
5.1 --- a/src/share/classes/java/util/HashSet.java Wed Nov 04 11:19:42 2009 -0800
5.2 +++ b/src/share/classes/java/util/HashSet.java Sun Nov 08 14:49:18 2009 -0800
5.3 @@ -280,8 +280,8 @@
5.4 s.writeInt(map.size());
5.5
5.6 // Write out all elements in the proper order.
5.7 - for (Iterator i=map.keySet().iterator(); i.hasNext(); )
5.8 - s.writeObject(i.next());
5.9 + for (E e : map.keySet())
5.10 + s.writeObject(e);
5.11 }
5.12
5.13 /**
6.1 --- a/src/share/classes/java/util/Random.java Wed Nov 04 11:19:42 2009 -0800
6.2 +++ b/src/share/classes/java/util/Random.java Sun Nov 08 14:49:18 2009 -0800
6.3 @@ -50,6 +50,18 @@
6.4 * <p>
6.5 * Many applications will find the method {@link Math#random} simpler to use.
6.6 *
6.7 + * <p>Instances of {@code java.util.Random} are threadsafe.
6.8 + * However, the concurrent use of the same {@code java.util.Random}
6.9 + * instance across threads may encounter contention and consequent
6.10 + * poor performance. Consider instead using
6.11 + * {@link java.util.concurrent.ThreadLocalRandom} in multithreaded
6.12 + * designs.
6.13 + *
6.14 + * <p>Instances of {@code java.util.Random} are not cryptographically
6.15 + * secure. Consider instead using {@link java.security.SecureRandom} to
6.16 + * get a cryptographically secure pseudo-random number generator for use
6.17 + * by security-sensitive applications.
6.18 + *
6.19 * @author Frank Yellin
6.20 * @since 1.0
6.21 */
7.1 --- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Wed Nov 04 11:19:42 2009 -0800
7.2 +++ b/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Sun Nov 08 14:49:18 2009 -0800
7.3 @@ -218,8 +218,8 @@
7.4 if (capacity < c.size())
7.5 throw new IllegalArgumentException();
7.6
7.7 - for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
7.8 - add(it.next());
7.9 + for (E e : c)
7.10 + add(e);
7.11 }
7.12
7.13 /**
8.1 --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Wed Nov 04 11:19:42 2009 -0800
8.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Sun Nov 08 14:49:18 2009 -0800
8.3 @@ -250,8 +250,8 @@
8.4 * of its elements are null
8.5 */
8.6 public ConcurrentLinkedQueue(Collection<? extends E> c) {
8.7 - for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
8.8 - add(it.next());
8.9 + for (E e : c)
8.10 + add(e);
8.11 }
8.12
8.13 // Have to override just to update the javadoc
9.1 --- a/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Wed Nov 04 11:19:42 2009 -0800
9.2 +++ b/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Sun Nov 08 14:49:18 2009 -0800
9.3 @@ -895,7 +895,7 @@
9.4 if (n != null) {
9.5 Node<K,V> f = n.next;
9.6 if (n != b.next) // inconsistent read
9.7 - break;;
9.8 + break;
9.9 Object v = n.value;
9.10 if (v == null) { // n is deleted
9.11 n.helpDelete(b, f);
10.1 --- a/src/share/classes/java/util/concurrent/CountDownLatch.java Wed Nov 04 11:19:42 2009 -0800
10.2 +++ b/src/share/classes/java/util/concurrent/CountDownLatch.java Sun Nov 08 14:49:18 2009 -0800
10.3 @@ -148,7 +148,8 @@
10.4 *
10.5 * </pre>
10.6 *
10.7 - * <p>Memory consistency effects: Actions in a thread prior to calling
10.8 + * <p>Memory consistency effects: Until the count reaches
10.9 + * zero, actions in a thread prior to calling
10.10 * {@code countDown()}
10.11 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
10.12 * actions following a successful return from a corresponding
11.1 --- a/src/share/classes/java/util/concurrent/ExecutorService.java Wed Nov 04 11:19:42 2009 -0800
11.2 +++ b/src/share/classes/java/util/concurrent/ExecutorService.java Sun Nov 08 14:49:18 2009 -0800
11.3 @@ -332,8 +332,8 @@
11.4 * @param tasks the collection of tasks
11.5 * @return the result returned by one of the tasks
11.6 * @throws InterruptedException if interrupted while waiting
11.7 - * @throws NullPointerException if tasks or any of its elements
11.8 - * are <tt>null</tt>
11.9 + * @throws NullPointerException if tasks or any element task
11.10 + * subject to execution is <tt>null</tt>
11.11 * @throws IllegalArgumentException if tasks is empty
11.12 * @throws ExecutionException if no task successfully completes
11.13 * @throws RejectedExecutionException if tasks cannot be scheduled
11.14 @@ -356,8 +356,8 @@
11.15 * @param unit the time unit of the timeout argument
11.16 * @return the result returned by one of the tasks.
11.17 * @throws InterruptedException if interrupted while waiting
11.18 - * @throws NullPointerException if tasks, any of its elements, or
11.19 - * unit are <tt>null</tt>
11.20 + * @throws NullPointerException if tasks, or unit, or any element
11.21 + * task subject to execution is <tt>null</tt>
11.22 * @throws TimeoutException if the given timeout elapses before
11.23 * any task successfully completes
11.24 * @throws ExecutionException if no task successfully completes
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java Sun Nov 08 14:49:18 2009 -0800
12.3 @@ -0,0 +1,1988 @@
12.4 +/*
12.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.6 + *
12.7 + * This code is free software; you can redistribute it and/or modify it
12.8 + * under the terms of the GNU General Public License version 2 only, as
12.9 + * published by the Free Software Foundation. Sun designates this
12.10 + * particular file as subject to the "Classpath" exception as provided
12.11 + * by Sun in the LICENSE file that accompanied this code.
12.12 + *
12.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
12.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.16 + * version 2 for more details (a copy is included in the LICENSE file that
12.17 + * accompanied this code).
12.18 + *
12.19 + * You should have received a copy of the GNU General Public License version
12.20 + * 2 along with this work; if not, write to the Free Software Foundation,
12.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.22 + *
12.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
12.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
12.25 + * have any questions.
12.26 + */
12.27 +
12.28 +/*
12.29 + * This file is available under and governed by the GNU General Public
12.30 + * License version 2 only, as published by the Free Software Foundation.
12.31 + * However, the following notice accompanied the original version of this
12.32 + * file:
12.33 + *
12.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
12.35 + * Expert Group and released to the public domain, as explained at
12.36 + * http://creativecommons.org/licenses/publicdomain
12.37 + */
12.38 +
12.39 +package java.util.concurrent;
12.40 +
12.41 +import java.util.ArrayList;
12.42 +import java.util.Arrays;
12.43 +import java.util.Collection;
12.44 +import java.util.Collections;
12.45 +import java.util.List;
12.46 +import java.util.concurrent.locks.Condition;
12.47 +import java.util.concurrent.locks.LockSupport;
12.48 +import java.util.concurrent.locks.ReentrantLock;
12.49 +import java.util.concurrent.atomic.AtomicInteger;
12.50 +import java.util.concurrent.atomic.AtomicLong;
12.51 +
12.52 +/**
12.53 + * An {@link ExecutorService} for running {@link ForkJoinTask}s.
12.54 + * A {@code ForkJoinPool} provides the entry point for submissions
12.55 + * from non-{@code ForkJoinTask}s, as well as management and
12.56 + * monitoring operations.
12.57 + *
12.58 + * <p>A {@code ForkJoinPool} differs from other kinds of {@link
12.59 + * ExecutorService} mainly by virtue of employing
12.60 + * <em>work-stealing</em>: all threads in the pool attempt to find and
12.61 + * execute subtasks created by other active tasks (eventually blocking
12.62 + * waiting for work if none exist). This enables efficient processing
12.63 + * when most tasks spawn other subtasks (as do most {@code
12.64 + * ForkJoinTask}s). A {@code ForkJoinPool} may also be used for mixed
12.65 + * execution of some plain {@code Runnable}- or {@code Callable}-
12.66 + * based activities along with {@code ForkJoinTask}s. When setting
12.67 + * {@linkplain #setAsyncMode async mode}, a {@code ForkJoinPool} may
12.68 + * also be appropriate for use with fine-grained tasks of any form
12.69 + * that are never joined. Otherwise, other {@code ExecutorService}
12.70 + * implementations are typically more appropriate choices.
12.71 + *
12.72 + * <p>A {@code ForkJoinPool} is constructed with a given target
12.73 + * parallelism level; by default, equal to the number of available
12.74 + * processors. Unless configured otherwise via {@link
12.75 + * #setMaintainsParallelism}, the pool attempts to maintain this
12.76 + * number of active (or available) threads by dynamically adding,
12.77 + * suspending, or resuming internal worker threads, even if some tasks
12.78 + * are stalled waiting to join others. However, no such adjustments
12.79 + * are performed in the face of blocked IO or other unmanaged
12.80 + * synchronization. The nested {@link ManagedBlocker} interface
12.81 + * enables extension of the kinds of synchronization accommodated.
12.82 + * The target parallelism level may also be changed dynamically
12.83 + * ({@link #setParallelism}). The total number of threads may be
12.84 + * limited using method {@link #setMaximumPoolSize}, in which case it
12.85 + * may become possible for the activities of a pool to stall due to
12.86 + * the lack of available threads to process new tasks.
12.87 + *
12.88 + * <p>In addition to execution and lifecycle control methods, this
12.89 + * class provides status check methods (for example
12.90 + * {@link #getStealCount}) that are intended to aid in developing,
12.91 + * tuning, and monitoring fork/join applications. Also, method
12.92 + * {@link #toString} returns indications of pool state in a
12.93 + * convenient form for informal monitoring.
12.94 + *
12.95 + * <p><b>Sample Usage.</b> Normally a single {@code ForkJoinPool} is
12.96 + * used for all parallel task execution in a program or subsystem.
12.97 + * Otherwise, use would not usually outweigh the construction and
12.98 + * bookkeeping overhead of creating a large set of threads. For
12.99 + * example, a common pool could be used for the {@code SortTasks}
12.100 + * illustrated in {@link RecursiveAction}. Because {@code
12.101 + * ForkJoinPool} uses threads in {@linkplain java.lang.Thread#isDaemon
12.102 + * daemon} mode, there is typically no need to explicitly {@link
12.103 + * #shutdown} such a pool upon program exit.
12.104 + *
12.105 + * <pre>
12.106 + * static final ForkJoinPool mainPool = new ForkJoinPool();
12.107 + * ...
12.108 + * public void sort(long[] array) {
12.109 + * mainPool.invoke(new SortTask(array, 0, array.length));
12.110 + * }
12.111 + * </pre>
12.112 + *
12.113 + * <p><b>Implementation notes</b>: This implementation restricts the
12.114 + * maximum number of running threads to 32767. Attempts to create
12.115 + * pools with greater than the maximum number result in
12.116 + * {@code IllegalArgumentException}.
12.117 + *
12.118 + * <p>This implementation rejects submitted tasks (that is, by throwing
12.119 + * {@link RejectedExecutionException}) only when the pool is shut down.
12.120 + *
12.121 + * @since 1.7
12.122 + * @author Doug Lea
12.123 + */
12.124 +public class ForkJoinPool extends AbstractExecutorService {
12.125 +
12.126 + /*
12.127 + * See the extended comments interspersed below for design,
12.128 + * rationale, and walkthroughs.
12.129 + */
12.130 +
12.131 + /** Mask for packing and unpacking shorts */
12.132 + private static final int shortMask = 0xffff;
12.133 +
12.134 + /** Max pool size -- must be a power of two minus 1 */
12.135 + private static final int MAX_THREADS = 0x7FFF;
12.136 +
12.137 + /**
12.138 + * Factory for creating new {@link ForkJoinWorkerThread}s.
12.139 + * A {@code ForkJoinWorkerThreadFactory} must be defined and used
12.140 + * for {@code ForkJoinWorkerThread} subclasses that extend base
12.141 + * functionality or initialize threads with different contexts.
12.142 + */
12.143 + public static interface ForkJoinWorkerThreadFactory {
12.144 + /**
12.145 + * Returns a new worker thread operating in the given pool.
12.146 + *
12.147 + * @param pool the pool this thread works in
12.148 + * @throws NullPointerException if the pool is null
12.149 + */
12.150 + public ForkJoinWorkerThread newThread(ForkJoinPool pool);
12.151 + }
12.152 +
12.153 + /**
12.154 + * Default ForkJoinWorkerThreadFactory implementation; creates a
12.155 + * new ForkJoinWorkerThread.
12.156 + */
12.157 + static class DefaultForkJoinWorkerThreadFactory
12.158 + implements ForkJoinWorkerThreadFactory {
12.159 + public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
12.160 + try {
12.161 + return new ForkJoinWorkerThread(pool);
12.162 + } catch (OutOfMemoryError oom) {
12.163 + return null;
12.164 + }
12.165 + }
12.166 + }
12.167 +
12.168 + /**
12.169 + * Creates a new ForkJoinWorkerThread. This factory is used unless
12.170 + * overridden in ForkJoinPool constructors.
12.171 + */
12.172 + public static final ForkJoinWorkerThreadFactory
12.173 + defaultForkJoinWorkerThreadFactory =
12.174 + new DefaultForkJoinWorkerThreadFactory();
12.175 +
12.176 + /**
12.177 + * Permission required for callers of methods that may start or
12.178 + * kill threads.
12.179 + */
12.180 + private static final RuntimePermission modifyThreadPermission =
12.181 + new RuntimePermission("modifyThread");
12.182 +
12.183 + /**
12.184 + * If there is a security manager, makes sure caller has
12.185 + * permission to modify threads.
12.186 + */
12.187 + private static void checkPermission() {
12.188 + SecurityManager security = System.getSecurityManager();
12.189 + if (security != null)
12.190 + security.checkPermission(modifyThreadPermission);
12.191 + }
12.192 +
12.193 + /**
12.194 + * Generator for assigning sequence numbers as pool names.
12.195 + */
12.196 + private static final AtomicInteger poolNumberGenerator =
12.197 + new AtomicInteger();
12.198 +
12.199 + /**
12.200 + * Array holding all worker threads in the pool. Initialized upon
12.201 + * first use. Array size must be a power of two. Updates and
12.202 + * replacements are protected by workerLock, but it is always kept
12.203 + * in a consistent enough state to be randomly accessed without
12.204 + * locking by workers performing work-stealing.
12.205 + */
12.206 + volatile ForkJoinWorkerThread[] workers;
12.207 +
12.208 + /**
12.209 + * Lock protecting access to workers.
12.210 + */
12.211 + private final ReentrantLock workerLock;
12.212 +
12.213 + /**
12.214 + * Condition for awaitTermination.
12.215 + */
12.216 + private final Condition termination;
12.217 +
12.218 + /**
12.219 + * The uncaught exception handler used when any worker
12.220 + * abruptly terminates
12.221 + */
12.222 + private Thread.UncaughtExceptionHandler ueh;
12.223 +
12.224 + /**
12.225 + * Creation factory for worker threads.
12.226 + */
12.227 + private final ForkJoinWorkerThreadFactory factory;
12.228 +
12.229 + /**
12.230 + * Head of stack of threads that were created to maintain
12.231 + * parallelism when other threads blocked, but have since
12.232 + * suspended when the parallelism level rose.
12.233 + */
12.234 + private volatile WaitQueueNode spareStack;
12.235 +
12.236 + /**
12.237 + * Sum of per-thread steal counts, updated only when threads are
12.238 + * idle or terminating.
12.239 + */
12.240 + private final AtomicLong stealCount;
12.241 +
12.242 + /**
12.243 + * Queue for external submissions.
12.244 + */
12.245 + private final LinkedTransferQueue<ForkJoinTask<?>> submissionQueue;
12.246 +
12.247 + /**
12.248 + * Head of Treiber stack for barrier sync. See below for explanation.
12.249 + */
12.250 + private volatile WaitQueueNode syncStack;
12.251 +
12.252 + /**
12.253 + * The count for event barrier
12.254 + */
12.255 + private volatile long eventCount;
12.256 +
12.257 + /**
12.258 + * Pool number, just for assigning useful names to worker threads
12.259 + */
12.260 + private final int poolNumber;
12.261 +
12.262 + /**
12.263 + * The maximum allowed pool size
12.264 + */
12.265 + private volatile int maxPoolSize;
12.266 +
12.267 + /**
12.268 + * The desired parallelism level, updated only under workerLock.
12.269 + */
12.270 + private volatile int parallelism;
12.271 +
12.272 + /**
12.273 + * True if use local fifo, not default lifo, for local polling
12.274 + */
12.275 + private volatile boolean locallyFifo;
12.276 +
12.277 + /**
12.278 + * Holds number of total (i.e., created and not yet terminated)
12.279 + * and running (i.e., not blocked on joins or other managed sync)
12.280 + * threads, packed into one int to ensure consistent snapshot when
12.281 + * making decisions about creating and suspending spare
12.282 + * threads. Updated only by CAS. Note: CASes in
12.283 + * updateRunningCount and preJoin assume that running active count
12.284 + * is in low word, so need to be modified if this changes.
12.285 + */
12.286 + private volatile int workerCounts;
12.287 +
12.288 + private static int totalCountOf(int s) { return s >>> 16; }
12.289 + private static int runningCountOf(int s) { return s & shortMask; }
12.290 + private static int workerCountsFor(int t, int r) { return (t << 16) + r; }
12.291 +
12.292 + /**
12.293 + * Adds delta (which may be negative) to running count. This must
12.294 + * be called before (with negative arg) and after (with positive)
12.295 + * any managed synchronization (i.e., mainly, joins).
12.296 + *
12.297 + * @param delta the number to add
12.298 + */
12.299 + final void updateRunningCount(int delta) {
12.300 + int s;
12.301 + do {} while (!casWorkerCounts(s = workerCounts, s + delta));
12.302 + }
12.303 +
12.304 + /**
12.305 + * Adds delta (which may be negative) to both total and running
12.306 + * count. This must be called upon creation and termination of
12.307 + * worker threads.
12.308 + *
12.309 + * @param delta the number to add
12.310 + */
12.311 + private void updateWorkerCount(int delta) {
12.312 + int d = delta + (delta << 16); // add to both lo and hi parts
12.313 + int s;
12.314 + do {} while (!casWorkerCounts(s = workerCounts, s + d));
12.315 + }
12.316 +
12.317 + /**
12.318 + * Lifecycle control. High word contains runState, low word
12.319 + * contains the number of workers that are (probably) executing
12.320 + * tasks. This value is atomically incremented before a worker
12.321 + * gets a task to run, and decremented when worker has no tasks
12.322 + * and cannot find any. These two fields are bundled together to
12.323 + * support correct termination triggering. Note: activeCount
12.324 + * CAS'es cheat by assuming active count is in low word, so need
12.325 + * to be modified if this changes
12.326 + */
12.327 + private volatile int runControl;
12.328 +
12.329 + // RunState values. Order among values matters
12.330 + private static final int RUNNING = 0;
12.331 + private static final int SHUTDOWN = 1;
12.332 + private static final int TERMINATING = 2;
12.333 + private static final int TERMINATED = 3;
12.334 +
12.335 + private static int runStateOf(int c) { return c >>> 16; }
12.336 + private static int activeCountOf(int c) { return c & shortMask; }
12.337 + private static int runControlFor(int r, int a) { return (r << 16) + a; }
12.338 +
12.339 + /**
12.340 + * Tries incrementing active count; fails on contention.
12.341 + * Called by workers before/during executing tasks.
12.342 + *
12.343 + * @return true on success
12.344 + */
12.345 + final boolean tryIncrementActiveCount() {
12.346 + int c = runControl;
12.347 + return casRunControl(c, c+1);
12.348 + }
12.349 +
12.350 + /**
12.351 + * Tries decrementing active count; fails on contention.
12.352 + * Possibly triggers termination on success.
12.353 + * Called by workers when they can't find tasks.
12.354 + *
12.355 + * @return true on success
12.356 + */
12.357 + final boolean tryDecrementActiveCount() {
12.358 + int c = runControl;
12.359 + int nextc = c - 1;
12.360 + if (!casRunControl(c, nextc))
12.361 + return false;
12.362 + if (canTerminateOnShutdown(nextc))
12.363 + terminateOnShutdown();
12.364 + return true;
12.365 + }
12.366 +
12.367 + /**
12.368 + * Returns {@code true} if argument represents zero active count
12.369 + * and nonzero runstate, which is the triggering condition for
12.370 + * terminating on shutdown.
12.371 + */
12.372 + private static boolean canTerminateOnShutdown(int c) {
12.373 + // i.e. least bit is nonzero runState bit
12.374 + return ((c & -c) >>> 16) != 0;
12.375 + }
12.376 +
12.377 + /**
12.378 + * Transition run state to at least the given state. Return true
12.379 + * if not already at least given state.
12.380 + */
12.381 + private boolean transitionRunStateTo(int state) {
12.382 + for (;;) {
12.383 + int c = runControl;
12.384 + if (runStateOf(c) >= state)
12.385 + return false;
12.386 + if (casRunControl(c, runControlFor(state, activeCountOf(c))))
12.387 + return true;
12.388 + }
12.389 + }
12.390 +
12.391 + /**
12.392 + * Controls whether to add spares to maintain parallelism
12.393 + */
12.394 + private volatile boolean maintainsParallelism;
12.395 +
12.396 + // Constructors
12.397 +
12.398 + /**
12.399 + * Creates a {@code ForkJoinPool} with parallelism equal to {@link
12.400 + * java.lang.Runtime#availableProcessors}, and using the {@linkplain
12.401 + * #defaultForkJoinWorkerThreadFactory default thread factory}.
12.402 + *
12.403 + * @throws SecurityException if a security manager exists and
12.404 + * the caller is not permitted to modify threads
12.405 + * because it does not hold {@link
12.406 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.407 + */
12.408 + public ForkJoinPool() {
12.409 + this(Runtime.getRuntime().availableProcessors(),
12.410 + defaultForkJoinWorkerThreadFactory);
12.411 + }
12.412 +
12.413 + /**
12.414 + * Creates a {@code ForkJoinPool} with the indicated parallelism
12.415 + * level and using the {@linkplain
12.416 + * #defaultForkJoinWorkerThreadFactory default thread factory}.
12.417 + *
12.418 + * @param parallelism the parallelism level
12.419 + * @throws IllegalArgumentException if parallelism less than or
12.420 + * equal to zero, or greater than implementation limit
12.421 + * @throws SecurityException if a security manager exists and
12.422 + * the caller is not permitted to modify threads
12.423 + * because it does not hold {@link
12.424 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.425 + */
12.426 + public ForkJoinPool(int parallelism) {
12.427 + this(parallelism, defaultForkJoinWorkerThreadFactory);
12.428 + }
12.429 +
12.430 + /**
12.431 + * Creates a {@code ForkJoinPool} with parallelism equal to {@link
12.432 + * java.lang.Runtime#availableProcessors}, and using the given
12.433 + * thread factory.
12.434 + *
12.435 + * @param factory the factory for creating new threads
12.436 + * @throws NullPointerException if the factory is null
12.437 + * @throws SecurityException if a security manager exists and
12.438 + * the caller is not permitted to modify threads
12.439 + * because it does not hold {@link
12.440 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.441 + */
12.442 + public ForkJoinPool(ForkJoinWorkerThreadFactory factory) {
12.443 + this(Runtime.getRuntime().availableProcessors(), factory);
12.444 + }
12.445 +
12.446 + /**
12.447 + * Creates a {@code ForkJoinPool} with the given parallelism and
12.448 + * thread factory.
12.449 + *
12.450 + * @param parallelism the parallelism level
12.451 + * @param factory the factory for creating new threads
12.452 + * @throws IllegalArgumentException if parallelism less than or
12.453 + * equal to zero, or greater than implementation limit
12.454 + * @throws NullPointerException if the factory is null
12.455 + * @throws SecurityException if a security manager exists and
12.456 + * the caller is not permitted to modify threads
12.457 + * because it does not hold {@link
12.458 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.459 + */
12.460 + public ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory) {
12.461 + if (parallelism <= 0 || parallelism > MAX_THREADS)
12.462 + throw new IllegalArgumentException();
12.463 + if (factory == null)
12.464 + throw new NullPointerException();
12.465 + checkPermission();
12.466 + this.factory = factory;
12.467 + this.parallelism = parallelism;
12.468 + this.maxPoolSize = MAX_THREADS;
12.469 + this.maintainsParallelism = true;
12.470 + this.poolNumber = poolNumberGenerator.incrementAndGet();
12.471 + this.workerLock = new ReentrantLock();
12.472 + this.termination = workerLock.newCondition();
12.473 + this.stealCount = new AtomicLong();
12.474 + this.submissionQueue = new LinkedTransferQueue<ForkJoinTask<?>>();
12.475 + // worker array and workers are lazily constructed
12.476 + }
12.477 +
12.478 + /**
12.479 + * Creates a new worker thread using factory.
12.480 + *
12.481 + * @param index the index to assign worker
12.482 + * @return new worker, or null if factory failed
12.483 + */
12.484 + private ForkJoinWorkerThread createWorker(int index) {
12.485 + Thread.UncaughtExceptionHandler h = ueh;
12.486 + ForkJoinWorkerThread w = factory.newThread(this);
12.487 + if (w != null) {
12.488 + w.poolIndex = index;
12.489 + w.setDaemon(true);
12.490 + w.setAsyncMode(locallyFifo);
12.491 + w.setName("ForkJoinPool-" + poolNumber + "-worker-" + index);
12.492 + if (h != null)
12.493 + w.setUncaughtExceptionHandler(h);
12.494 + }
12.495 + return w;
12.496 + }
12.497 +
12.498 + /**
12.499 + * Returns a good size for worker array given pool size.
12.500 + * Currently requires size to be a power of two.
12.501 + */
12.502 + private static int arraySizeFor(int poolSize) {
12.503 + if (poolSize <= 1)
12.504 + return 1;
12.505 + // See Hackers Delight, sec 3.2
12.506 + int c = poolSize >= MAX_THREADS ? MAX_THREADS : (poolSize - 1);
12.507 + c |= c >>> 1;
12.508 + c |= c >>> 2;
12.509 + c |= c >>> 4;
12.510 + c |= c >>> 8;
12.511 + c |= c >>> 16;
12.512 + return c + 1;
12.513 + }
12.514 +
12.515 + /**
12.516 + * Creates or resizes array if necessary to hold newLength.
12.517 + * Call only under exclusion.
12.518 + *
12.519 + * @return the array
12.520 + */
12.521 + private ForkJoinWorkerThread[] ensureWorkerArrayCapacity(int newLength) {
12.522 + ForkJoinWorkerThread[] ws = workers;
12.523 + if (ws == null)
12.524 + return workers = new ForkJoinWorkerThread[arraySizeFor(newLength)];
12.525 + else if (newLength > ws.length)
12.526 + return workers = Arrays.copyOf(ws, arraySizeFor(newLength));
12.527 + else
12.528 + return ws;
12.529 + }
12.530 +
12.531 + /**
12.532 + * Tries to shrink workers into smaller array after one or more terminate.
12.533 + */
12.534 + private void tryShrinkWorkerArray() {
12.535 + ForkJoinWorkerThread[] ws = workers;
12.536 + if (ws != null) {
12.537 + int len = ws.length;
12.538 + int last = len - 1;
12.539 + while (last >= 0 && ws[last] == null)
12.540 + --last;
12.541 + int newLength = arraySizeFor(last+1);
12.542 + if (newLength < len)
12.543 + workers = Arrays.copyOf(ws, newLength);
12.544 + }
12.545 + }
12.546 +
12.547 + /**
12.548 + * Initializes workers if necessary.
12.549 + */
12.550 + final void ensureWorkerInitialization() {
12.551 + ForkJoinWorkerThread[] ws = workers;
12.552 + if (ws == null) {
12.553 + final ReentrantLock lock = this.workerLock;
12.554 + lock.lock();
12.555 + try {
12.556 + ws = workers;
12.557 + if (ws == null) {
12.558 + int ps = parallelism;
12.559 + ws = ensureWorkerArrayCapacity(ps);
12.560 + for (int i = 0; i < ps; ++i) {
12.561 + ForkJoinWorkerThread w = createWorker(i);
12.562 + if (w != null) {
12.563 + ws[i] = w;
12.564 + w.start();
12.565 + updateWorkerCount(1);
12.566 + }
12.567 + }
12.568 + }
12.569 + } finally {
12.570 + lock.unlock();
12.571 + }
12.572 + }
12.573 + }
12.574 +
12.575 + /**
12.576 + * Worker creation and startup for threads added via setParallelism.
12.577 + */
12.578 + private void createAndStartAddedWorkers() {
12.579 + resumeAllSpares(); // Allow spares to convert to nonspare
12.580 + int ps = parallelism;
12.581 + ForkJoinWorkerThread[] ws = ensureWorkerArrayCapacity(ps);
12.582 + int len = ws.length;
12.583 + // Sweep through slots, to keep lowest indices most populated
12.584 + int k = 0;
12.585 + while (k < len) {
12.586 + if (ws[k] != null) {
12.587 + ++k;
12.588 + continue;
12.589 + }
12.590 + int s = workerCounts;
12.591 + int tc = totalCountOf(s);
12.592 + int rc = runningCountOf(s);
12.593 + if (rc >= ps || tc >= ps)
12.594 + break;
12.595 + if (casWorkerCounts (s, workerCountsFor(tc+1, rc+1))) {
12.596 + ForkJoinWorkerThread w = createWorker(k);
12.597 + if (w != null) {
12.598 + ws[k++] = w;
12.599 + w.start();
12.600 + }
12.601 + else {
12.602 + updateWorkerCount(-1); // back out on failed creation
12.603 + break;
12.604 + }
12.605 + }
12.606 + }
12.607 + }
12.608 +
12.609 + // Execution methods
12.610 +
12.611 + /**
12.612 + * Common code for execute, invoke and submit
12.613 + */
12.614 + private <T> void doSubmit(ForkJoinTask<T> task) {
12.615 + if (task == null)
12.616 + throw new NullPointerException();
12.617 + if (isShutdown())
12.618 + throw new RejectedExecutionException();
12.619 + if (workers == null)
12.620 + ensureWorkerInitialization();
12.621 + submissionQueue.offer(task);
12.622 + signalIdleWorkers();
12.623 + }
12.624 +
12.625 + /**
12.626 + * Performs the given task, returning its result upon completion.
12.627 + *
12.628 + * @param task the task
12.629 + * @return the task's result
12.630 + * @throws NullPointerException if the task is null
12.631 + * @throws RejectedExecutionException if the task cannot be
12.632 + * scheduled for execution
12.633 + */
12.634 + public <T> T invoke(ForkJoinTask<T> task) {
12.635 + doSubmit(task);
12.636 + return task.join();
12.637 + }
12.638 +
12.639 + /**
12.640 + * Arranges for (asynchronous) execution of the given task.
12.641 + *
12.642 + * @param task the task
12.643 + * @throws NullPointerException if the task is null
12.644 + * @throws RejectedExecutionException if the task cannot be
12.645 + * scheduled for execution
12.646 + */
12.647 + public void execute(ForkJoinTask<?> task) {
12.648 + doSubmit(task);
12.649 + }
12.650 +
12.651 + // AbstractExecutorService methods
12.652 +
12.653 + /**
12.654 + * @throws NullPointerException if the task is null
12.655 + * @throws RejectedExecutionException if the task cannot be
12.656 + * scheduled for execution
12.657 + */
12.658 + public void execute(Runnable task) {
12.659 + ForkJoinTask<?> job;
12.660 + if (task instanceof ForkJoinTask<?>) // avoid re-wrap
12.661 + job = (ForkJoinTask<?>) task;
12.662 + else
12.663 + job = ForkJoinTask.adapt(task, null);
12.664 + doSubmit(job);
12.665 + }
12.666 +
12.667 + /**
12.668 + * @throws NullPointerException if the task is null
12.669 + * @throws RejectedExecutionException if the task cannot be
12.670 + * scheduled for execution
12.671 + */
12.672 + public <T> ForkJoinTask<T> submit(Callable<T> task) {
12.673 + ForkJoinTask<T> job = ForkJoinTask.adapt(task);
12.674 + doSubmit(job);
12.675 + return job;
12.676 + }
12.677 +
12.678 + /**
12.679 + * @throws NullPointerException if the task is null
12.680 + * @throws RejectedExecutionException if the task cannot be
12.681 + * scheduled for execution
12.682 + */
12.683 + public <T> ForkJoinTask<T> submit(Runnable task, T result) {
12.684 + ForkJoinTask<T> job = ForkJoinTask.adapt(task, result);
12.685 + doSubmit(job);
12.686 + return job;
12.687 + }
12.688 +
12.689 + /**
12.690 + * @throws NullPointerException if the task is null
12.691 + * @throws RejectedExecutionException if the task cannot be
12.692 + * scheduled for execution
12.693 + */
12.694 + public ForkJoinTask<?> submit(Runnable task) {
12.695 + ForkJoinTask<?> job;
12.696 + if (task instanceof ForkJoinTask<?>) // avoid re-wrap
12.697 + job = (ForkJoinTask<?>) task;
12.698 + else
12.699 + job = ForkJoinTask.adapt(task, null);
12.700 + doSubmit(job);
12.701 + return job;
12.702 + }
12.703 +
12.704 + /**
12.705 + * Submits a ForkJoinTask for execution.
12.706 + *
12.707 + * @param task the task to submit
12.708 + * @return the task
12.709 + * @throws NullPointerException if the task is null
12.710 + * @throws RejectedExecutionException if the task cannot be
12.711 + * scheduled for execution
12.712 + */
12.713 + public <T> ForkJoinTask<T> submit(ForkJoinTask<T> task) {
12.714 + doSubmit(task);
12.715 + return task;
12.716 + }
12.717 +
12.718 +
12.719 + /**
12.720 + * @throws NullPointerException {@inheritDoc}
12.721 + * @throws RejectedExecutionException {@inheritDoc}
12.722 + */
12.723 + public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
12.724 + ArrayList<ForkJoinTask<T>> forkJoinTasks =
12.725 + new ArrayList<ForkJoinTask<T>>(tasks.size());
12.726 + for (Callable<T> task : tasks)
12.727 + forkJoinTasks.add(ForkJoinTask.adapt(task));
12.728 + invoke(new InvokeAll<T>(forkJoinTasks));
12.729 +
12.730 + @SuppressWarnings({"unchecked", "rawtypes"})
12.731 + List<Future<T>> futures = (List<Future<T>>) (List) forkJoinTasks;
12.732 + return futures;
12.733 + }
12.734 +
12.735 + static final class InvokeAll<T> extends RecursiveAction {
12.736 + final ArrayList<ForkJoinTask<T>> tasks;
12.737 + InvokeAll(ArrayList<ForkJoinTask<T>> tasks) { this.tasks = tasks; }
12.738 + public void compute() {
12.739 + try { invokeAll(tasks); }
12.740 + catch (Exception ignore) {}
12.741 + }
12.742 + private static final long serialVersionUID = -7914297376763021607L;
12.743 + }
12.744 +
12.745 + // Configuration and status settings and queries
12.746 +
12.747 + /**
12.748 + * Returns the factory used for constructing new workers.
12.749 + *
12.750 + * @return the factory used for constructing new workers
12.751 + */
12.752 + public ForkJoinWorkerThreadFactory getFactory() {
12.753 + return factory;
12.754 + }
12.755 +
12.756 + /**
12.757 + * Returns the handler for internal worker threads that terminate
12.758 + * due to unrecoverable errors encountered while executing tasks.
12.759 + *
12.760 + * @return the handler, or {@code null} if none
12.761 + */
12.762 + public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
12.763 + Thread.UncaughtExceptionHandler h;
12.764 + final ReentrantLock lock = this.workerLock;
12.765 + lock.lock();
12.766 + try {
12.767 + h = ueh;
12.768 + } finally {
12.769 + lock.unlock();
12.770 + }
12.771 + return h;
12.772 + }
12.773 +
12.774 + /**
12.775 + * Sets the handler for internal worker threads that terminate due
12.776 + * to unrecoverable errors encountered while executing tasks.
12.777 + * Unless set, the current default or ThreadGroup handler is used
12.778 + * as handler.
12.779 + *
12.780 + * @param h the new handler
12.781 + * @return the old handler, or {@code null} if none
12.782 + * @throws SecurityException if a security manager exists and
12.783 + * the caller is not permitted to modify threads
12.784 + * because it does not hold {@link
12.785 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.786 + */
12.787 + public Thread.UncaughtExceptionHandler
12.788 + setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler h) {
12.789 + checkPermission();
12.790 + Thread.UncaughtExceptionHandler old = null;
12.791 + final ReentrantLock lock = this.workerLock;
12.792 + lock.lock();
12.793 + try {
12.794 + old = ueh;
12.795 + ueh = h;
12.796 + ForkJoinWorkerThread[] ws = workers;
12.797 + if (ws != null) {
12.798 + for (int i = 0; i < ws.length; ++i) {
12.799 + ForkJoinWorkerThread w = ws[i];
12.800 + if (w != null)
12.801 + w.setUncaughtExceptionHandler(h);
12.802 + }
12.803 + }
12.804 + } finally {
12.805 + lock.unlock();
12.806 + }
12.807 + return old;
12.808 + }
12.809 +
12.810 +
12.811 + /**
12.812 + * Sets the target parallelism level of this pool.
12.813 + *
12.814 + * @param parallelism the target parallelism
12.815 + * @throws IllegalArgumentException if parallelism less than or
12.816 + * equal to zero or greater than maximum size bounds
12.817 + * @throws SecurityException if a security manager exists and
12.818 + * the caller is not permitted to modify threads
12.819 + * because it does not hold {@link
12.820 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.821 + */
12.822 + public void setParallelism(int parallelism) {
12.823 + checkPermission();
12.824 + if (parallelism <= 0 || parallelism > maxPoolSize)
12.825 + throw new IllegalArgumentException();
12.826 + final ReentrantLock lock = this.workerLock;
12.827 + lock.lock();
12.828 + try {
12.829 + if (isProcessingTasks()) {
12.830 + int p = this.parallelism;
12.831 + this.parallelism = parallelism;
12.832 + if (parallelism > p)
12.833 + createAndStartAddedWorkers();
12.834 + else
12.835 + trimSpares();
12.836 + }
12.837 + } finally {
12.838 + lock.unlock();
12.839 + }
12.840 + signalIdleWorkers();
12.841 + }
12.842 +
12.843 + /**
12.844 + * Returns the targeted parallelism level of this pool.
12.845 + *
12.846 + * @return the targeted parallelism level of this pool
12.847 + */
12.848 + public int getParallelism() {
12.849 + return parallelism;
12.850 + }
12.851 +
12.852 + /**
12.853 + * Returns the number of worker threads that have started but not
12.854 + * yet terminated. This result returned by this method may differ
12.855 + * from {@link #getParallelism} when threads are created to
12.856 + * maintain parallelism when others are cooperatively blocked.
12.857 + *
12.858 + * @return the number of worker threads
12.859 + */
12.860 + public int getPoolSize() {
12.861 + return totalCountOf(workerCounts);
12.862 + }
12.863 +
12.864 + /**
12.865 + * Returns the maximum number of threads allowed to exist in the
12.866 + * pool. Unless set using {@link #setMaximumPoolSize}, the
12.867 + * maximum is an implementation-defined value designed only to
12.868 + * prevent runaway growth.
12.869 + *
12.870 + * @return the maximum
12.871 + */
12.872 + public int getMaximumPoolSize() {
12.873 + return maxPoolSize;
12.874 + }
12.875 +
12.876 + /**
12.877 + * Sets the maximum number of threads allowed to exist in the
12.878 + * pool. The given value should normally be greater than or equal
12.879 + * to the {@link #getParallelism parallelism} level. Setting this
12.880 + * value has no effect on current pool size. It controls
12.881 + * construction of new threads.
12.882 + *
12.883 + * @throws IllegalArgumentException if negative or greater than
12.884 + * internal implementation limit
12.885 + */
12.886 + public void setMaximumPoolSize(int newMax) {
12.887 + if (newMax < 0 || newMax > MAX_THREADS)
12.888 + throw new IllegalArgumentException();
12.889 + maxPoolSize = newMax;
12.890 + }
12.891 +
12.892 +
12.893 + /**
12.894 + * Returns {@code true} if this pool dynamically maintains its
12.895 + * target parallelism level. If false, new threads are added only
12.896 + * to avoid possible starvation. This setting is by default true.
12.897 + *
12.898 + * @return {@code true} if maintains parallelism
12.899 + */
12.900 + public boolean getMaintainsParallelism() {
12.901 + return maintainsParallelism;
12.902 + }
12.903 +
12.904 + /**
12.905 + * Sets whether this pool dynamically maintains its target
12.906 + * parallelism level. If false, new threads are added only to
12.907 + * avoid possible starvation.
12.908 + *
12.909 + * @param enable {@code true} to maintain parallelism
12.910 + */
12.911 + public void setMaintainsParallelism(boolean enable) {
12.912 + maintainsParallelism = enable;
12.913 + }
12.914 +
12.915 + /**
12.916 + * Establishes local first-in-first-out scheduling mode for forked
12.917 + * tasks that are never joined. This mode may be more appropriate
12.918 + * than default locally stack-based mode in applications in which
12.919 + * worker threads only process asynchronous tasks. This method is
12.920 + * designed to be invoked only when the pool is quiescent, and
12.921 + * typically only before any tasks are submitted. The effects of
12.922 + * invocations at other times may be unpredictable.
12.923 + *
12.924 + * @param async if {@code true}, use locally FIFO scheduling
12.925 + * @return the previous mode
12.926 + * @see #getAsyncMode
12.927 + */
12.928 + public boolean setAsyncMode(boolean async) {
12.929 + boolean oldMode = locallyFifo;
12.930 + locallyFifo = async;
12.931 + ForkJoinWorkerThread[] ws = workers;
12.932 + if (ws != null) {
12.933 + for (int i = 0; i < ws.length; ++i) {
12.934 + ForkJoinWorkerThread t = ws[i];
12.935 + if (t != null)
12.936 + t.setAsyncMode(async);
12.937 + }
12.938 + }
12.939 + return oldMode;
12.940 + }
12.941 +
12.942 + /**
12.943 + * Returns {@code true} if this pool uses local first-in-first-out
12.944 + * scheduling mode for forked tasks that are never joined.
12.945 + *
12.946 + * @return {@code true} if this pool uses async mode
12.947 + * @see #setAsyncMode
12.948 + */
12.949 + public boolean getAsyncMode() {
12.950 + return locallyFifo;
12.951 + }
12.952 +
12.953 + /**
12.954 + * Returns an estimate of the number of worker threads that are
12.955 + * not blocked waiting to join tasks or for other managed
12.956 + * synchronization.
12.957 + *
12.958 + * @return the number of worker threads
12.959 + */
12.960 + public int getRunningThreadCount() {
12.961 + return runningCountOf(workerCounts);
12.962 + }
12.963 +
12.964 + /**
12.965 + * Returns an estimate of the number of threads that are currently
12.966 + * stealing or executing tasks. This method may overestimate the
12.967 + * number of active threads.
12.968 + *
12.969 + * @return the number of active threads
12.970 + */
12.971 + public int getActiveThreadCount() {
12.972 + return activeCountOf(runControl);
12.973 + }
12.974 +
12.975 + /**
12.976 + * Returns an estimate of the number of threads that are currently
12.977 + * idle waiting for tasks. This method may underestimate the
12.978 + * number of idle threads.
12.979 + *
12.980 + * @return the number of idle threads
12.981 + */
12.982 + final int getIdleThreadCount() {
12.983 + int c = runningCountOf(workerCounts) - activeCountOf(runControl);
12.984 + return (c <= 0) ? 0 : c;
12.985 + }
12.986 +
12.987 + /**
12.988 + * Returns {@code true} if all worker threads are currently idle.
12.989 + * An idle worker is one that cannot obtain a task to execute
12.990 + * because none are available to steal from other threads, and
12.991 + * there are no pending submissions to the pool. This method is
12.992 + * conservative; it might not return {@code true} immediately upon
12.993 + * idleness of all threads, but will eventually become true if
12.994 + * threads remain inactive.
12.995 + *
12.996 + * @return {@code true} if all threads are currently idle
12.997 + */
12.998 + public boolean isQuiescent() {
12.999 + return activeCountOf(runControl) == 0;
12.1000 + }
12.1001 +
12.1002 + /**
12.1003 + * Returns an estimate of the total number of tasks stolen from
12.1004 + * one thread's work queue by another. The reported value
12.1005 + * underestimates the actual total number of steals when the pool
12.1006 + * is not quiescent. This value may be useful for monitoring and
12.1007 + * tuning fork/join programs: in general, steal counts should be
12.1008 + * high enough to keep threads busy, but low enough to avoid
12.1009 + * overhead and contention across threads.
12.1010 + *
12.1011 + * @return the number of steals
12.1012 + */
12.1013 + public long getStealCount() {
12.1014 + return stealCount.get();
12.1015 + }
12.1016 +
12.1017 + /**
12.1018 + * Accumulates steal count from a worker.
12.1019 + * Call only when worker known to be idle.
12.1020 + */
12.1021 + private void updateStealCount(ForkJoinWorkerThread w) {
12.1022 + int sc = w.getAndClearStealCount();
12.1023 + if (sc != 0)
12.1024 + stealCount.addAndGet(sc);
12.1025 + }
12.1026 +
12.1027 + /**
12.1028 + * Returns an estimate of the total number of tasks currently held
12.1029 + * in queues by worker threads (but not including tasks submitted
12.1030 + * to the pool that have not begun executing). This value is only
12.1031 + * an approximation, obtained by iterating across all threads in
12.1032 + * the pool. This method may be useful for tuning task
12.1033 + * granularities.
12.1034 + *
12.1035 + * @return the number of queued tasks
12.1036 + */
12.1037 + public long getQueuedTaskCount() {
12.1038 + long count = 0;
12.1039 + ForkJoinWorkerThread[] ws = workers;
12.1040 + if (ws != null) {
12.1041 + for (int i = 0; i < ws.length; ++i) {
12.1042 + ForkJoinWorkerThread t = ws[i];
12.1043 + if (t != null)
12.1044 + count += t.getQueueSize();
12.1045 + }
12.1046 + }
12.1047 + return count;
12.1048 + }
12.1049 +
12.1050 + /**
12.1051 + * Returns an estimate of the number of tasks submitted to this
12.1052 + * pool that have not yet begun executing. This method takes time
12.1053 + * proportional to the number of submissions.
12.1054 + *
12.1055 + * @return the number of queued submissions
12.1056 + */
12.1057 + public int getQueuedSubmissionCount() {
12.1058 + return submissionQueue.size();
12.1059 + }
12.1060 +
12.1061 + /**
12.1062 + * Returns {@code true} if there are any tasks submitted to this
12.1063 + * pool that have not yet begun executing.
12.1064 + *
12.1065 + * @return {@code true} if there are any queued submissions
12.1066 + */
12.1067 + public boolean hasQueuedSubmissions() {
12.1068 + return !submissionQueue.isEmpty();
12.1069 + }
12.1070 +
12.1071 + /**
12.1072 + * Removes and returns the next unexecuted submission if one is
12.1073 + * available. This method may be useful in extensions to this
12.1074 + * class that re-assign work in systems with multiple pools.
12.1075 + *
12.1076 + * @return the next submission, or {@code null} if none
12.1077 + */
12.1078 + protected ForkJoinTask<?> pollSubmission() {
12.1079 + return submissionQueue.poll();
12.1080 + }
12.1081 +
12.1082 + /**
12.1083 + * Removes all available unexecuted submitted and forked tasks
12.1084 + * from scheduling queues and adds them to the given collection,
12.1085 + * without altering their execution status. These may include
12.1086 + * artificially generated or wrapped tasks. This method is
12.1087 + * designed to be invoked only when the pool is known to be
12.1088 + * quiescent. Invocations at other times may not remove all
12.1089 + * tasks. A failure encountered while attempting to add elements
12.1090 + * to collection {@code c} may result in elements being in
12.1091 + * neither, either or both collections when the associated
12.1092 + * exception is thrown. The behavior of this operation is
12.1093 + * undefined if the specified collection is modified while the
12.1094 + * operation is in progress.
12.1095 + *
12.1096 + * @param c the collection to transfer elements into
12.1097 + * @return the number of elements transferred
12.1098 + */
12.1099 + protected int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
12.1100 + int n = submissionQueue.drainTo(c);
12.1101 + ForkJoinWorkerThread[] ws = workers;
12.1102 + if (ws != null) {
12.1103 + for (int i = 0; i < ws.length; ++i) {
12.1104 + ForkJoinWorkerThread w = ws[i];
12.1105 + if (w != null)
12.1106 + n += w.drainTasksTo(c);
12.1107 + }
12.1108 + }
12.1109 + return n;
12.1110 + }
12.1111 +
12.1112 + /**
12.1113 + * Returns a string identifying this pool, as well as its state,
12.1114 + * including indications of run state, parallelism level, and
12.1115 + * worker and task counts.
12.1116 + *
12.1117 + * @return a string identifying this pool, as well as its state
12.1118 + */
12.1119 + public String toString() {
12.1120 + int ps = parallelism;
12.1121 + int wc = workerCounts;
12.1122 + int rc = runControl;
12.1123 + long st = getStealCount();
12.1124 + long qt = getQueuedTaskCount();
12.1125 + long qs = getQueuedSubmissionCount();
12.1126 + return super.toString() +
12.1127 + "[" + runStateToString(runStateOf(rc)) +
12.1128 + ", parallelism = " + ps +
12.1129 + ", size = " + totalCountOf(wc) +
12.1130 + ", active = " + activeCountOf(rc) +
12.1131 + ", running = " + runningCountOf(wc) +
12.1132 + ", steals = " + st +
12.1133 + ", tasks = " + qt +
12.1134 + ", submissions = " + qs +
12.1135 + "]";
12.1136 + }
12.1137 +
12.1138 + private static String runStateToString(int rs) {
12.1139 + switch(rs) {
12.1140 + case RUNNING: return "Running";
12.1141 + case SHUTDOWN: return "Shutting down";
12.1142 + case TERMINATING: return "Terminating";
12.1143 + case TERMINATED: return "Terminated";
12.1144 + default: throw new Error("Unknown run state");
12.1145 + }
12.1146 + }
12.1147 +
12.1148 + // lifecycle control
12.1149 +
12.1150 + /**
12.1151 + * Initiates an orderly shutdown in which previously submitted
12.1152 + * tasks are executed, but no new tasks will be accepted.
12.1153 + * Invocation has no additional effect if already shut down.
12.1154 + * Tasks that are in the process of being submitted concurrently
12.1155 + * during the course of this method may or may not be rejected.
12.1156 + *
12.1157 + * @throws SecurityException if a security manager exists and
12.1158 + * the caller is not permitted to modify threads
12.1159 + * because it does not hold {@link
12.1160 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.1161 + */
12.1162 + public void shutdown() {
12.1163 + checkPermission();
12.1164 + transitionRunStateTo(SHUTDOWN);
12.1165 + if (canTerminateOnShutdown(runControl)) {
12.1166 + if (workers == null) { // shutting down before workers created
12.1167 + final ReentrantLock lock = this.workerLock;
12.1168 + lock.lock();
12.1169 + try {
12.1170 + if (workers == null) {
12.1171 + terminate();
12.1172 + transitionRunStateTo(TERMINATED);
12.1173 + termination.signalAll();
12.1174 + }
12.1175 + } finally {
12.1176 + lock.unlock();
12.1177 + }
12.1178 + }
12.1179 + terminateOnShutdown();
12.1180 + }
12.1181 + }
12.1182 +
12.1183 + /**
12.1184 + * Attempts to cancel and/or stop all tasks, and reject all
12.1185 + * subsequently submitted tasks. Tasks that are in the process of
12.1186 + * being submitted or executed concurrently during the course of
12.1187 + * this method may or may not be rejected. This method cancels
12.1188 + * both existing and unexecuted tasks, in order to permit
12.1189 + * termination in the presence of task dependencies. So the method
12.1190 + * always returns an empty list (unlike the case for some other
12.1191 + * Executors).
12.1192 + *
12.1193 + * @return an empty list
12.1194 + * @throws SecurityException if a security manager exists and
12.1195 + * the caller is not permitted to modify threads
12.1196 + * because it does not hold {@link
12.1197 + * java.lang.RuntimePermission}{@code ("modifyThread")}
12.1198 + */
12.1199 + public List<Runnable> shutdownNow() {
12.1200 + checkPermission();
12.1201 + terminate();
12.1202 + return Collections.emptyList();
12.1203 + }
12.1204 +
12.1205 + /**
12.1206 + * Returns {@code true} if all tasks have completed following shut down.
12.1207 + *
12.1208 + * @return {@code true} if all tasks have completed following shut down
12.1209 + */
12.1210 + public boolean isTerminated() {
12.1211 + return runStateOf(runControl) == TERMINATED;
12.1212 + }
12.1213 +
12.1214 + /**
12.1215 + * Returns {@code true} if the process of termination has
12.1216 + * commenced but not yet completed. This method may be useful for
12.1217 + * debugging. A return of {@code true} reported a sufficient
12.1218 + * period after shutdown may indicate that submitted tasks have
12.1219 + * ignored or suppressed interruption, causing this executor not
12.1220 + * to properly terminate.
12.1221 + *
12.1222 + * @return {@code true} if terminating but not yet terminated
12.1223 + */
12.1224 + public boolean isTerminating() {
12.1225 + return runStateOf(runControl) == TERMINATING;
12.1226 + }
12.1227 +
12.1228 + /**
12.1229 + * Returns {@code true} if this pool has been shut down.
12.1230 + *
12.1231 + * @return {@code true} if this pool has been shut down
12.1232 + */
12.1233 + public boolean isShutdown() {
12.1234 + return runStateOf(runControl) >= SHUTDOWN;
12.1235 + }
12.1236 +
12.1237 + /**
12.1238 + * Returns true if pool is not terminating or terminated.
12.1239 + * Used internally to suppress execution when terminating.
12.1240 + */
12.1241 + final boolean isProcessingTasks() {
12.1242 + return runStateOf(runControl) < TERMINATING;
12.1243 + }
12.1244 +
12.1245 + /**
12.1246 + * Blocks until all tasks have completed execution after a shutdown
12.1247 + * request, or the timeout occurs, or the current thread is
12.1248 + * interrupted, whichever happens first.
12.1249 + *
12.1250 + * @param timeout the maximum time to wait
12.1251 + * @param unit the time unit of the timeout argument
12.1252 + * @return {@code true} if this executor terminated and
12.1253 + * {@code false} if the timeout elapsed before termination
12.1254 + * @throws InterruptedException if interrupted while waiting
12.1255 + */
12.1256 + public boolean awaitTermination(long timeout, TimeUnit unit)
12.1257 + throws InterruptedException {
12.1258 + long nanos = unit.toNanos(timeout);
12.1259 + final ReentrantLock lock = this.workerLock;
12.1260 + lock.lock();
12.1261 + try {
12.1262 + for (;;) {
12.1263 + if (isTerminated())
12.1264 + return true;
12.1265 + if (nanos <= 0)
12.1266 + return false;
12.1267 + nanos = termination.awaitNanos(nanos);
12.1268 + }
12.1269 + } finally {
12.1270 + lock.unlock();
12.1271 + }
12.1272 + }
12.1273 +
12.1274 + // Shutdown and termination support
12.1275 +
12.1276 + /**
12.1277 + * Callback from terminating worker. Nulls out the corresponding
12.1278 + * workers slot, and if terminating, tries to terminate; else
12.1279 + * tries to shrink workers array.
12.1280 + *
12.1281 + * @param w the worker
12.1282 + */
12.1283 + final void workerTerminated(ForkJoinWorkerThread w) {
12.1284 + updateStealCount(w);
12.1285 + updateWorkerCount(-1);
12.1286 + final ReentrantLock lock = this.workerLock;
12.1287 + lock.lock();
12.1288 + try {
12.1289 + ForkJoinWorkerThread[] ws = workers;
12.1290 + if (ws != null) {
12.1291 + int idx = w.poolIndex;
12.1292 + if (idx >= 0 && idx < ws.length && ws[idx] == w)
12.1293 + ws[idx] = null;
12.1294 + if (totalCountOf(workerCounts) == 0) {
12.1295 + terminate(); // no-op if already terminating
12.1296 + transitionRunStateTo(TERMINATED);
12.1297 + termination.signalAll();
12.1298 + }
12.1299 + else if (isProcessingTasks()) {
12.1300 + tryShrinkWorkerArray();
12.1301 + tryResumeSpare(true); // allow replacement
12.1302 + }
12.1303 + }
12.1304 + } finally {
12.1305 + lock.unlock();
12.1306 + }
12.1307 + signalIdleWorkers();
12.1308 + }
12.1309 +
12.1310 + /**
12.1311 + * Initiates termination.
12.1312 + */
12.1313 + private void terminate() {
12.1314 + if (transitionRunStateTo(TERMINATING)) {
12.1315 + stopAllWorkers();
12.1316 + resumeAllSpares();
12.1317 + signalIdleWorkers();
12.1318 + cancelQueuedSubmissions();
12.1319 + cancelQueuedWorkerTasks();
12.1320 + interruptUnterminatedWorkers();
12.1321 + signalIdleWorkers(); // resignal after interrupt
12.1322 + }
12.1323 + }
12.1324 +
12.1325 + /**
12.1326 + * Possibly terminates when on shutdown state.
12.1327 + */
12.1328 + private void terminateOnShutdown() {
12.1329 + if (!hasQueuedSubmissions() && canTerminateOnShutdown(runControl))
12.1330 + terminate();
12.1331 + }
12.1332 +
12.1333 + /**
12.1334 + * Clears out and cancels submissions.
12.1335 + */
12.1336 + private void cancelQueuedSubmissions() {
12.1337 + ForkJoinTask<?> task;
12.1338 + while ((task = pollSubmission()) != null)
12.1339 + task.cancel(false);
12.1340 + }
12.1341 +
12.1342 + /**
12.1343 + * Cleans out worker queues.
12.1344 + */
12.1345 + private void cancelQueuedWorkerTasks() {
12.1346 + final ReentrantLock lock = this.workerLock;
12.1347 + lock.lock();
12.1348 + try {
12.1349 + ForkJoinWorkerThread[] ws = workers;
12.1350 + if (ws != null) {
12.1351 + for (int i = 0; i < ws.length; ++i) {
12.1352 + ForkJoinWorkerThread t = ws[i];
12.1353 + if (t != null)
12.1354 + t.cancelTasks();
12.1355 + }
12.1356 + }
12.1357 + } finally {
12.1358 + lock.unlock();
12.1359 + }
12.1360 + }
12.1361 +
12.1362 + /**
12.1363 + * Sets each worker's status to terminating. Requires lock to avoid
12.1364 + * conflicts with add/remove.
12.1365 + */
12.1366 + private void stopAllWorkers() {
12.1367 + final ReentrantLock lock = this.workerLock;
12.1368 + lock.lock();
12.1369 + try {
12.1370 + ForkJoinWorkerThread[] ws = workers;
12.1371 + if (ws != null) {
12.1372 + for (int i = 0; i < ws.length; ++i) {
12.1373 + ForkJoinWorkerThread t = ws[i];
12.1374 + if (t != null)
12.1375 + t.shutdownNow();
12.1376 + }
12.1377 + }
12.1378 + } finally {
12.1379 + lock.unlock();
12.1380 + }
12.1381 + }
12.1382 +
12.1383 + /**
12.1384 + * Interrupts all unterminated workers. This is not required for
12.1385 + * sake of internal control, but may help unstick user code during
12.1386 + * shutdown.
12.1387 + */
12.1388 + private void interruptUnterminatedWorkers() {
12.1389 + final ReentrantLock lock = this.workerLock;
12.1390 + lock.lock();
12.1391 + try {
12.1392 + ForkJoinWorkerThread[] ws = workers;
12.1393 + if (ws != null) {
12.1394 + for (int i = 0; i < ws.length; ++i) {
12.1395 + ForkJoinWorkerThread t = ws[i];
12.1396 + if (t != null && !t.isTerminated()) {
12.1397 + try {
12.1398 + t.interrupt();
12.1399 + } catch (SecurityException ignore) {
12.1400 + }
12.1401 + }
12.1402 + }
12.1403 + }
12.1404 + } finally {
12.1405 + lock.unlock();
12.1406 + }
12.1407 + }
12.1408 +
12.1409 +
12.1410 + /*
12.1411 + * Nodes for event barrier to manage idle threads. Queue nodes
12.1412 + * are basic Treiber stack nodes, also used for spare stack.
12.1413 + *
12.1414 + * The event barrier has an event count and a wait queue (actually
12.1415 + * a Treiber stack). Workers are enabled to look for work when
12.1416 + * the eventCount is incremented. If they fail to find work, they
12.1417 + * may wait for next count. Upon release, threads help others wake
12.1418 + * up.
12.1419 + *
12.1420 + * Synchronization events occur only in enough contexts to
12.1421 + * maintain overall liveness:
12.1422 + *
12.1423 + * - Submission of a new task to the pool
12.1424 + * - Resizes or other changes to the workers array
12.1425 + * - pool termination
12.1426 + * - A worker pushing a task on an empty queue
12.1427 + *
12.1428 + * The case of pushing a task occurs often enough, and is heavy
12.1429 + * enough compared to simple stack pushes, to require special
12.1430 + * handling: Method signalWork returns without advancing count if
12.1431 + * the queue appears to be empty. This would ordinarily result in
12.1432 + * races causing some queued waiters not to be woken up. To avoid
12.1433 + * this, the first worker enqueued in method sync (see
12.1434 + * syncIsReleasable) rescans for tasks after being enqueued, and
12.1435 + * helps signal if any are found. This works well because the
12.1436 + * worker has nothing better to do, and so might as well help
12.1437 + * alleviate the overhead and contention on the threads actually
12.1438 + * doing work. Also, since event counts increments on task
12.1439 + * availability exist to maintain liveness (rather than to force
12.1440 + * refreshes etc), it is OK for callers to exit early if
12.1441 + * contending with another signaller.
12.1442 + */
12.1443 + static final class WaitQueueNode {
12.1444 + WaitQueueNode next; // only written before enqueued
12.1445 + volatile ForkJoinWorkerThread thread; // nulled to cancel wait
12.1446 + final long count; // unused for spare stack
12.1447 +
12.1448 + WaitQueueNode(long c, ForkJoinWorkerThread w) {
12.1449 + count = c;
12.1450 + thread = w;
12.1451 + }
12.1452 +
12.1453 + /**
12.1454 + * Wakes up waiter, returning false if known to already
12.1455 + */
12.1456 + boolean signal() {
12.1457 + ForkJoinWorkerThread t = thread;
12.1458 + if (t == null)
12.1459 + return false;
12.1460 + thread = null;
12.1461 + LockSupport.unpark(t);
12.1462 + return true;
12.1463 + }
12.1464 +
12.1465 + /**
12.1466 + * Awaits release on sync.
12.1467 + */
12.1468 + void awaitSyncRelease(ForkJoinPool p) {
12.1469 + while (thread != null && !p.syncIsReleasable(this))
12.1470 + LockSupport.park(this);
12.1471 + }
12.1472 +
12.1473 + /**
12.1474 + * Awaits resumption as spare.
12.1475 + */
12.1476 + void awaitSpareRelease() {
12.1477 + while (thread != null) {
12.1478 + if (!Thread.interrupted())
12.1479 + LockSupport.park(this);
12.1480 + }
12.1481 + }
12.1482 + }
12.1483 +
12.1484 + /**
12.1485 + * Ensures that no thread is waiting for count to advance from the
12.1486 + * current value of eventCount read on entry to this method, by
12.1487 + * releasing waiting threads if necessary.
12.1488 + *
12.1489 + * @return the count
12.1490 + */
12.1491 + final long ensureSync() {
12.1492 + long c = eventCount;
12.1493 + WaitQueueNode q;
12.1494 + while ((q = syncStack) != null && q.count < c) {
12.1495 + if (casBarrierStack(q, null)) {
12.1496 + do {
12.1497 + q.signal();
12.1498 + } while ((q = q.next) != null);
12.1499 + break;
12.1500 + }
12.1501 + }
12.1502 + return c;
12.1503 + }
12.1504 +
12.1505 + /**
12.1506 + * Increments event count and releases waiting threads.
12.1507 + */
12.1508 + private void signalIdleWorkers() {
12.1509 + long c;
12.1510 + do {} while (!casEventCount(c = eventCount, c+1));
12.1511 + ensureSync();
12.1512 + }
12.1513 +
12.1514 + /**
12.1515 + * Signals threads waiting to poll a task. Because method sync
12.1516 + * rechecks availability, it is OK to only proceed if queue
12.1517 + * appears to be non-empty, and OK to skip under contention to
12.1518 + * increment count (since some other thread succeeded).
12.1519 + */
12.1520 + final void signalWork() {
12.1521 + long c;
12.1522 + WaitQueueNode q;
12.1523 + if (syncStack != null &&
12.1524 + casEventCount(c = eventCount, c+1) &&
12.1525 + (((q = syncStack) != null && q.count <= c) &&
12.1526 + (!casBarrierStack(q, q.next) || !q.signal())))
12.1527 + ensureSync();
12.1528 + }
12.1529 +
12.1530 + /**
12.1531 + * Waits until event count advances from last value held by
12.1532 + * caller, or if excess threads, caller is resumed as spare, or
12.1533 + * caller or pool is terminating. Updates caller's event on exit.
12.1534 + *
12.1535 + * @param w the calling worker thread
12.1536 + */
12.1537 + final void sync(ForkJoinWorkerThread w) {
12.1538 + updateStealCount(w); // Transfer w's count while it is idle
12.1539 +
12.1540 + while (!w.isShutdown() && isProcessingTasks() && !suspendIfSpare(w)) {
12.1541 + long prev = w.lastEventCount;
12.1542 + WaitQueueNode node = null;
12.1543 + WaitQueueNode h;
12.1544 + while (eventCount == prev &&
12.1545 + ((h = syncStack) == null || h.count == prev)) {
12.1546 + if (node == null)
12.1547 + node = new WaitQueueNode(prev, w);
12.1548 + if (casBarrierStack(node.next = h, node)) {
12.1549 + node.awaitSyncRelease(this);
12.1550 + break;
12.1551 + }
12.1552 + }
12.1553 + long ec = ensureSync();
12.1554 + if (ec != prev) {
12.1555 + w.lastEventCount = ec;
12.1556 + break;
12.1557 + }
12.1558 + }
12.1559 + }
12.1560 +
12.1561 + /**
12.1562 + * Returns {@code true} if worker waiting on sync can proceed:
12.1563 + * - on signal (thread == null)
12.1564 + * - on event count advance (winning race to notify vs signaller)
12.1565 + * - on interrupt
12.1566 + * - if the first queued node, we find work available
12.1567 + * If node was not signalled and event count not advanced on exit,
12.1568 + * then we also help advance event count.
12.1569 + *
12.1570 + * @return {@code true} if node can be released
12.1571 + */
12.1572 + final boolean syncIsReleasable(WaitQueueNode node) {
12.1573 + long prev = node.count;
12.1574 + if (!Thread.interrupted() && node.thread != null &&
12.1575 + (node.next != null ||
12.1576 + !ForkJoinWorkerThread.hasQueuedTasks(workers)) &&
12.1577 + eventCount == prev)
12.1578 + return false;
12.1579 + if (node.thread != null) {
12.1580 + node.thread = null;
12.1581 + long ec = eventCount;
12.1582 + if (prev <= ec) // help signal
12.1583 + casEventCount(ec, ec+1);
12.1584 + }
12.1585 + return true;
12.1586 + }
12.1587 +
12.1588 + /**
12.1589 + * Returns {@code true} if a new sync event occurred since last
12.1590 + * call to sync or this method, if so, updating caller's count.
12.1591 + */
12.1592 + final boolean hasNewSyncEvent(ForkJoinWorkerThread w) {
12.1593 + long lc = w.lastEventCount;
12.1594 + long ec = ensureSync();
12.1595 + if (ec == lc)
12.1596 + return false;
12.1597 + w.lastEventCount = ec;
12.1598 + return true;
12.1599 + }
12.1600 +
12.1601 + // Parallelism maintenance
12.1602 +
12.1603 + /**
12.1604 + * Decrements running count; if too low, adds spare.
12.1605 + *
12.1606 + * Conceptually, all we need to do here is add or resume a
12.1607 + * spare thread when one is about to block (and remove or
12.1608 + * suspend it later when unblocked -- see suspendIfSpare).
12.1609 + * However, implementing this idea requires coping with
12.1610 + * several problems: we have imperfect information about the
12.1611 + * states of threads. Some count updates can and usually do
12.1612 + * lag run state changes, despite arrangements to keep them
12.1613 + * accurate (for example, when possible, updating counts
12.1614 + * before signalling or resuming), especially when running on
12.1615 + * dynamic JVMs that don't optimize the infrequent paths that
12.1616 + * update counts. Generating too many threads can make these
12.1617 + * problems become worse, because excess threads are more
12.1618 + * likely to be context-switched with others, slowing them all
12.1619 + * down, especially if there is no work available, so all are
12.1620 + * busy scanning or idling. Also, excess spare threads can
12.1621 + * only be suspended or removed when they are idle, not
12.1622 + * immediately when they aren't needed. So adding threads will
12.1623 + * raise parallelism level for longer than necessary. Also,
12.1624 + * FJ applications often encounter highly transient peaks when
12.1625 + * many threads are blocked joining, but for less time than it
12.1626 + * takes to create or resume spares.
12.1627 + *
12.1628 + * @param joinMe if non-null, return early if done
12.1629 + * @param maintainParallelism if true, try to stay within
12.1630 + * target counts, else create only to avoid starvation
12.1631 + * @return true if joinMe known to be done
12.1632 + */
12.1633 + final boolean preJoin(ForkJoinTask<?> joinMe,
12.1634 + boolean maintainParallelism) {
12.1635 + maintainParallelism &= maintainsParallelism; // overrride
12.1636 + boolean dec = false; // true when running count decremented
12.1637 + while (spareStack == null || !tryResumeSpare(dec)) {
12.1638 + int counts = workerCounts;
12.1639 + if (dec || (dec = casWorkerCounts(counts, --counts))) {
12.1640 + if (!needSpare(counts, maintainParallelism))
12.1641 + break;
12.1642 + if (joinMe.status < 0)
12.1643 + return true;
12.1644 + if (tryAddSpare(counts))
12.1645 + break;
12.1646 + }
12.1647 + }
12.1648 + return false;
12.1649 + }
12.1650 +
12.1651 + /**
12.1652 + * Same idea as preJoin
12.1653 + */
12.1654 + final boolean preBlock(ManagedBlocker blocker,
12.1655 + boolean maintainParallelism) {
12.1656 + maintainParallelism &= maintainsParallelism;
12.1657 + boolean dec = false;
12.1658 + while (spareStack == null || !tryResumeSpare(dec)) {
12.1659 + int counts = workerCounts;
12.1660 + if (dec || (dec = casWorkerCounts(counts, --counts))) {
12.1661 + if (!needSpare(counts, maintainParallelism))
12.1662 + break;
12.1663 + if (blocker.isReleasable())
12.1664 + return true;
12.1665 + if (tryAddSpare(counts))
12.1666 + break;
12.1667 + }
12.1668 + }
12.1669 + return false;
12.1670 + }
12.1671 +
12.1672 + /**
12.1673 + * Returns {@code true} if a spare thread appears to be needed.
12.1674 + * If maintaining parallelism, returns true when the deficit in
12.1675 + * running threads is more than the surplus of total threads, and
12.1676 + * there is apparently some work to do. This self-limiting rule
12.1677 + * means that the more threads that have already been added, the
12.1678 + * less parallelism we will tolerate before adding another.
12.1679 + *
12.1680 + * @param counts current worker counts
12.1681 + * @param maintainParallelism try to maintain parallelism
12.1682 + */
12.1683 + private boolean needSpare(int counts, boolean maintainParallelism) {
12.1684 + int ps = parallelism;
12.1685 + int rc = runningCountOf(counts);
12.1686 + int tc = totalCountOf(counts);
12.1687 + int runningDeficit = ps - rc;
12.1688 + int totalSurplus = tc - ps;
12.1689 + return (tc < maxPoolSize &&
12.1690 + (rc == 0 || totalSurplus < 0 ||
12.1691 + (maintainParallelism &&
12.1692 + runningDeficit > totalSurplus &&
12.1693 + ForkJoinWorkerThread.hasQueuedTasks(workers))));
12.1694 + }
12.1695 +
12.1696 + /**
12.1697 + * Adds a spare worker if lock available and no more than the
12.1698 + * expected numbers of threads exist.
12.1699 + *
12.1700 + * @return true if successful
12.1701 + */
12.1702 + private boolean tryAddSpare(int expectedCounts) {
12.1703 + final ReentrantLock lock = this.workerLock;
12.1704 + int expectedRunning = runningCountOf(expectedCounts);
12.1705 + int expectedTotal = totalCountOf(expectedCounts);
12.1706 + boolean success = false;
12.1707 + boolean locked = false;
12.1708 + // confirm counts while locking; CAS after obtaining lock
12.1709 + try {
12.1710 + for (;;) {
12.1711 + int s = workerCounts;
12.1712 + int tc = totalCountOf(s);
12.1713 + int rc = runningCountOf(s);
12.1714 + if (rc > expectedRunning || tc > expectedTotal)
12.1715 + break;
12.1716 + if (!locked && !(locked = lock.tryLock()))
12.1717 + break;
12.1718 + if (casWorkerCounts(s, workerCountsFor(tc+1, rc+1))) {
12.1719 + createAndStartSpare(tc);
12.1720 + success = true;
12.1721 + break;
12.1722 + }
12.1723 + }
12.1724 + } finally {
12.1725 + if (locked)
12.1726 + lock.unlock();
12.1727 + }
12.1728 + return success;
12.1729 + }
12.1730 +
12.1731 + /**
12.1732 + * Adds the kth spare worker. On entry, pool counts are already
12.1733 + * adjusted to reflect addition.
12.1734 + */
12.1735 + private void createAndStartSpare(int k) {
12.1736 + ForkJoinWorkerThread w = null;
12.1737 + ForkJoinWorkerThread[] ws = ensureWorkerArrayCapacity(k + 1);
12.1738 + int len = ws.length;
12.1739 + // Probably, we can place at slot k. If not, find empty slot
12.1740 + if (k < len && ws[k] != null) {
12.1741 + for (k = 0; k < len && ws[k] != null; ++k)
12.1742 + ;
12.1743 + }
12.1744 + if (k < len && isProcessingTasks() && (w = createWorker(k)) != null) {
12.1745 + ws[k] = w;
12.1746 + w.start();
12.1747 + }
12.1748 + else
12.1749 + updateWorkerCount(-1); // adjust on failure
12.1750 + signalIdleWorkers();
12.1751 + }
12.1752 +
12.1753 + /**
12.1754 + * Suspends calling thread w if there are excess threads. Called
12.1755 + * only from sync. Spares are enqueued in a Treiber stack using
12.1756 + * the same WaitQueueNodes as barriers. They are resumed mainly
12.1757 + * in preJoin, but are also woken on pool events that require all
12.1758 + * threads to check run state.
12.1759 + *
12.1760 + * @param w the caller
12.1761 + */
12.1762 + private boolean suspendIfSpare(ForkJoinWorkerThread w) {
12.1763 + WaitQueueNode node = null;
12.1764 + int s;
12.1765 + while (parallelism < runningCountOf(s = workerCounts)) {
12.1766 + if (node == null)
12.1767 + node = new WaitQueueNode(0, w);
12.1768 + if (casWorkerCounts(s, s-1)) { // representation-dependent
12.1769 + // push onto stack
12.1770 + do {} while (!casSpareStack(node.next = spareStack, node));
12.1771 + // block until released by resumeSpare
12.1772 + node.awaitSpareRelease();
12.1773 + return true;
12.1774 + }
12.1775 + }
12.1776 + return false;
12.1777 + }
12.1778 +
12.1779 + /**
12.1780 + * Tries to pop and resume a spare thread.
12.1781 + *
12.1782 + * @param updateCount if true, increment running count on success
12.1783 + * @return true if successful
12.1784 + */
12.1785 + private boolean tryResumeSpare(boolean updateCount) {
12.1786 + WaitQueueNode q;
12.1787 + while ((q = spareStack) != null) {
12.1788 + if (casSpareStack(q, q.next)) {
12.1789 + if (updateCount)
12.1790 + updateRunningCount(1);
12.1791 + q.signal();
12.1792 + return true;
12.1793 + }
12.1794 + }
12.1795 + return false;
12.1796 + }
12.1797 +
12.1798 + /**
12.1799 + * Pops and resumes all spare threads. Same idea as ensureSync.
12.1800 + *
12.1801 + * @return true if any spares released
12.1802 + */
12.1803 + private boolean resumeAllSpares() {
12.1804 + WaitQueueNode q;
12.1805 + while ( (q = spareStack) != null) {
12.1806 + if (casSpareStack(q, null)) {
12.1807 + do {
12.1808 + updateRunningCount(1);
12.1809 + q.signal();
12.1810 + } while ((q = q.next) != null);
12.1811 + return true;
12.1812 + }
12.1813 + }
12.1814 + return false;
12.1815 + }
12.1816 +
12.1817 + /**
12.1818 + * Pops and shuts down excessive spare threads. Call only while
12.1819 + * holding lock. This is not guaranteed to eliminate all excess
12.1820 + * threads, only those suspended as spares, which are the ones
12.1821 + * unlikely to be needed in the future.
12.1822 + */
12.1823 + private void trimSpares() {
12.1824 + int surplus = totalCountOf(workerCounts) - parallelism;
12.1825 + WaitQueueNode q;
12.1826 + while (surplus > 0 && (q = spareStack) != null) {
12.1827 + if (casSpareStack(q, null)) {
12.1828 + do {
12.1829 + updateRunningCount(1);
12.1830 + ForkJoinWorkerThread w = q.thread;
12.1831 + if (w != null && surplus > 0 &&
12.1832 + runningCountOf(workerCounts) > 0 && w.shutdown())
12.1833 + --surplus;
12.1834 + q.signal();
12.1835 + } while ((q = q.next) != null);
12.1836 + }
12.1837 + }
12.1838 + }
12.1839 +
12.1840 + /**
12.1841 + * Interface for extending managed parallelism for tasks running
12.1842 + * in {@link ForkJoinPool}s.
12.1843 + *
12.1844 + * <p>A {@code ManagedBlocker} provides two methods.
12.1845 + * Method {@code isReleasable} must return {@code true} if
12.1846 + * blocking is not necessary. Method {@code block} blocks the
12.1847 + * current thread if necessary (perhaps internally invoking
12.1848 + * {@code isReleasable} before actually blocking).
12.1849 + *
12.1850 + * <p>For example, here is a ManagedBlocker based on a
12.1851 + * ReentrantLock:
12.1852 + * <pre> {@code
12.1853 + * class ManagedLocker implements ManagedBlocker {
12.1854 + * final ReentrantLock lock;
12.1855 + * boolean hasLock = false;
12.1856 + * ManagedLocker(ReentrantLock lock) { this.lock = lock; }
12.1857 + * public boolean block() {
12.1858 + * if (!hasLock)
12.1859 + * lock.lock();
12.1860 + * return true;
12.1861 + * }
12.1862 + * public boolean isReleasable() {
12.1863 + * return hasLock || (hasLock = lock.tryLock());
12.1864 + * }
12.1865 + * }}</pre>
12.1866 + */
12.1867 + public static interface ManagedBlocker {
12.1868 + /**
12.1869 + * Possibly blocks the current thread, for example waiting for
12.1870 + * a lock or condition.
12.1871 + *
12.1872 + * @return {@code true} if no additional blocking is necessary
12.1873 + * (i.e., if isReleasable would return true)
12.1874 + * @throws InterruptedException if interrupted while waiting
12.1875 + * (the method is not required to do so, but is allowed to)
12.1876 + */
12.1877 + boolean block() throws InterruptedException;
12.1878 +
12.1879 + /**
12.1880 + * Returns {@code true} if blocking is unnecessary.
12.1881 + */
12.1882 + boolean isReleasable();
12.1883 + }
12.1884 +
12.1885 + /**
12.1886 + * Blocks in accord with the given blocker. If the current thread
12.1887 + * is a {@link ForkJoinWorkerThread}, this method possibly
12.1888 + * arranges for a spare thread to be activated if necessary to
12.1889 + * ensure parallelism while the current thread is blocked.
12.1890 + *
12.1891 + * <p>If {@code maintainParallelism} is {@code true} and the pool
12.1892 + * supports it ({@link #getMaintainsParallelism}), this method
12.1893 + * attempts to maintain the pool's nominal parallelism. Otherwise
12.1894 + * it activates a thread only if necessary to avoid complete
12.1895 + * starvation. This option may be preferable when blockages use
12.1896 + * timeouts, or are almost always brief.
12.1897 + *
12.1898 + * <p>If the caller is not a {@link ForkJoinTask}, this method is
12.1899 + * behaviorally equivalent to
12.1900 + * <pre> {@code
12.1901 + * while (!blocker.isReleasable())
12.1902 + * if (blocker.block())
12.1903 + * return;
12.1904 + * }</pre>
12.1905 + *
12.1906 + * If the caller is a {@code ForkJoinTask}, then the pool may
12.1907 + * first be expanded to ensure parallelism, and later adjusted.
12.1908 + *
12.1909 + * @param blocker the blocker
12.1910 + * @param maintainParallelism if {@code true} and supported by
12.1911 + * this pool, attempt to maintain the pool's nominal parallelism;
12.1912 + * otherwise activate a thread only if necessary to avoid
12.1913 + * complete starvation.
12.1914 + * @throws InterruptedException if blocker.block did so
12.1915 + */
12.1916 + public static void managedBlock(ManagedBlocker blocker,
12.1917 + boolean maintainParallelism)
12.1918 + throws InterruptedException {
12.1919 + Thread t = Thread.currentThread();
12.1920 + ForkJoinPool pool = ((t instanceof ForkJoinWorkerThread) ?
12.1921 + ((ForkJoinWorkerThread) t).pool : null);
12.1922 + if (!blocker.isReleasable()) {
12.1923 + try {
12.1924 + if (pool == null ||
12.1925 + !pool.preBlock(blocker, maintainParallelism))
12.1926 + awaitBlocker(blocker);
12.1927 + } finally {
12.1928 + if (pool != null)
12.1929 + pool.updateRunningCount(1);
12.1930 + }
12.1931 + }
12.1932 + }
12.1933 +
12.1934 + private static void awaitBlocker(ManagedBlocker blocker)
12.1935 + throws InterruptedException {
12.1936 + do {} while (!blocker.isReleasable() && !blocker.block());
12.1937 + }
12.1938 +
12.1939 + // AbstractExecutorService overrides. These rely on undocumented
12.1940 + // fact that ForkJoinTask.adapt returns ForkJoinTasks that also
12.1941 + // implement RunnableFuture.
12.1942 +
12.1943 + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
12.1944 + return (RunnableFuture<T>) ForkJoinTask.adapt(runnable, value);
12.1945 + }
12.1946 +
12.1947 + protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
12.1948 + return (RunnableFuture<T>) ForkJoinTask.adapt(callable);
12.1949 + }
12.1950 +
12.1951 + // Unsafe mechanics
12.1952 +
12.1953 + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
12.1954 + private static final long eventCountOffset =
12.1955 + objectFieldOffset("eventCount", ForkJoinPool.class);
12.1956 + private static final long workerCountsOffset =
12.1957 + objectFieldOffset("workerCounts", ForkJoinPool.class);
12.1958 + private static final long runControlOffset =
12.1959 + objectFieldOffset("runControl", ForkJoinPool.class);
12.1960 + private static final long syncStackOffset =
12.1961 + objectFieldOffset("syncStack",ForkJoinPool.class);
12.1962 + private static final long spareStackOffset =
12.1963 + objectFieldOffset("spareStack", ForkJoinPool.class);
12.1964 +
12.1965 + private boolean casEventCount(long cmp, long val) {
12.1966 + return UNSAFE.compareAndSwapLong(this, eventCountOffset, cmp, val);
12.1967 + }
12.1968 + private boolean casWorkerCounts(int cmp, int val) {
12.1969 + return UNSAFE.compareAndSwapInt(this, workerCountsOffset, cmp, val);
12.1970 + }
12.1971 + private boolean casRunControl(int cmp, int val) {
12.1972 + return UNSAFE.compareAndSwapInt(this, runControlOffset, cmp, val);
12.1973 + }
12.1974 + private boolean casSpareStack(WaitQueueNode cmp, WaitQueueNode val) {
12.1975 + return UNSAFE.compareAndSwapObject(this, spareStackOffset, cmp, val);
12.1976 + }
12.1977 + private boolean casBarrierStack(WaitQueueNode cmp, WaitQueueNode val) {
12.1978 + return UNSAFE.compareAndSwapObject(this, syncStackOffset, cmp, val);
12.1979 + }
12.1980 +
12.1981 + private static long objectFieldOffset(String field, Class<?> klazz) {
12.1982 + try {
12.1983 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
12.1984 + } catch (NoSuchFieldException e) {
12.1985 + // Convert Exception to corresponding Error
12.1986 + NoSuchFieldError error = new NoSuchFieldError(field);
12.1987 + error.initCause(e);
12.1988 + throw error;
12.1989 + }
12.1990 + }
12.1991 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java Sun Nov 08 14:49:18 2009 -0800
13.3 @@ -0,0 +1,1292 @@
13.4 +/*
13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.6 + *
13.7 + * This code is free software; you can redistribute it and/or modify it
13.8 + * under the terms of the GNU General Public License version 2 only, as
13.9 + * published by the Free Software Foundation. Sun designates this
13.10 + * particular file as subject to the "Classpath" exception as provided
13.11 + * by Sun in the LICENSE file that accompanied this code.
13.12 + *
13.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
13.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.16 + * version 2 for more details (a copy is included in the LICENSE file that
13.17 + * accompanied this code).
13.18 + *
13.19 + * You should have received a copy of the GNU General Public License version
13.20 + * 2 along with this work; if not, write to the Free Software Foundation,
13.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.22 + *
13.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
13.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
13.25 + * have any questions.
13.26 + */
13.27 +
13.28 +/*
13.29 + * This file is available under and governed by the GNU General Public
13.30 + * License version 2 only, as published by the Free Software Foundation.
13.31 + * However, the following notice accompanied the original version of this
13.32 + * file:
13.33 + *
13.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
13.35 + * Expert Group and released to the public domain, as explained at
13.36 + * http://creativecommons.org/licenses/publicdomain
13.37 + */
13.38 +
13.39 +package java.util.concurrent;
13.40 +
13.41 +import java.io.Serializable;
13.42 +import java.util.Collection;
13.43 +import java.util.Collections;
13.44 +import java.util.List;
13.45 +import java.util.RandomAccess;
13.46 +import java.util.Map;
13.47 +import java.util.WeakHashMap;
13.48 +
13.49 +/**
13.50 + * Abstract base class for tasks that run within a {@link ForkJoinPool}.
13.51 + * A {@code ForkJoinTask} is a thread-like entity that is much
13.52 + * lighter weight than a normal thread. Huge numbers of tasks and
13.53 + * subtasks may be hosted by a small number of actual threads in a
13.54 + * ForkJoinPool, at the price of some usage limitations.
13.55 + *
13.56 + * <p>A "main" {@code ForkJoinTask} begins execution when submitted
13.57 + * to a {@link ForkJoinPool}. Once started, it will usually in turn
13.58 + * start other subtasks. As indicated by the name of this class,
13.59 + * many programs using {@code ForkJoinTask} employ only methods
13.60 + * {@link #fork} and {@link #join}, or derivatives such as {@link
13.61 + * #invokeAll}. However, this class also provides a number of other
13.62 + * methods that can come into play in advanced usages, as well as
13.63 + * extension mechanics that allow support of new forms of fork/join
13.64 + * processing.
13.65 + *
13.66 + * <p>A {@code ForkJoinTask} is a lightweight form of {@link Future}.
13.67 + * The efficiency of {@code ForkJoinTask}s stems from a set of
13.68 + * restrictions (that are only partially statically enforceable)
13.69 + * reflecting their intended use as computational tasks calculating
13.70 + * pure functions or operating on purely isolated objects. The
13.71 + * primary coordination mechanisms are {@link #fork}, that arranges
13.72 + * asynchronous execution, and {@link #join}, that doesn't proceed
13.73 + * until the task's result has been computed. Computations should
13.74 + * avoid {@code synchronized} methods or blocks, and should minimize
13.75 + * other blocking synchronization apart from joining other tasks or
13.76 + * using synchronizers such as Phasers that are advertised to
13.77 + * cooperate with fork/join scheduling. Tasks should also not perform
13.78 + * blocking IO, and should ideally access variables that are
13.79 + * completely independent of those accessed by other running
13.80 + * tasks. Minor breaches of these restrictions, for example using
13.81 + * shared output streams, may be tolerable in practice, but frequent
13.82 + * use may result in poor performance, and the potential to
13.83 + * indefinitely stall if the number of threads not waiting for IO or
13.84 + * other external synchronization becomes exhausted. This usage
13.85 + * restriction is in part enforced by not permitting checked
13.86 + * exceptions such as {@code IOExceptions} to be thrown. However,
13.87 + * computations may still encounter unchecked exceptions, that are
13.88 + * rethrown to callers attempting to join them. These exceptions may
13.89 + * additionally include {@link RejectedExecutionException} stemming
13.90 + * from internal resource exhaustion, such as failure to allocate
13.91 + * internal task queues.
13.92 + *
13.93 + * <p>The primary method for awaiting completion and extracting
13.94 + * results of a task is {@link #join}, but there are several variants:
13.95 + * The {@link Future#get} methods support interruptible and/or timed
13.96 + * waits for completion and report results using {@code Future}
13.97 + * conventions. Method {@link #helpJoin} enables callers to actively
13.98 + * execute other tasks while awaiting joins, which is sometimes more
13.99 + * efficient but only applies when all subtasks are known to be
13.100 + * strictly tree-structured. Method {@link #invoke} is semantically
13.101 + * equivalent to {@code fork(); join()} but always attempts to begin
13.102 + * execution in the current thread. The "<em>quiet</em>" forms of
13.103 + * these methods do not extract results or report exceptions. These
13.104 + * may be useful when a set of tasks are being executed, and you need
13.105 + * to delay processing of results or exceptions until all complete.
13.106 + * Method {@code invokeAll} (available in multiple versions)
13.107 + * performs the most common form of parallel invocation: forking a set
13.108 + * of tasks and joining them all.
13.109 + *
13.110 + * <p>The execution status of tasks may be queried at several levels
13.111 + * of detail: {@link #isDone} is true if a task completed in any way
13.112 + * (including the case where a task was cancelled without executing);
13.113 + * {@link #isCompletedNormally} is true if a task completed without
13.114 + * cancellation or encountering an exception; {@link #isCancelled} is
13.115 + * true if the task was cancelled (in which case {@link #getException}
13.116 + * returns a {@link java.util.concurrent.CancellationException}); and
13.117 + * {@link #isCompletedAbnormally} is true if a task was either
13.118 + * cancelled or encountered an exception, in which case {@link
13.119 + * #getException} will return either the encountered exception or
13.120 + * {@link java.util.concurrent.CancellationException}.
13.121 + *
13.122 + * <p>The ForkJoinTask class is not usually directly subclassed.
13.123 + * Instead, you subclass one of the abstract classes that support a
13.124 + * particular style of fork/join processing, typically {@link
13.125 + * RecursiveAction} for computations that do not return results, or
13.126 + * {@link RecursiveTask} for those that do. Normally, a concrete
13.127 + * ForkJoinTask subclass declares fields comprising its parameters,
13.128 + * established in a constructor, and then defines a {@code compute}
13.129 + * method that somehow uses the control methods supplied by this base
13.130 + * class. While these methods have {@code public} access (to allow
13.131 + * instances of different task subclasses to call each other's
13.132 + * methods), some of them may only be called from within other
13.133 + * ForkJoinTasks (as may be determined using method {@link
13.134 + * #inForkJoinPool}). Attempts to invoke them in other contexts
13.135 + * result in exceptions or errors, possibly including
13.136 + * ClassCastException.
13.137 + *
13.138 + * <p>Most base support methods are {@code final}, to prevent
13.139 + * overriding of implementations that are intrinsically tied to the
13.140 + * underlying lightweight task scheduling framework. Developers
13.141 + * creating new basic styles of fork/join processing should minimally
13.142 + * implement {@code protected} methods {@link #exec}, {@link
13.143 + * #setRawResult}, and {@link #getRawResult}, while also introducing
13.144 + * an abstract computational method that can be implemented in its
13.145 + * subclasses, possibly relying on other {@code protected} methods
13.146 + * provided by this class.
13.147 + *
13.148 + * <p>ForkJoinTasks should perform relatively small amounts of
13.149 + * computation. Large tasks should be split into smaller subtasks,
13.150 + * usually via recursive decomposition. As a very rough rule of thumb,
13.151 + * a task should perform more than 100 and less than 10000 basic
13.152 + * computational steps. If tasks are too big, then parallelism cannot
13.153 + * improve throughput. If too small, then memory and internal task
13.154 + * maintenance overhead may overwhelm processing.
13.155 + *
13.156 + * <p>This class provides {@code adapt} methods for {@link Runnable}
13.157 + * and {@link Callable}, that may be of use when mixing execution of
13.158 + * {@code ForkJoinTasks} with other kinds of tasks. When all tasks
13.159 + * are of this form, consider using a pool in
13.160 + * {@linkplain ForkJoinPool#setAsyncMode async mode}.
13.161 + *
13.162 + * <p>ForkJoinTasks are {@code Serializable}, which enables them to be
13.163 + * used in extensions such as remote execution frameworks. It is
13.164 + * sensible to serialize tasks only before or after, but not during,
13.165 + * execution. Serialization is not relied on during execution itself.
13.166 + *
13.167 + * @since 1.7
13.168 + * @author Doug Lea
13.169 + */
13.170 +public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
13.171 +
13.172 + /**
13.173 + * Run control status bits packed into a single int to minimize
13.174 + * footprint and to ensure atomicity (via CAS). Status is
13.175 + * initially zero, and takes on nonnegative values until
13.176 + * completed, upon which status holds COMPLETED. CANCELLED, or
13.177 + * EXCEPTIONAL, which use the top 3 bits. Tasks undergoing
13.178 + * blocking waits by other threads have SIGNAL_MASK bits set --
13.179 + * bit 15 for external (nonFJ) waits, and the rest a count of
13.180 + * waiting FJ threads. (This representation relies on
13.181 + * ForkJoinPool max thread limits). Completion of a stolen task
13.182 + * with SIGNAL_MASK bits set awakens waiter via notifyAll. Even
13.183 + * though suboptimal for some purposes, we use basic builtin
13.184 + * wait/notify to take advantage of "monitor inflation" in JVMs
13.185 + * that we would otherwise need to emulate to avoid adding further
13.186 + * per-task bookkeeping overhead. Note that bits 16-28 are
13.187 + * currently unused. Also value 0x80000000 is available as spare
13.188 + * completion value.
13.189 + */
13.190 + volatile int status; // accessed directly by pool and workers
13.191 +
13.192 + static final int COMPLETION_MASK = 0xe0000000;
13.193 + static final int NORMAL = 0xe0000000; // == mask
13.194 + static final int CANCELLED = 0xc0000000;
13.195 + static final int EXCEPTIONAL = 0xa0000000;
13.196 + static final int SIGNAL_MASK = 0x0000ffff;
13.197 + static final int INTERNAL_SIGNAL_MASK = 0x00007fff;
13.198 + static final int EXTERNAL_SIGNAL = 0x00008000; // top bit of low word
13.199 +
13.200 + /**
13.201 + * Table of exceptions thrown by tasks, to enable reporting by
13.202 + * callers. Because exceptions are rare, we don't directly keep
13.203 + * them with task objects, but instead use a weak ref table. Note
13.204 + * that cancellation exceptions don't appear in the table, but are
13.205 + * instead recorded as status values.
13.206 + * TODO: Use ConcurrentReferenceHashMap
13.207 + */
13.208 + static final Map<ForkJoinTask<?>, Throwable> exceptionMap =
13.209 + Collections.synchronizedMap
13.210 + (new WeakHashMap<ForkJoinTask<?>, Throwable>());
13.211 +
13.212 + // within-package utilities
13.213 +
13.214 + /**
13.215 + * Gets current worker thread, or null if not a worker thread.
13.216 + */
13.217 + static ForkJoinWorkerThread getWorker() {
13.218 + Thread t = Thread.currentThread();
13.219 + return ((t instanceof ForkJoinWorkerThread) ?
13.220 + (ForkJoinWorkerThread) t : null);
13.221 + }
13.222 +
13.223 + final boolean casStatus(int cmp, int val) {
13.224 + return UNSAFE.compareAndSwapInt(this, statusOffset, cmp, val);
13.225 + }
13.226 +
13.227 + /**
13.228 + * Workaround for not being able to rethrow unchecked exceptions.
13.229 + */
13.230 + static void rethrowException(Throwable ex) {
13.231 + if (ex != null)
13.232 + UNSAFE.throwException(ex);
13.233 + }
13.234 +
13.235 + // Setting completion status
13.236 +
13.237 + /**
13.238 + * Marks completion and wakes up threads waiting to join this task.
13.239 + *
13.240 + * @param completion one of NORMAL, CANCELLED, EXCEPTIONAL
13.241 + */
13.242 + final void setCompletion(int completion) {
13.243 + ForkJoinPool pool = getPool();
13.244 + if (pool != null) {
13.245 + int s; // Clear signal bits while setting completion status
13.246 + do {} while ((s = status) >= 0 && !casStatus(s, completion));
13.247 +
13.248 + if ((s & SIGNAL_MASK) != 0) {
13.249 + if ((s &= INTERNAL_SIGNAL_MASK) != 0)
13.250 + pool.updateRunningCount(s);
13.251 + synchronized (this) { notifyAll(); }
13.252 + }
13.253 + }
13.254 + else
13.255 + externallySetCompletion(completion);
13.256 + }
13.257 +
13.258 + /**
13.259 + * Version of setCompletion for non-FJ threads. Leaves signal
13.260 + * bits for unblocked threads to adjust, and always notifies.
13.261 + */
13.262 + private void externallySetCompletion(int completion) {
13.263 + int s;
13.264 + do {} while ((s = status) >= 0 &&
13.265 + !casStatus(s, (s & SIGNAL_MASK) | completion));
13.266 + synchronized (this) { notifyAll(); }
13.267 + }
13.268 +
13.269 + /**
13.270 + * Sets status to indicate normal completion.
13.271 + */
13.272 + final void setNormalCompletion() {
13.273 + // Try typical fast case -- single CAS, no signal, not already done.
13.274 + // Manually expand casStatus to improve chances of inlining it
13.275 + if (!UNSAFE.compareAndSwapInt(this, statusOffset, 0, NORMAL))
13.276 + setCompletion(NORMAL);
13.277 + }
13.278 +
13.279 + // internal waiting and notification
13.280 +
13.281 + /**
13.282 + * Performs the actual monitor wait for awaitDone.
13.283 + */
13.284 + private void doAwaitDone() {
13.285 + // Minimize lock bias and in/de-flation effects by maximizing
13.286 + // chances of waiting inside sync
13.287 + try {
13.288 + while (status >= 0)
13.289 + synchronized (this) { if (status >= 0) wait(); }
13.290 + } catch (InterruptedException ie) {
13.291 + onInterruptedWait();
13.292 + }
13.293 + }
13.294 +
13.295 + /**
13.296 + * Performs the actual timed monitor wait for awaitDone.
13.297 + */
13.298 + private void doAwaitDone(long startTime, long nanos) {
13.299 + synchronized (this) {
13.300 + try {
13.301 + while (status >= 0) {
13.302 + long nt = nanos - (System.nanoTime() - startTime);
13.303 + if (nt <= 0)
13.304 + break;
13.305 + wait(nt / 1000000, (int) (nt % 1000000));
13.306 + }
13.307 + } catch (InterruptedException ie) {
13.308 + onInterruptedWait();
13.309 + }
13.310 + }
13.311 + }
13.312 +
13.313 + // Awaiting completion
13.314 +
13.315 + /**
13.316 + * Sets status to indicate there is joiner, then waits for join,
13.317 + * surrounded with pool notifications.
13.318 + *
13.319 + * @return status upon exit
13.320 + */
13.321 + private int awaitDone(ForkJoinWorkerThread w,
13.322 + boolean maintainParallelism) {
13.323 + ForkJoinPool pool = (w == null) ? null : w.pool;
13.324 + int s;
13.325 + while ((s = status) >= 0) {
13.326 + if (casStatus(s, (pool == null) ? s|EXTERNAL_SIGNAL : s+1)) {
13.327 + if (pool == null || !pool.preJoin(this, maintainParallelism))
13.328 + doAwaitDone();
13.329 + if (((s = status) & INTERNAL_SIGNAL_MASK) != 0)
13.330 + adjustPoolCountsOnUnblock(pool);
13.331 + break;
13.332 + }
13.333 + }
13.334 + return s;
13.335 + }
13.336 +
13.337 + /**
13.338 + * Timed version of awaitDone
13.339 + *
13.340 + * @return status upon exit
13.341 + */
13.342 + private int awaitDone(ForkJoinWorkerThread w, long nanos) {
13.343 + ForkJoinPool pool = (w == null) ? null : w.pool;
13.344 + int s;
13.345 + while ((s = status) >= 0) {
13.346 + if (casStatus(s, (pool == null) ? s|EXTERNAL_SIGNAL : s+1)) {
13.347 + long startTime = System.nanoTime();
13.348 + if (pool == null || !pool.preJoin(this, false))
13.349 + doAwaitDone(startTime, nanos);
13.350 + if ((s = status) >= 0) {
13.351 + adjustPoolCountsOnCancelledWait(pool);
13.352 + s = status;
13.353 + }
13.354 + if (s < 0 && (s & INTERNAL_SIGNAL_MASK) != 0)
13.355 + adjustPoolCountsOnUnblock(pool);
13.356 + break;
13.357 + }
13.358 + }
13.359 + return s;
13.360 + }
13.361 +
13.362 + /**
13.363 + * Notifies pool that thread is unblocked. Called by signalled
13.364 + * threads when woken by non-FJ threads (which is atypical).
13.365 + */
13.366 + private void adjustPoolCountsOnUnblock(ForkJoinPool pool) {
13.367 + int s;
13.368 + do {} while ((s = status) < 0 && !casStatus(s, s & COMPLETION_MASK));
13.369 + if (pool != null && (s &= INTERNAL_SIGNAL_MASK) != 0)
13.370 + pool.updateRunningCount(s);
13.371 + }
13.372 +
13.373 + /**
13.374 + * Notifies pool to adjust counts on cancelled or timed out wait.
13.375 + */
13.376 + private void adjustPoolCountsOnCancelledWait(ForkJoinPool pool) {
13.377 + if (pool != null) {
13.378 + int s;
13.379 + while ((s = status) >= 0 && (s & INTERNAL_SIGNAL_MASK) != 0) {
13.380 + if (casStatus(s, s - 1)) {
13.381 + pool.updateRunningCount(1);
13.382 + break;
13.383 + }
13.384 + }
13.385 + }
13.386 + }
13.387 +
13.388 + /**
13.389 + * Handles interruptions during waits.
13.390 + */
13.391 + private void onInterruptedWait() {
13.392 + ForkJoinWorkerThread w = getWorker();
13.393 + if (w == null)
13.394 + Thread.currentThread().interrupt(); // re-interrupt
13.395 + else if (w.isTerminating())
13.396 + cancelIgnoringExceptions();
13.397 + // else if FJworker, ignore interrupt
13.398 + }
13.399 +
13.400 + // Recording and reporting exceptions
13.401 +
13.402 + private void setDoneExceptionally(Throwable rex) {
13.403 + exceptionMap.put(this, rex);
13.404 + setCompletion(EXCEPTIONAL);
13.405 + }
13.406 +
13.407 + /**
13.408 + * Throws the exception associated with status s.
13.409 + *
13.410 + * @throws the exception
13.411 + */
13.412 + private void reportException(int s) {
13.413 + if ((s &= COMPLETION_MASK) < NORMAL) {
13.414 + if (s == CANCELLED)
13.415 + throw new CancellationException();
13.416 + else
13.417 + rethrowException(exceptionMap.get(this));
13.418 + }
13.419 + }
13.420 +
13.421 + /**
13.422 + * Returns result or throws exception using j.u.c.Future conventions.
13.423 + * Only call when {@code isDone} known to be true or thread known
13.424 + * to be interrupted.
13.425 + */
13.426 + private V reportFutureResult()
13.427 + throws InterruptedException, ExecutionException {
13.428 + if (Thread.interrupted())
13.429 + throw new InterruptedException();
13.430 + int s = status & COMPLETION_MASK;
13.431 + if (s < NORMAL) {
13.432 + Throwable ex;
13.433 + if (s == CANCELLED)
13.434 + throw new CancellationException();
13.435 + if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
13.436 + throw new ExecutionException(ex);
13.437 + }
13.438 + return getRawResult();
13.439 + }
13.440 +
13.441 + /**
13.442 + * Returns result or throws exception using j.u.c.Future conventions
13.443 + * with timeouts.
13.444 + */
13.445 + private V reportTimedFutureResult()
13.446 + throws InterruptedException, ExecutionException, TimeoutException {
13.447 + if (Thread.interrupted())
13.448 + throw new InterruptedException();
13.449 + Throwable ex;
13.450 + int s = status & COMPLETION_MASK;
13.451 + if (s == NORMAL)
13.452 + return getRawResult();
13.453 + else if (s == CANCELLED)
13.454 + throw new CancellationException();
13.455 + else if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
13.456 + throw new ExecutionException(ex);
13.457 + else
13.458 + throw new TimeoutException();
13.459 + }
13.460 +
13.461 + // internal execution methods
13.462 +
13.463 + /**
13.464 + * Calls exec, recording completion, and rethrowing exception if
13.465 + * encountered. Caller should normally check status before calling.
13.466 + *
13.467 + * @return true if completed normally
13.468 + */
13.469 + private boolean tryExec() {
13.470 + try { // try block must contain only call to exec
13.471 + if (!exec())
13.472 + return false;
13.473 + } catch (Throwable rex) {
13.474 + setDoneExceptionally(rex);
13.475 + rethrowException(rex);
13.476 + return false; // not reached
13.477 + }
13.478 + setNormalCompletion();
13.479 + return true;
13.480 + }
13.481 +
13.482 + /**
13.483 + * Main execution method used by worker threads. Invokes
13.484 + * base computation unless already complete.
13.485 + */
13.486 + final void quietlyExec() {
13.487 + if (status >= 0) {
13.488 + try {
13.489 + if (!exec())
13.490 + return;
13.491 + } catch (Throwable rex) {
13.492 + setDoneExceptionally(rex);
13.493 + return;
13.494 + }
13.495 + setNormalCompletion();
13.496 + }
13.497 + }
13.498 +
13.499 + /**
13.500 + * Calls exec(), recording but not rethrowing exception.
13.501 + * Caller should normally check status before calling.
13.502 + *
13.503 + * @return true if completed normally
13.504 + */
13.505 + private boolean tryQuietlyInvoke() {
13.506 + try {
13.507 + if (!exec())
13.508 + return false;
13.509 + } catch (Throwable rex) {
13.510 + setDoneExceptionally(rex);
13.511 + return false;
13.512 + }
13.513 + setNormalCompletion();
13.514 + return true;
13.515 + }
13.516 +
13.517 + /**
13.518 + * Cancels, ignoring any exceptions it throws.
13.519 + */
13.520 + final void cancelIgnoringExceptions() {
13.521 + try {
13.522 + cancel(false);
13.523 + } catch (Throwable ignore) {
13.524 + }
13.525 + }
13.526 +
13.527 + /**
13.528 + * Main implementation of helpJoin
13.529 + */
13.530 + private int busyJoin(ForkJoinWorkerThread w) {
13.531 + int s;
13.532 + ForkJoinTask<?> t;
13.533 + while ((s = status) >= 0 && (t = w.scanWhileJoining(this)) != null)
13.534 + t.quietlyExec();
13.535 + return (s >= 0) ? awaitDone(w, false) : s; // block if no work
13.536 + }
13.537 +
13.538 + // public methods
13.539 +
13.540 + /**
13.541 + * Arranges to asynchronously execute this task. While it is not
13.542 + * necessarily enforced, it is a usage error to fork a task more
13.543 + * than once unless it has completed and been reinitialized.
13.544 + * Subsequent modifications to the state of this task or any data
13.545 + * it operates on are not necessarily consistently observable by
13.546 + * any thread other than the one executing it unless preceded by a
13.547 + * call to {@link #join} or related methods, or a call to {@link
13.548 + * #isDone} returning {@code true}.
13.549 + *
13.550 + * <p>This method may be invoked only from within {@code
13.551 + * ForkJoinTask} computations (as may be determined using method
13.552 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.553 + * result in exceptions or errors, possibly including {@code
13.554 + * ClassCastException}.
13.555 + *
13.556 + * @return {@code this}, to simplify usage
13.557 + */
13.558 + public final ForkJoinTask<V> fork() {
13.559 + ((ForkJoinWorkerThread) Thread.currentThread())
13.560 + .pushTask(this);
13.561 + return this;
13.562 + }
13.563 +
13.564 + /**
13.565 + * Returns the result of the computation when it {@link #isDone is done}.
13.566 + * This method differs from {@link #get()} in that
13.567 + * abnormal completion results in {@code RuntimeException} or
13.568 + * {@code Error}, not {@code ExecutionException}.
13.569 + *
13.570 + * @return the computed result
13.571 + */
13.572 + public final V join() {
13.573 + ForkJoinWorkerThread w = getWorker();
13.574 + if (w == null || status < 0 || !w.unpushTask(this) || !tryExec())
13.575 + reportException(awaitDone(w, true));
13.576 + return getRawResult();
13.577 + }
13.578 +
13.579 + /**
13.580 + * Commences performing this task, awaits its completion if
13.581 + * necessary, and return its result, or throws an (unchecked)
13.582 + * exception if the underlying computation did so.
13.583 + *
13.584 + * @return the computed result
13.585 + */
13.586 + public final V invoke() {
13.587 + if (status >= 0 && tryExec())
13.588 + return getRawResult();
13.589 + else
13.590 + return join();
13.591 + }
13.592 +
13.593 + /**
13.594 + * Forks the given tasks, returning when {@code isDone} holds for
13.595 + * each task or an (unchecked) exception is encountered, in which
13.596 + * case the exception is rethrown. If either task encounters an
13.597 + * exception, the other one may be, but is not guaranteed to be,
13.598 + * cancelled. If both tasks throw an exception, then this method
13.599 + * throws one of them. The individual status of each task may be
13.600 + * checked using {@link #getException()} and related methods.
13.601 + *
13.602 + * <p>This method may be invoked only from within {@code
13.603 + * ForkJoinTask} computations (as may be determined using method
13.604 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.605 + * result in exceptions or errors, possibly including {@code
13.606 + * ClassCastException}.
13.607 + *
13.608 + * @param t1 the first task
13.609 + * @param t2 the second task
13.610 + * @throws NullPointerException if any task is null
13.611 + */
13.612 + public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
13.613 + t2.fork();
13.614 + t1.invoke();
13.615 + t2.join();
13.616 + }
13.617 +
13.618 + /**
13.619 + * Forks the given tasks, returning when {@code isDone} holds for
13.620 + * each task or an (unchecked) exception is encountered, in which
13.621 + * case the exception is rethrown. If any task encounters an
13.622 + * exception, others may be, but are not guaranteed to be,
13.623 + * cancelled. If more than one task encounters an exception, then
13.624 + * this method throws any one of these exceptions. The individual
13.625 + * status of each task may be checked using {@link #getException()}
13.626 + * and related methods.
13.627 + *
13.628 + * <p>This method may be invoked only from within {@code
13.629 + * ForkJoinTask} computations (as may be determined using method
13.630 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.631 + * result in exceptions or errors, possibly including {@code
13.632 + * ClassCastException}.
13.633 + *
13.634 + * @param tasks the tasks
13.635 + * @throws NullPointerException if any task is null
13.636 + */
13.637 + public static void invokeAll(ForkJoinTask<?>... tasks) {
13.638 + Throwable ex = null;
13.639 + int last = tasks.length - 1;
13.640 + for (int i = last; i >= 0; --i) {
13.641 + ForkJoinTask<?> t = tasks[i];
13.642 + if (t == null) {
13.643 + if (ex == null)
13.644 + ex = new NullPointerException();
13.645 + }
13.646 + else if (i != 0)
13.647 + t.fork();
13.648 + else {
13.649 + t.quietlyInvoke();
13.650 + if (ex == null)
13.651 + ex = t.getException();
13.652 + }
13.653 + }
13.654 + for (int i = 1; i <= last; ++i) {
13.655 + ForkJoinTask<?> t = tasks[i];
13.656 + if (t != null) {
13.657 + if (ex != null)
13.658 + t.cancel(false);
13.659 + else {
13.660 + t.quietlyJoin();
13.661 + if (ex == null)
13.662 + ex = t.getException();
13.663 + }
13.664 + }
13.665 + }
13.666 + if (ex != null)
13.667 + rethrowException(ex);
13.668 + }
13.669 +
13.670 + /**
13.671 + * Forks all tasks in the specified collection, returning when
13.672 + * {@code isDone} holds for each task or an (unchecked) exception
13.673 + * is encountered. If any task encounters an exception, others
13.674 + * may be, but are not guaranteed to be, cancelled. If more than
13.675 + * one task encounters an exception, then this method throws any
13.676 + * one of these exceptions. The individual status of each task
13.677 + * may be checked using {@link #getException()} and related
13.678 + * methods. The behavior of this operation is undefined if the
13.679 + * specified collection is modified while the operation is in
13.680 + * progress.
13.681 + *
13.682 + * <p>This method may be invoked only from within {@code
13.683 + * ForkJoinTask} computations (as may be determined using method
13.684 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.685 + * result in exceptions or errors, possibly including {@code
13.686 + * ClassCastException}.
13.687 + *
13.688 + * @param tasks the collection of tasks
13.689 + * @return the tasks argument, to simplify usage
13.690 + * @throws NullPointerException if tasks or any element are null
13.691 + */
13.692 + public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
13.693 + if (!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) {
13.694 + invokeAll(tasks.toArray(new ForkJoinTask<?>[tasks.size()]));
13.695 + return tasks;
13.696 + }
13.697 + @SuppressWarnings("unchecked")
13.698 + List<? extends ForkJoinTask<?>> ts =
13.699 + (List<? extends ForkJoinTask<?>>) tasks;
13.700 + Throwable ex = null;
13.701 + int last = ts.size() - 1;
13.702 + for (int i = last; i >= 0; --i) {
13.703 + ForkJoinTask<?> t = ts.get(i);
13.704 + if (t == null) {
13.705 + if (ex == null)
13.706 + ex = new NullPointerException();
13.707 + }
13.708 + else if (i != 0)
13.709 + t.fork();
13.710 + else {
13.711 + t.quietlyInvoke();
13.712 + if (ex == null)
13.713 + ex = t.getException();
13.714 + }
13.715 + }
13.716 + for (int i = 1; i <= last; ++i) {
13.717 + ForkJoinTask<?> t = ts.get(i);
13.718 + if (t != null) {
13.719 + if (ex != null)
13.720 + t.cancel(false);
13.721 + else {
13.722 + t.quietlyJoin();
13.723 + if (ex == null)
13.724 + ex = t.getException();
13.725 + }
13.726 + }
13.727 + }
13.728 + if (ex != null)
13.729 + rethrowException(ex);
13.730 + return tasks;
13.731 + }
13.732 +
13.733 + /**
13.734 + * Attempts to cancel execution of this task. This attempt will
13.735 + * fail if the task has already completed, has already been
13.736 + * cancelled, or could not be cancelled for some other reason. If
13.737 + * successful, and this task has not started when cancel is
13.738 + * called, execution of this task is suppressed, {@link
13.739 + * #isCancelled} will report true, and {@link #join} will result
13.740 + * in a {@code CancellationException} being thrown.
13.741 + *
13.742 + * <p>This method may be overridden in subclasses, but if so, must
13.743 + * still ensure that these minimal properties hold. In particular,
13.744 + * the {@code cancel} method itself must not throw exceptions.
13.745 + *
13.746 + * <p>This method is designed to be invoked by <em>other</em>
13.747 + * tasks. To terminate the current task, you can just return or
13.748 + * throw an unchecked exception from its computation method, or
13.749 + * invoke {@link #completeExceptionally}.
13.750 + *
13.751 + * @param mayInterruptIfRunning this value is ignored in the
13.752 + * default implementation because tasks are not
13.753 + * cancelled via interruption
13.754 + *
13.755 + * @return {@code true} if this task is now cancelled
13.756 + */
13.757 + public boolean cancel(boolean mayInterruptIfRunning) {
13.758 + setCompletion(CANCELLED);
13.759 + return (status & COMPLETION_MASK) == CANCELLED;
13.760 + }
13.761 +
13.762 + public final boolean isDone() {
13.763 + return status < 0;
13.764 + }
13.765 +
13.766 + public final boolean isCancelled() {
13.767 + return (status & COMPLETION_MASK) == CANCELLED;
13.768 + }
13.769 +
13.770 + /**
13.771 + * Returns {@code true} if this task threw an exception or was cancelled.
13.772 + *
13.773 + * @return {@code true} if this task threw an exception or was cancelled
13.774 + */
13.775 + public final boolean isCompletedAbnormally() {
13.776 + return (status & COMPLETION_MASK) < NORMAL;
13.777 + }
13.778 +
13.779 + /**
13.780 + * Returns {@code true} if this task completed without throwing an
13.781 + * exception and was not cancelled.
13.782 + *
13.783 + * @return {@code true} if this task completed without throwing an
13.784 + * exception and was not cancelled
13.785 + */
13.786 + public final boolean isCompletedNormally() {
13.787 + return (status & COMPLETION_MASK) == NORMAL;
13.788 + }
13.789 +
13.790 + /**
13.791 + * Returns the exception thrown by the base computation, or a
13.792 + * {@code CancellationException} if cancelled, or {@code null} if
13.793 + * none or if the method has not yet completed.
13.794 + *
13.795 + * @return the exception, or {@code null} if none
13.796 + */
13.797 + public final Throwable getException() {
13.798 + int s = status & COMPLETION_MASK;
13.799 + return ((s >= NORMAL) ? null :
13.800 + (s == CANCELLED) ? new CancellationException() :
13.801 + exceptionMap.get(this));
13.802 + }
13.803 +
13.804 + /**
13.805 + * Completes this task abnormally, and if not already aborted or
13.806 + * cancelled, causes it to throw the given exception upon
13.807 + * {@code join} and related operations. This method may be used
13.808 + * to induce exceptions in asynchronous tasks, or to force
13.809 + * completion of tasks that would not otherwise complete. Its use
13.810 + * in other situations is discouraged. This method is
13.811 + * overridable, but overridden versions must invoke {@code super}
13.812 + * implementation to maintain guarantees.
13.813 + *
13.814 + * @param ex the exception to throw. If this exception is not a
13.815 + * {@code RuntimeException} or {@code Error}, the actual exception
13.816 + * thrown will be a {@code RuntimeException} with cause {@code ex}.
13.817 + */
13.818 + public void completeExceptionally(Throwable ex) {
13.819 + setDoneExceptionally((ex instanceof RuntimeException) ||
13.820 + (ex instanceof Error) ? ex :
13.821 + new RuntimeException(ex));
13.822 + }
13.823 +
13.824 + /**
13.825 + * Completes this task, and if not already aborted or cancelled,
13.826 + * returning a {@code null} result upon {@code join} and related
13.827 + * operations. This method may be used to provide results for
13.828 + * asynchronous tasks, or to provide alternative handling for
13.829 + * tasks that would not otherwise complete normally. Its use in
13.830 + * other situations is discouraged. This method is
13.831 + * overridable, but overridden versions must invoke {@code super}
13.832 + * implementation to maintain guarantees.
13.833 + *
13.834 + * @param value the result value for this task
13.835 + */
13.836 + public void complete(V value) {
13.837 + try {
13.838 + setRawResult(value);
13.839 + } catch (Throwable rex) {
13.840 + setDoneExceptionally(rex);
13.841 + return;
13.842 + }
13.843 + setNormalCompletion();
13.844 + }
13.845 +
13.846 + public final V get() throws InterruptedException, ExecutionException {
13.847 + ForkJoinWorkerThread w = getWorker();
13.848 + if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke())
13.849 + awaitDone(w, true);
13.850 + return reportFutureResult();
13.851 + }
13.852 +
13.853 + public final V get(long timeout, TimeUnit unit)
13.854 + throws InterruptedException, ExecutionException, TimeoutException {
13.855 + long nanos = unit.toNanos(timeout);
13.856 + ForkJoinWorkerThread w = getWorker();
13.857 + if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke())
13.858 + awaitDone(w, nanos);
13.859 + return reportTimedFutureResult();
13.860 + }
13.861 +
13.862 + /**
13.863 + * Possibly executes other tasks until this task {@link #isDone is
13.864 + * done}, then returns the result of the computation. This method
13.865 + * may be more efficient than {@code join}, but is only applicable
13.866 + * when there are no potential dependencies between continuation
13.867 + * of the current task and that of any other task that might be
13.868 + * executed while helping. (This usually holds for pure
13.869 + * divide-and-conquer tasks).
13.870 + *
13.871 + * <p>This method may be invoked only from within {@code
13.872 + * ForkJoinTask} computations (as may be determined using method
13.873 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.874 + * result in exceptions or errors, possibly including {@code
13.875 + * ClassCastException}.
13.876 + *
13.877 + * @return the computed result
13.878 + */
13.879 + public final V helpJoin() {
13.880 + ForkJoinWorkerThread w = (ForkJoinWorkerThread) Thread.currentThread();
13.881 + if (status < 0 || !w.unpushTask(this) || !tryExec())
13.882 + reportException(busyJoin(w));
13.883 + return getRawResult();
13.884 + }
13.885 +
13.886 + /**
13.887 + * Possibly executes other tasks until this task {@link #isDone is
13.888 + * done}. This method may be useful when processing collections
13.889 + * of tasks when some have been cancelled or otherwise known to
13.890 + * have aborted.
13.891 + *
13.892 + * <p>This method may be invoked only from within {@code
13.893 + * ForkJoinTask} computations (as may be determined using method
13.894 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.895 + * result in exceptions or errors, possibly including {@code
13.896 + * ClassCastException}.
13.897 + */
13.898 + public final void quietlyHelpJoin() {
13.899 + if (status >= 0) {
13.900 + ForkJoinWorkerThread w =
13.901 + (ForkJoinWorkerThread) Thread.currentThread();
13.902 + if (!w.unpushTask(this) || !tryQuietlyInvoke())
13.903 + busyJoin(w);
13.904 + }
13.905 + }
13.906 +
13.907 + /**
13.908 + * Joins this task, without returning its result or throwing an
13.909 + * exception. This method may be useful when processing
13.910 + * collections of tasks when some have been cancelled or otherwise
13.911 + * known to have aborted.
13.912 + */
13.913 + public final void quietlyJoin() {
13.914 + if (status >= 0) {
13.915 + ForkJoinWorkerThread w = getWorker();
13.916 + if (w == null || !w.unpushTask(this) || !tryQuietlyInvoke())
13.917 + awaitDone(w, true);
13.918 + }
13.919 + }
13.920 +
13.921 + /**
13.922 + * Commences performing this task and awaits its completion if
13.923 + * necessary, without returning its result or throwing an
13.924 + * exception. This method may be useful when processing
13.925 + * collections of tasks when some have been cancelled or otherwise
13.926 + * known to have aborted.
13.927 + */
13.928 + public final void quietlyInvoke() {
13.929 + if (status >= 0 && !tryQuietlyInvoke())
13.930 + quietlyJoin();
13.931 + }
13.932 +
13.933 + /**
13.934 + * Possibly executes tasks until the pool hosting the current task
13.935 + * {@link ForkJoinPool#isQuiescent is quiescent}. This method may
13.936 + * be of use in designs in which many tasks are forked, but none
13.937 + * are explicitly joined, instead executing them until all are
13.938 + * processed.
13.939 + *
13.940 + * <p>This method may be invoked only from within {@code
13.941 + * ForkJoinTask} computations (as may be determined using method
13.942 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.943 + * result in exceptions or errors, possibly including {@code
13.944 + * ClassCastException}.
13.945 + */
13.946 + public static void helpQuiesce() {
13.947 + ((ForkJoinWorkerThread) Thread.currentThread())
13.948 + .helpQuiescePool();
13.949 + }
13.950 +
13.951 + /**
13.952 + * Resets the internal bookkeeping state of this task, allowing a
13.953 + * subsequent {@code fork}. This method allows repeated reuse of
13.954 + * this task, but only if reuse occurs when this task has either
13.955 + * never been forked, or has been forked, then completed and all
13.956 + * outstanding joins of this task have also completed. Effects
13.957 + * under any other usage conditions are not guaranteed.
13.958 + * This method may be useful when executing
13.959 + * pre-constructed trees of subtasks in loops.
13.960 + */
13.961 + public void reinitialize() {
13.962 + if ((status & COMPLETION_MASK) == EXCEPTIONAL)
13.963 + exceptionMap.remove(this);
13.964 + status = 0;
13.965 + }
13.966 +
13.967 + /**
13.968 + * Returns the pool hosting the current task execution, or null
13.969 + * if this task is executing outside of any ForkJoinPool.
13.970 + *
13.971 + * @see #inForkJoinPool
13.972 + * @return the pool, or {@code null} if none
13.973 + */
13.974 + public static ForkJoinPool getPool() {
13.975 + Thread t = Thread.currentThread();
13.976 + return (t instanceof ForkJoinWorkerThread) ?
13.977 + ((ForkJoinWorkerThread) t).pool : null;
13.978 + }
13.979 +
13.980 + /**
13.981 + * Returns {@code true} if the current thread is executing as a
13.982 + * ForkJoinPool computation.
13.983 + *
13.984 + * @return {@code true} if the current thread is executing as a
13.985 + * ForkJoinPool computation, or false otherwise
13.986 + */
13.987 + public static boolean inForkJoinPool() {
13.988 + return Thread.currentThread() instanceof ForkJoinWorkerThread;
13.989 + }
13.990 +
13.991 + /**
13.992 + * Tries to unschedule this task for execution. This method will
13.993 + * typically succeed if this task is the most recently forked task
13.994 + * by the current thread, and has not commenced executing in
13.995 + * another thread. This method may be useful when arranging
13.996 + * alternative local processing of tasks that could have been, but
13.997 + * were not, stolen.
13.998 + *
13.999 + * <p>This method may be invoked only from within {@code
13.1000 + * ForkJoinTask} computations (as may be determined using method
13.1001 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.1002 + * result in exceptions or errors, possibly including {@code
13.1003 + * ClassCastException}.
13.1004 + *
13.1005 + * @return {@code true} if unforked
13.1006 + */
13.1007 + public boolean tryUnfork() {
13.1008 + return ((ForkJoinWorkerThread) Thread.currentThread())
13.1009 + .unpushTask(this);
13.1010 + }
13.1011 +
13.1012 + /**
13.1013 + * Returns an estimate of the number of tasks that have been
13.1014 + * forked by the current worker thread but not yet executed. This
13.1015 + * value may be useful for heuristic decisions about whether to
13.1016 + * fork other tasks.
13.1017 + *
13.1018 + * <p>This method may be invoked only from within {@code
13.1019 + * ForkJoinTask} computations (as may be determined using method
13.1020 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.1021 + * result in exceptions or errors, possibly including {@code
13.1022 + * ClassCastException}.
13.1023 + *
13.1024 + * @return the number of tasks
13.1025 + */
13.1026 + public static int getQueuedTaskCount() {
13.1027 + return ((ForkJoinWorkerThread) Thread.currentThread())
13.1028 + .getQueueSize();
13.1029 + }
13.1030 +
13.1031 + /**
13.1032 + * Returns an estimate of how many more locally queued tasks are
13.1033 + * held by the current worker thread than there are other worker
13.1034 + * threads that might steal them. This value may be useful for
13.1035 + * heuristic decisions about whether to fork other tasks. In many
13.1036 + * usages of ForkJoinTasks, at steady state, each worker should
13.1037 + * aim to maintain a small constant surplus (for example, 3) of
13.1038 + * tasks, and to process computations locally if this threshold is
13.1039 + * exceeded.
13.1040 + *
13.1041 + * <p>This method may be invoked only from within {@code
13.1042 + * ForkJoinTask} computations (as may be determined using method
13.1043 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.1044 + * result in exceptions or errors, possibly including {@code
13.1045 + * ClassCastException}.
13.1046 + *
13.1047 + * @return the surplus number of tasks, which may be negative
13.1048 + */
13.1049 + public static int getSurplusQueuedTaskCount() {
13.1050 + return ((ForkJoinWorkerThread) Thread.currentThread())
13.1051 + .getEstimatedSurplusTaskCount();
13.1052 + }
13.1053 +
13.1054 + // Extension methods
13.1055 +
13.1056 + /**
13.1057 + * Returns the result that would be returned by {@link #join}, even
13.1058 + * if this task completed abnormally, or {@code null} if this task
13.1059 + * is not known to have been completed. This method is designed
13.1060 + * to aid debugging, as well as to support extensions. Its use in
13.1061 + * any other context is discouraged.
13.1062 + *
13.1063 + * @return the result, or {@code null} if not completed
13.1064 + */
13.1065 + public abstract V getRawResult();
13.1066 +
13.1067 + /**
13.1068 + * Forces the given value to be returned as a result. This method
13.1069 + * is designed to support extensions, and should not in general be
13.1070 + * called otherwise.
13.1071 + *
13.1072 + * @param value the value
13.1073 + */
13.1074 + protected abstract void setRawResult(V value);
13.1075 +
13.1076 + /**
13.1077 + * Immediately performs the base action of this task. This method
13.1078 + * is designed to support extensions, and should not in general be
13.1079 + * called otherwise. The return value controls whether this task
13.1080 + * is considered to be done normally. It may return false in
13.1081 + * asynchronous actions that require explicit invocations of
13.1082 + * {@link #complete} to become joinable. It may also throw an
13.1083 + * (unchecked) exception to indicate abnormal exit.
13.1084 + *
13.1085 + * @return {@code true} if completed normally
13.1086 + */
13.1087 + protected abstract boolean exec();
13.1088 +
13.1089 + /**
13.1090 + * Returns, but does not unschedule or execute, a task queued by
13.1091 + * the current thread but not yet executed, if one is immediately
13.1092 + * available. There is no guarantee that this task will actually
13.1093 + * be polled or executed next. Conversely, this method may return
13.1094 + * null even if a task exists but cannot be accessed without
13.1095 + * contention with other threads. This method is designed
13.1096 + * primarily to support extensions, and is unlikely to be useful
13.1097 + * otherwise.
13.1098 + *
13.1099 + * <p>This method may be invoked only from within {@code
13.1100 + * ForkJoinTask} computations (as may be determined using method
13.1101 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.1102 + * result in exceptions or errors, possibly including {@code
13.1103 + * ClassCastException}.
13.1104 + *
13.1105 + * @return the next task, or {@code null} if none are available
13.1106 + */
13.1107 + protected static ForkJoinTask<?> peekNextLocalTask() {
13.1108 + return ((ForkJoinWorkerThread) Thread.currentThread())
13.1109 + .peekTask();
13.1110 + }
13.1111 +
13.1112 + /**
13.1113 + * Unschedules and returns, without executing, the next task
13.1114 + * queued by the current thread but not yet executed. This method
13.1115 + * is designed primarily to support extensions, and is unlikely to
13.1116 + * be useful otherwise.
13.1117 + *
13.1118 + * <p>This method may be invoked only from within {@code
13.1119 + * ForkJoinTask} computations (as may be determined using method
13.1120 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.1121 + * result in exceptions or errors, possibly including {@code
13.1122 + * ClassCastException}.
13.1123 + *
13.1124 + * @return the next task, or {@code null} if none are available
13.1125 + */
13.1126 + protected static ForkJoinTask<?> pollNextLocalTask() {
13.1127 + return ((ForkJoinWorkerThread) Thread.currentThread())
13.1128 + .pollLocalTask();
13.1129 + }
13.1130 +
13.1131 + /**
13.1132 + * Unschedules and returns, without executing, the next task
13.1133 + * queued by the current thread but not yet executed, if one is
13.1134 + * available, or if not available, a task that was forked by some
13.1135 + * other thread, if available. Availability may be transient, so a
13.1136 + * {@code null} result does not necessarily imply quiescence
13.1137 + * of the pool this task is operating in. This method is designed
13.1138 + * primarily to support extensions, and is unlikely to be useful
13.1139 + * otherwise.
13.1140 + *
13.1141 + * <p>This method may be invoked only from within {@code
13.1142 + * ForkJoinTask} computations (as may be determined using method
13.1143 + * {@link #inForkJoinPool}). Attempts to invoke in other contexts
13.1144 + * result in exceptions or errors, possibly including {@code
13.1145 + * ClassCastException}.
13.1146 + *
13.1147 + * @return a task, or {@code null} if none are available
13.1148 + */
13.1149 + protected static ForkJoinTask<?> pollTask() {
13.1150 + return ((ForkJoinWorkerThread) Thread.currentThread())
13.1151 + .pollTask();
13.1152 + }
13.1153 +
13.1154 + /**
13.1155 + * Adaptor for Runnables. This implements RunnableFuture
13.1156 + * to be compliant with AbstractExecutorService constraints
13.1157 + * when used in ForkJoinPool.
13.1158 + */
13.1159 + static final class AdaptedRunnable<T> extends ForkJoinTask<T>
13.1160 + implements RunnableFuture<T> {
13.1161 + final Runnable runnable;
13.1162 + final T resultOnCompletion;
13.1163 + T result;
13.1164 + AdaptedRunnable(Runnable runnable, T result) {
13.1165 + if (runnable == null) throw new NullPointerException();
13.1166 + this.runnable = runnable;
13.1167 + this.resultOnCompletion = result;
13.1168 + }
13.1169 + public T getRawResult() { return result; }
13.1170 + public void setRawResult(T v) { result = v; }
13.1171 + public boolean exec() {
13.1172 + runnable.run();
13.1173 + result = resultOnCompletion;
13.1174 + return true;
13.1175 + }
13.1176 + public void run() { invoke(); }
13.1177 + private static final long serialVersionUID = 5232453952276885070L;
13.1178 + }
13.1179 +
13.1180 + /**
13.1181 + * Adaptor for Callables
13.1182 + */
13.1183 + static final class AdaptedCallable<T> extends ForkJoinTask<T>
13.1184 + implements RunnableFuture<T> {
13.1185 + final Callable<? extends T> callable;
13.1186 + T result;
13.1187 + AdaptedCallable(Callable<? extends T> callable) {
13.1188 + if (callable == null) throw new NullPointerException();
13.1189 + this.callable = callable;
13.1190 + }
13.1191 + public T getRawResult() { return result; }
13.1192 + public void setRawResult(T v) { result = v; }
13.1193 + public boolean exec() {
13.1194 + try {
13.1195 + result = callable.call();
13.1196 + return true;
13.1197 + } catch (Error err) {
13.1198 + throw err;
13.1199 + } catch (RuntimeException rex) {
13.1200 + throw rex;
13.1201 + } catch (Exception ex) {
13.1202 + throw new RuntimeException(ex);
13.1203 + }
13.1204 + }
13.1205 + public void run() { invoke(); }
13.1206 + private static final long serialVersionUID = 2838392045355241008L;
13.1207 + }
13.1208 +
13.1209 + /**
13.1210 + * Returns a new {@code ForkJoinTask} that performs the {@code run}
13.1211 + * method of the given {@code Runnable} as its action, and returns
13.1212 + * a null result upon {@link #join}.
13.1213 + *
13.1214 + * @param runnable the runnable action
13.1215 + * @return the task
13.1216 + */
13.1217 + public static ForkJoinTask<?> adapt(Runnable runnable) {
13.1218 + return new AdaptedRunnable<Void>(runnable, null);
13.1219 + }
13.1220 +
13.1221 + /**
13.1222 + * Returns a new {@code ForkJoinTask} that performs the {@code run}
13.1223 + * method of the given {@code Runnable} as its action, and returns
13.1224 + * the given result upon {@link #join}.
13.1225 + *
13.1226 + * @param runnable the runnable action
13.1227 + * @param result the result upon completion
13.1228 + * @return the task
13.1229 + */
13.1230 + public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) {
13.1231 + return new AdaptedRunnable<T>(runnable, result);
13.1232 + }
13.1233 +
13.1234 + /**
13.1235 + * Returns a new {@code ForkJoinTask} that performs the {@code call}
13.1236 + * method of the given {@code Callable} as its action, and returns
13.1237 + * its result upon {@link #join}, translating any checked exceptions
13.1238 + * encountered into {@code RuntimeException}.
13.1239 + *
13.1240 + * @param callable the callable action
13.1241 + * @return the task
13.1242 + */
13.1243 + public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) {
13.1244 + return new AdaptedCallable<T>(callable);
13.1245 + }
13.1246 +
13.1247 + // Serialization support
13.1248 +
13.1249 + private static final long serialVersionUID = -7721805057305804111L;
13.1250 +
13.1251 + /**
13.1252 + * Saves the state to a stream.
13.1253 + *
13.1254 + * @serialData the current run status and the exception thrown
13.1255 + * during execution, or {@code null} if none
13.1256 + * @param s the stream
13.1257 + */
13.1258 + private void writeObject(java.io.ObjectOutputStream s)
13.1259 + throws java.io.IOException {
13.1260 + s.defaultWriteObject();
13.1261 + s.writeObject(getException());
13.1262 + }
13.1263 +
13.1264 + /**
13.1265 + * Reconstitutes the instance from a stream.
13.1266 + *
13.1267 + * @param s the stream
13.1268 + */
13.1269 + private void readObject(java.io.ObjectInputStream s)
13.1270 + throws java.io.IOException, ClassNotFoundException {
13.1271 + s.defaultReadObject();
13.1272 + status &= ~INTERNAL_SIGNAL_MASK; // clear internal signal counts
13.1273 + status |= EXTERNAL_SIGNAL; // conservatively set external signal
13.1274 + Object ex = s.readObject();
13.1275 + if (ex != null)
13.1276 + setDoneExceptionally((Throwable) ex);
13.1277 + }
13.1278 +
13.1279 + // Unsafe mechanics
13.1280 +
13.1281 + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
13.1282 + private static final long statusOffset =
13.1283 + objectFieldOffset("status", ForkJoinTask.class);
13.1284 +
13.1285 + private static long objectFieldOffset(String field, Class<?> klazz) {
13.1286 + try {
13.1287 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
13.1288 + } catch (NoSuchFieldException e) {
13.1289 + // Convert Exception to corresponding Error
13.1290 + NoSuchFieldError error = new NoSuchFieldError(field);
13.1291 + error.initCause(e);
13.1292 + throw error;
13.1293 + }
13.1294 + }
13.1295 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Sun Nov 08 14:49:18 2009 -0800
14.3 @@ -0,0 +1,827 @@
14.4 +/*
14.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.6 + *
14.7 + * This code is free software; you can redistribute it and/or modify it
14.8 + * under the terms of the GNU General Public License version 2 only, as
14.9 + * published by the Free Software Foundation. Sun designates this
14.10 + * particular file as subject to the "Classpath" exception as provided
14.11 + * by Sun in the LICENSE file that accompanied this code.
14.12 + *
14.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.16 + * version 2 for more details (a copy is included in the LICENSE file that
14.17 + * accompanied this code).
14.18 + *
14.19 + * You should have received a copy of the GNU General Public License version
14.20 + * 2 along with this work; if not, write to the Free Software Foundation,
14.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.22 + *
14.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
14.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
14.25 + * have any questions.
14.26 + */
14.27 +
14.28 +/*
14.29 + * This file is available under and governed by the GNU General Public
14.30 + * License version 2 only, as published by the Free Software Foundation.
14.31 + * However, the following notice accompanied the original version of this
14.32 + * file:
14.33 + *
14.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
14.35 + * Expert Group and released to the public domain, as explained at
14.36 + * http://creativecommons.org/licenses/publicdomain
14.37 + */
14.38 +
14.39 +package java.util.concurrent;
14.40 +
14.41 +import java.util.Collection;
14.42 +
14.43 +/**
14.44 + * A thread managed by a {@link ForkJoinPool}. This class is
14.45 + * subclassable solely for the sake of adding functionality -- there
14.46 + * are no overridable methods dealing with scheduling or execution.
14.47 + * However, you can override initialization and termination methods
14.48 + * surrounding the main task processing loop. If you do create such a
14.49 + * subclass, you will also need to supply a custom {@link
14.50 + * ForkJoinPool.ForkJoinWorkerThreadFactory} to use it in a {@code
14.51 + * ForkJoinPool}.
14.52 + *
14.53 + * @since 1.7
14.54 + * @author Doug Lea
14.55 + */
14.56 +public class ForkJoinWorkerThread extends Thread {
14.57 + /*
14.58 + * Algorithm overview:
14.59 + *
14.60 + * 1. Work-Stealing: Work-stealing queues are special forms of
14.61 + * Deques that support only three of the four possible
14.62 + * end-operations -- push, pop, and deq (aka steal), and only do
14.63 + * so under the constraints that push and pop are called only from
14.64 + * the owning thread, while deq may be called from other threads.
14.65 + * (If you are unfamiliar with them, you probably want to read
14.66 + * Herlihy and Shavit's book "The Art of Multiprocessor
14.67 + * programming", chapter 16 describing these in more detail before
14.68 + * proceeding.) The main work-stealing queue design is roughly
14.69 + * similar to "Dynamic Circular Work-Stealing Deque" by David
14.70 + * Chase and Yossi Lev, SPAA 2005
14.71 + * (http://research.sun.com/scalable/pubs/index.html). The main
14.72 + * difference ultimately stems from gc requirements that we null
14.73 + * out taken slots as soon as we can, to maintain as small a
14.74 + * footprint as possible even in programs generating huge numbers
14.75 + * of tasks. To accomplish this, we shift the CAS arbitrating pop
14.76 + * vs deq (steal) from being on the indices ("base" and "sp") to
14.77 + * the slots themselves (mainly via method "casSlotNull()"). So,
14.78 + * both a successful pop and deq mainly entail CAS'ing a non-null
14.79 + * slot to null. Because we rely on CASes of references, we do
14.80 + * not need tag bits on base or sp. They are simple ints as used
14.81 + * in any circular array-based queue (see for example ArrayDeque).
14.82 + * Updates to the indices must still be ordered in a way that
14.83 + * guarantees that (sp - base) > 0 means the queue is empty, but
14.84 + * otherwise may err on the side of possibly making the queue
14.85 + * appear nonempty when a push, pop, or deq have not fully
14.86 + * committed. Note that this means that the deq operation,
14.87 + * considered individually, is not wait-free. One thief cannot
14.88 + * successfully continue until another in-progress one (or, if
14.89 + * previously empty, a push) completes. However, in the
14.90 + * aggregate, we ensure at least probabilistic
14.91 + * non-blockingness. If an attempted steal fails, a thief always
14.92 + * chooses a different random victim target to try next. So, in
14.93 + * order for one thief to progress, it suffices for any
14.94 + * in-progress deq or new push on any empty queue to complete. One
14.95 + * reason this works well here is that apparently-nonempty often
14.96 + * means soon-to-be-stealable, which gives threads a chance to
14.97 + * activate if necessary before stealing (see below).
14.98 + *
14.99 + * This approach also enables support for "async mode" where local
14.100 + * task processing is in FIFO, not LIFO order; simply by using a
14.101 + * version of deq rather than pop when locallyFifo is true (as set
14.102 + * by the ForkJoinPool). This allows use in message-passing
14.103 + * frameworks in which tasks are never joined.
14.104 + *
14.105 + * Efficient implementation of this approach currently relies on
14.106 + * an uncomfortable amount of "Unsafe" mechanics. To maintain
14.107 + * correct orderings, reads and writes of variable base require
14.108 + * volatile ordering. Variable sp does not require volatile write
14.109 + * but needs cheaper store-ordering on writes. Because they are
14.110 + * protected by volatile base reads, reads of the queue array and
14.111 + * its slots do not need volatile load semantics, but writes (in
14.112 + * push) require store order and CASes (in pop and deq) require
14.113 + * (volatile) CAS semantics. (See "Idempotent work stealing" by
14.114 + * Michael, Saraswat, and Vechev, PPoPP 2009
14.115 + * http://portal.acm.org/citation.cfm?id=1504186 for an algorithm
14.116 + * with similar properties, but without support for nulling
14.117 + * slots.) Since these combinations aren't supported using
14.118 + * ordinary volatiles, the only way to accomplish these
14.119 + * efficiently is to use direct Unsafe calls. (Using external
14.120 + * AtomicIntegers and AtomicReferenceArrays for the indices and
14.121 + * array is significantly slower because of memory locality and
14.122 + * indirection effects.)
14.123 + *
14.124 + * Further, performance on most platforms is very sensitive to
14.125 + * placement and sizing of the (resizable) queue array. Even
14.126 + * though these queues don't usually become all that big, the
14.127 + * initial size must be large enough to counteract cache
14.128 + * contention effects across multiple queues (especially in the
14.129 + * presence of GC cardmarking). Also, to improve thread-locality,
14.130 + * queues are currently initialized immediately after the thread
14.131 + * gets the initial signal to start processing tasks. However,
14.132 + * all queue-related methods except pushTask are written in a way
14.133 + * that allows them to instead be lazily allocated and/or disposed
14.134 + * of when empty. All together, these low-level implementation
14.135 + * choices produce as much as a factor of 4 performance
14.136 + * improvement compared to naive implementations, and enable the
14.137 + * processing of billions of tasks per second, sometimes at the
14.138 + * expense of ugliness.
14.139 + *
14.140 + * 2. Run control: The primary run control is based on a global
14.141 + * counter (activeCount) held by the pool. It uses an algorithm
14.142 + * similar to that in Herlihy and Shavit section 17.6 to cause
14.143 + * threads to eventually block when all threads declare they are
14.144 + * inactive. For this to work, threads must be declared active
14.145 + * when executing tasks, and before stealing a task. They must be
14.146 + * inactive before blocking on the Pool Barrier (awaiting a new
14.147 + * submission or other Pool event). In between, there is some free
14.148 + * play which we take advantage of to avoid contention and rapid
14.149 + * flickering of the global activeCount: If inactive, we activate
14.150 + * only if a victim queue appears to be nonempty (see above).
14.151 + * Similarly, a thread tries to inactivate only after a full scan
14.152 + * of other threads. The net effect is that contention on
14.153 + * activeCount is rarely a measurable performance issue. (There
14.154 + * are also a few other cases where we scan for work rather than
14.155 + * retry/block upon contention.)
14.156 + *
14.157 + * 3. Selection control. We maintain policy of always choosing to
14.158 + * run local tasks rather than stealing, and always trying to
14.159 + * steal tasks before trying to run a new submission. All steals
14.160 + * are currently performed in randomly-chosen deq-order. It may be
14.161 + * worthwhile to bias these with locality / anti-locality
14.162 + * information, but doing this well probably requires more
14.163 + * lower-level information from JVMs than currently provided.
14.164 + */
14.165 +
14.166 + /**
14.167 + * Capacity of work-stealing queue array upon initialization.
14.168 + * Must be a power of two. Initial size must be at least 2, but is
14.169 + * padded to minimize cache effects.
14.170 + */
14.171 + private static final int INITIAL_QUEUE_CAPACITY = 1 << 13;
14.172 +
14.173 + /**
14.174 + * Maximum work-stealing queue array size. Must be less than or
14.175 + * equal to 1 << 28 to ensure lack of index wraparound. (This
14.176 + * is less than usual bounds, because we need leftshift by 3
14.177 + * to be in int range).
14.178 + */
14.179 + private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 28;
14.180 +
14.181 + /**
14.182 + * The pool this thread works in. Accessed directly by ForkJoinTask.
14.183 + */
14.184 + final ForkJoinPool pool;
14.185 +
14.186 + /**
14.187 + * The work-stealing queue array. Size must be a power of two.
14.188 + * Initialized when thread starts, to improve memory locality.
14.189 + */
14.190 + private ForkJoinTask<?>[] queue;
14.191 +
14.192 + /**
14.193 + * Index (mod queue.length) of next queue slot to push to or pop
14.194 + * from. It is written only by owner thread, via ordered store.
14.195 + * Both sp and base are allowed to wrap around on overflow, but
14.196 + * (sp - base) still estimates size.
14.197 + */
14.198 + private volatile int sp;
14.199 +
14.200 + /**
14.201 + * Index (mod queue.length) of least valid queue slot, which is
14.202 + * always the next position to steal from if nonempty.
14.203 + */
14.204 + private volatile int base;
14.205 +
14.206 + /**
14.207 + * Activity status. When true, this worker is considered active.
14.208 + * Must be false upon construction. It must be true when executing
14.209 + * tasks, and BEFORE stealing a task. It must be false before
14.210 + * calling pool.sync.
14.211 + */
14.212 + private boolean active;
14.213 +
14.214 + /**
14.215 + * Run state of this worker. Supports simple versions of the usual
14.216 + * shutdown/shutdownNow control.
14.217 + */
14.218 + private volatile int runState;
14.219 +
14.220 + /**
14.221 + * Seed for random number generator for choosing steal victims.
14.222 + * Uses Marsaglia xorshift. Must be nonzero upon initialization.
14.223 + */
14.224 + private int seed;
14.225 +
14.226 + /**
14.227 + * Number of steals, transferred to pool when idle
14.228 + */
14.229 + private int stealCount;
14.230 +
14.231 + /**
14.232 + * Index of this worker in pool array. Set once by pool before
14.233 + * running, and accessed directly by pool during cleanup etc.
14.234 + */
14.235 + int poolIndex;
14.236 +
14.237 + /**
14.238 + * The last barrier event waited for. Accessed in pool callback
14.239 + * methods, but only by current thread.
14.240 + */
14.241 + long lastEventCount;
14.242 +
14.243 + /**
14.244 + * True if use local fifo, not default lifo, for local polling
14.245 + */
14.246 + private boolean locallyFifo;
14.247 +
14.248 + /**
14.249 + * Creates a ForkJoinWorkerThread operating in the given pool.
14.250 + *
14.251 + * @param pool the pool this thread works in
14.252 + * @throws NullPointerException if pool is null
14.253 + */
14.254 + protected ForkJoinWorkerThread(ForkJoinPool pool) {
14.255 + if (pool == null) throw new NullPointerException();
14.256 + this.pool = pool;
14.257 + // Note: poolIndex is set by pool during construction
14.258 + // Remaining initialization is deferred to onStart
14.259 + }
14.260 +
14.261 + // Public access methods
14.262 +
14.263 + /**
14.264 + * Returns the pool hosting this thread.
14.265 + *
14.266 + * @return the pool
14.267 + */
14.268 + public ForkJoinPool getPool() {
14.269 + return pool;
14.270 + }
14.271 +
14.272 + /**
14.273 + * Returns the index number of this thread in its pool. The
14.274 + * returned value ranges from zero to the maximum number of
14.275 + * threads (minus one) that have ever been created in the pool.
14.276 + * This method may be useful for applications that track status or
14.277 + * collect results per-worker rather than per-task.
14.278 + *
14.279 + * @return the index number
14.280 + */
14.281 + public int getPoolIndex() {
14.282 + return poolIndex;
14.283 + }
14.284 +
14.285 + /**
14.286 + * Establishes local first-in-first-out scheduling mode for forked
14.287 + * tasks that are never joined.
14.288 + *
14.289 + * @param async if true, use locally FIFO scheduling
14.290 + */
14.291 + void setAsyncMode(boolean async) {
14.292 + locallyFifo = async;
14.293 + }
14.294 +
14.295 + // Runstate management
14.296 +
14.297 + // Runstate values. Order matters
14.298 + private static final int RUNNING = 0;
14.299 + private static final int SHUTDOWN = 1;
14.300 + private static final int TERMINATING = 2;
14.301 + private static final int TERMINATED = 3;
14.302 +
14.303 + final boolean isShutdown() { return runState >= SHUTDOWN; }
14.304 + final boolean isTerminating() { return runState >= TERMINATING; }
14.305 + final boolean isTerminated() { return runState == TERMINATED; }
14.306 + final boolean shutdown() { return transitionRunStateTo(SHUTDOWN); }
14.307 + final boolean shutdownNow() { return transitionRunStateTo(TERMINATING); }
14.308 +
14.309 + /**
14.310 + * Transitions to at least the given state.
14.311 + *
14.312 + * @return {@code true} if not already at least at given state
14.313 + */
14.314 + private boolean transitionRunStateTo(int state) {
14.315 + for (;;) {
14.316 + int s = runState;
14.317 + if (s >= state)
14.318 + return false;
14.319 + if (UNSAFE.compareAndSwapInt(this, runStateOffset, s, state))
14.320 + return true;
14.321 + }
14.322 + }
14.323 +
14.324 + /**
14.325 + * Tries to set status to active; fails on contention.
14.326 + */
14.327 + private boolean tryActivate() {
14.328 + if (!active) {
14.329 + if (!pool.tryIncrementActiveCount())
14.330 + return false;
14.331 + active = true;
14.332 + }
14.333 + return true;
14.334 + }
14.335 +
14.336 + /**
14.337 + * Tries to set status to inactive; fails on contention.
14.338 + */
14.339 + private boolean tryInactivate() {
14.340 + if (active) {
14.341 + if (!pool.tryDecrementActiveCount())
14.342 + return false;
14.343 + active = false;
14.344 + }
14.345 + return true;
14.346 + }
14.347 +
14.348 + /**
14.349 + * Computes next value for random victim probe. Scans don't
14.350 + * require a very high quality generator, but also not a crummy
14.351 + * one. Marsaglia xor-shift is cheap and works well.
14.352 + */
14.353 + private static int xorShift(int r) {
14.354 + r ^= (r << 13);
14.355 + r ^= (r >>> 17);
14.356 + return r ^ (r << 5);
14.357 + }
14.358 +
14.359 + // Lifecycle methods
14.360 +
14.361 + /**
14.362 + * This method is required to be public, but should never be
14.363 + * called explicitly. It performs the main run loop to execute
14.364 + * ForkJoinTasks.
14.365 + */
14.366 + public void run() {
14.367 + Throwable exception = null;
14.368 + try {
14.369 + onStart();
14.370 + pool.sync(this); // await first pool event
14.371 + mainLoop();
14.372 + } catch (Throwable ex) {
14.373 + exception = ex;
14.374 + } finally {
14.375 + onTermination(exception);
14.376 + }
14.377 + }
14.378 +
14.379 + /**
14.380 + * Executes tasks until shut down.
14.381 + */
14.382 + private void mainLoop() {
14.383 + while (!isShutdown()) {
14.384 + ForkJoinTask<?> t = pollTask();
14.385 + if (t != null || (t = pollSubmission()) != null)
14.386 + t.quietlyExec();
14.387 + else if (tryInactivate())
14.388 + pool.sync(this);
14.389 + }
14.390 + }
14.391 +
14.392 + /**
14.393 + * Initializes internal state after construction but before
14.394 + * processing any tasks. If you override this method, you must
14.395 + * invoke super.onStart() at the beginning of the method.
14.396 + * Initialization requires care: Most fields must have legal
14.397 + * default values, to ensure that attempted accesses from other
14.398 + * threads work correctly even before this thread starts
14.399 + * processing tasks.
14.400 + */
14.401 + protected void onStart() {
14.402 + // Allocate while starting to improve chances of thread-local
14.403 + // isolation
14.404 + queue = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY];
14.405 + // Initial value of seed need not be especially random but
14.406 + // should differ across workers and must be nonzero
14.407 + int p = poolIndex + 1;
14.408 + seed = p + (p << 8) + (p << 16) + (p << 24); // spread bits
14.409 + }
14.410 +
14.411 + /**
14.412 + * Performs cleanup associated with termination of this worker
14.413 + * thread. If you override this method, you must invoke
14.414 + * {@code super.onTermination} at the end of the overridden method.
14.415 + *
14.416 + * @param exception the exception causing this thread to abort due
14.417 + * to an unrecoverable error, or {@code null} if completed normally
14.418 + */
14.419 + protected void onTermination(Throwable exception) {
14.420 + // Execute remaining local tasks unless aborting or terminating
14.421 + while (exception == null && pool.isProcessingTasks() && base != sp) {
14.422 + try {
14.423 + ForkJoinTask<?> t = popTask();
14.424 + if (t != null)
14.425 + t.quietlyExec();
14.426 + } catch (Throwable ex) {
14.427 + exception = ex;
14.428 + }
14.429 + }
14.430 + // Cancel other tasks, transition status, notify pool, and
14.431 + // propagate exception to uncaught exception handler
14.432 + try {
14.433 + do {} while (!tryInactivate()); // ensure inactive
14.434 + cancelTasks();
14.435 + runState = TERMINATED;
14.436 + pool.workerTerminated(this);
14.437 + } catch (Throwable ex) { // Shouldn't ever happen
14.438 + if (exception == null) // but if so, at least rethrown
14.439 + exception = ex;
14.440 + } finally {
14.441 + if (exception != null)
14.442 + ForkJoinTask.rethrowException(exception);
14.443 + }
14.444 + }
14.445 +
14.446 + // Intrinsics-based support for queue operations.
14.447 +
14.448 + private static long slotOffset(int i) {
14.449 + return ((long) i << qShift) + qBase;
14.450 + }
14.451 +
14.452 + /**
14.453 + * Adds in store-order the given task at given slot of q to null.
14.454 + * Caller must ensure q is non-null and index is in range.
14.455 + */
14.456 + private static void setSlot(ForkJoinTask<?>[] q, int i,
14.457 + ForkJoinTask<?> t) {
14.458 + UNSAFE.putOrderedObject(q, slotOffset(i), t);
14.459 + }
14.460 +
14.461 + /**
14.462 + * CAS given slot of q to null. Caller must ensure q is non-null
14.463 + * and index is in range.
14.464 + */
14.465 + private static boolean casSlotNull(ForkJoinTask<?>[] q, int i,
14.466 + ForkJoinTask<?> t) {
14.467 + return UNSAFE.compareAndSwapObject(q, slotOffset(i), t, null);
14.468 + }
14.469 +
14.470 + /**
14.471 + * Sets sp in store-order.
14.472 + */
14.473 + private void storeSp(int s) {
14.474 + UNSAFE.putOrderedInt(this, spOffset, s);
14.475 + }
14.476 +
14.477 + // Main queue methods
14.478 +
14.479 + /**
14.480 + * Pushes a task. Called only by current thread.
14.481 + *
14.482 + * @param t the task. Caller must ensure non-null.
14.483 + */
14.484 + final void pushTask(ForkJoinTask<?> t) {
14.485 + ForkJoinTask<?>[] q = queue;
14.486 + int mask = q.length - 1;
14.487 + int s = sp;
14.488 + setSlot(q, s & mask, t);
14.489 + storeSp(++s);
14.490 + if ((s -= base) == 1)
14.491 + pool.signalWork();
14.492 + else if (s >= mask)
14.493 + growQueue();
14.494 + }
14.495 +
14.496 + /**
14.497 + * Tries to take a task from the base of the queue, failing if
14.498 + * either empty or contended.
14.499 + *
14.500 + * @return a task, or null if none or contended
14.501 + */
14.502 + final ForkJoinTask<?> deqTask() {
14.503 + ForkJoinTask<?> t;
14.504 + ForkJoinTask<?>[] q;
14.505 + int i;
14.506 + int b;
14.507 + if (sp != (b = base) &&
14.508 + (q = queue) != null && // must read q after b
14.509 + (t = q[i = (q.length - 1) & b]) != null &&
14.510 + casSlotNull(q, i, t)) {
14.511 + base = b + 1;
14.512 + return t;
14.513 + }
14.514 + return null;
14.515 + }
14.516 +
14.517 + /**
14.518 + * Tries to take a task from the base of own queue, activating if
14.519 + * necessary, failing only if empty. Called only by current thread.
14.520 + *
14.521 + * @return a task, or null if none
14.522 + */
14.523 + final ForkJoinTask<?> locallyDeqTask() {
14.524 + int b;
14.525 + while (sp != (b = base)) {
14.526 + if (tryActivate()) {
14.527 + ForkJoinTask<?>[] q = queue;
14.528 + int i = (q.length - 1) & b;
14.529 + ForkJoinTask<?> t = q[i];
14.530 + if (t != null && casSlotNull(q, i, t)) {
14.531 + base = b + 1;
14.532 + return t;
14.533 + }
14.534 + }
14.535 + }
14.536 + return null;
14.537 + }
14.538 +
14.539 + /**
14.540 + * Returns a popped task, or null if empty. Ensures active status
14.541 + * if non-null. Called only by current thread.
14.542 + */
14.543 + final ForkJoinTask<?> popTask() {
14.544 + int s = sp;
14.545 + while (s != base) {
14.546 + if (tryActivate()) {
14.547 + ForkJoinTask<?>[] q = queue;
14.548 + int mask = q.length - 1;
14.549 + int i = (s - 1) & mask;
14.550 + ForkJoinTask<?> t = q[i];
14.551 + if (t == null || !casSlotNull(q, i, t))
14.552 + break;
14.553 + storeSp(s - 1);
14.554 + return t;
14.555 + }
14.556 + }
14.557 + return null;
14.558 + }
14.559 +
14.560 + /**
14.561 + * Specialized version of popTask to pop only if
14.562 + * topmost element is the given task. Called only
14.563 + * by current thread while active.
14.564 + *
14.565 + * @param t the task. Caller must ensure non-null.
14.566 + */
14.567 + final boolean unpushTask(ForkJoinTask<?> t) {
14.568 + ForkJoinTask<?>[] q = queue;
14.569 + int mask = q.length - 1;
14.570 + int s = sp - 1;
14.571 + if (casSlotNull(q, s & mask, t)) {
14.572 + storeSp(s);
14.573 + return true;
14.574 + }
14.575 + return false;
14.576 + }
14.577 +
14.578 + /**
14.579 + * Returns next task or null if empty or contended
14.580 + */
14.581 + final ForkJoinTask<?> peekTask() {
14.582 + ForkJoinTask<?>[] q = queue;
14.583 + if (q == null)
14.584 + return null;
14.585 + int mask = q.length - 1;
14.586 + int i = locallyFifo ? base : (sp - 1);
14.587 + return q[i & mask];
14.588 + }
14.589 +
14.590 + /**
14.591 + * Doubles queue array size. Transfers elements by emulating
14.592 + * steals (deqs) from old array and placing, oldest first, into
14.593 + * new array.
14.594 + */
14.595 + private void growQueue() {
14.596 + ForkJoinTask<?>[] oldQ = queue;
14.597 + int oldSize = oldQ.length;
14.598 + int newSize = oldSize << 1;
14.599 + if (newSize > MAXIMUM_QUEUE_CAPACITY)
14.600 + throw new RejectedExecutionException("Queue capacity exceeded");
14.601 + ForkJoinTask<?>[] newQ = queue = new ForkJoinTask<?>[newSize];
14.602 +
14.603 + int b = base;
14.604 + int bf = b + oldSize;
14.605 + int oldMask = oldSize - 1;
14.606 + int newMask = newSize - 1;
14.607 + do {
14.608 + int oldIndex = b & oldMask;
14.609 + ForkJoinTask<?> t = oldQ[oldIndex];
14.610 + if (t != null && !casSlotNull(oldQ, oldIndex, t))
14.611 + t = null;
14.612 + setSlot(newQ, b & newMask, t);
14.613 + } while (++b != bf);
14.614 + pool.signalWork();
14.615 + }
14.616 +
14.617 + /**
14.618 + * Tries to steal a task from another worker. Starts at a random
14.619 + * index of workers array, and probes workers until finding one
14.620 + * with non-empty queue or finding that all are empty. It
14.621 + * randomly selects the first n probes. If these are empty, it
14.622 + * resorts to a full circular traversal, which is necessary to
14.623 + * accurately set active status by caller. Also restarts if pool
14.624 + * events occurred since last scan, which forces refresh of
14.625 + * workers array, in case barrier was associated with resize.
14.626 + *
14.627 + * This method must be both fast and quiet -- usually avoiding
14.628 + * memory accesses that could disrupt cache sharing etc other than
14.629 + * those needed to check for and take tasks. This accounts for,
14.630 + * among other things, updating random seed in place without
14.631 + * storing it until exit.
14.632 + *
14.633 + * @return a task, or null if none found
14.634 + */
14.635 + private ForkJoinTask<?> scan() {
14.636 + ForkJoinTask<?> t = null;
14.637 + int r = seed; // extract once to keep scan quiet
14.638 + ForkJoinWorkerThread[] ws; // refreshed on outer loop
14.639 + int mask; // must be power 2 minus 1 and > 0
14.640 + outer:do {
14.641 + if ((ws = pool.workers) != null && (mask = ws.length - 1) > 0) {
14.642 + int idx = r;
14.643 + int probes = ~mask; // use random index while negative
14.644 + for (;;) {
14.645 + r = xorShift(r); // update random seed
14.646 + ForkJoinWorkerThread v = ws[mask & idx];
14.647 + if (v == null || v.sp == v.base) {
14.648 + if (probes <= mask)
14.649 + idx = (probes++ < 0) ? r : (idx + 1);
14.650 + else
14.651 + break;
14.652 + }
14.653 + else if (!tryActivate() || (t = v.deqTask()) == null)
14.654 + continue outer; // restart on contention
14.655 + else
14.656 + break outer;
14.657 + }
14.658 + }
14.659 + } while (pool.hasNewSyncEvent(this)); // retry on pool events
14.660 + seed = r;
14.661 + return t;
14.662 + }
14.663 +
14.664 + /**
14.665 + * Gets and removes a local or stolen task.
14.666 + *
14.667 + * @return a task, if available
14.668 + */
14.669 + final ForkJoinTask<?> pollTask() {
14.670 + ForkJoinTask<?> t = locallyFifo ? locallyDeqTask() : popTask();
14.671 + if (t == null && (t = scan()) != null)
14.672 + ++stealCount;
14.673 + return t;
14.674 + }
14.675 +
14.676 + /**
14.677 + * Gets a local task.
14.678 + *
14.679 + * @return a task, if available
14.680 + */
14.681 + final ForkJoinTask<?> pollLocalTask() {
14.682 + return locallyFifo ? locallyDeqTask() : popTask();
14.683 + }
14.684 +
14.685 + /**
14.686 + * Returns a pool submission, if one exists, activating first.
14.687 + *
14.688 + * @return a submission, if available
14.689 + */
14.690 + private ForkJoinTask<?> pollSubmission() {
14.691 + ForkJoinPool p = pool;
14.692 + while (p.hasQueuedSubmissions()) {
14.693 + ForkJoinTask<?> t;
14.694 + if (tryActivate() && (t = p.pollSubmission()) != null)
14.695 + return t;
14.696 + }
14.697 + return null;
14.698 + }
14.699 +
14.700 + // Methods accessed only by Pool
14.701 +
14.702 + /**
14.703 + * Removes and cancels all tasks in queue. Can be called from any
14.704 + * thread.
14.705 + */
14.706 + final void cancelTasks() {
14.707 + ForkJoinTask<?> t;
14.708 + while (base != sp && (t = deqTask()) != null)
14.709 + t.cancelIgnoringExceptions();
14.710 + }
14.711 +
14.712 + /**
14.713 + * Drains tasks to given collection c.
14.714 + *
14.715 + * @return the number of tasks drained
14.716 + */
14.717 + final int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
14.718 + int n = 0;
14.719 + ForkJoinTask<?> t;
14.720 + while (base != sp && (t = deqTask()) != null) {
14.721 + c.add(t);
14.722 + ++n;
14.723 + }
14.724 + return n;
14.725 + }
14.726 +
14.727 + /**
14.728 + * Gets and clears steal count for accumulation by pool. Called
14.729 + * only when known to be idle (in pool.sync and termination).
14.730 + */
14.731 + final int getAndClearStealCount() {
14.732 + int sc = stealCount;
14.733 + stealCount = 0;
14.734 + return sc;
14.735 + }
14.736 +
14.737 + /**
14.738 + * Returns {@code true} if at least one worker in the given array
14.739 + * appears to have at least one queued task.
14.740 + *
14.741 + * @param ws array of workers
14.742 + */
14.743 + static boolean hasQueuedTasks(ForkJoinWorkerThread[] ws) {
14.744 + if (ws != null) {
14.745 + int len = ws.length;
14.746 + for (int j = 0; j < 2; ++j) { // need two passes for clean sweep
14.747 + for (int i = 0; i < len; ++i) {
14.748 + ForkJoinWorkerThread w = ws[i];
14.749 + if (w != null && w.sp != w.base)
14.750 + return true;
14.751 + }
14.752 + }
14.753 + }
14.754 + return false;
14.755 + }
14.756 +
14.757 + // Support methods for ForkJoinTask
14.758 +
14.759 + /**
14.760 + * Returns an estimate of the number of tasks in the queue.
14.761 + */
14.762 + final int getQueueSize() {
14.763 + // suppress momentarily negative values
14.764 + return Math.max(0, sp - base);
14.765 + }
14.766 +
14.767 + /**
14.768 + * Returns an estimate of the number of tasks, offset by a
14.769 + * function of number of idle workers.
14.770 + */
14.771 + final int getEstimatedSurplusTaskCount() {
14.772 + // The halving approximates weighting idle vs non-idle workers
14.773 + return (sp - base) - (pool.getIdleThreadCount() >>> 1);
14.774 + }
14.775 +
14.776 + /**
14.777 + * Scans, returning early if joinMe done.
14.778 + */
14.779 + final ForkJoinTask<?> scanWhileJoining(ForkJoinTask<?> joinMe) {
14.780 + ForkJoinTask<?> t = pollTask();
14.781 + if (t != null && joinMe.status < 0 && sp == base) {
14.782 + pushTask(t); // unsteal if done and this task would be stealable
14.783 + t = null;
14.784 + }
14.785 + return t;
14.786 + }
14.787 +
14.788 + /**
14.789 + * Runs tasks until {@code pool.isQuiescent()}.
14.790 + */
14.791 + final void helpQuiescePool() {
14.792 + for (;;) {
14.793 + ForkJoinTask<?> t = pollTask();
14.794 + if (t != null)
14.795 + t.quietlyExec();
14.796 + else if (tryInactivate() && pool.isQuiescent())
14.797 + break;
14.798 + }
14.799 + do {} while (!tryActivate()); // re-activate on exit
14.800 + }
14.801 +
14.802 + // Unsafe mechanics
14.803 +
14.804 + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
14.805 + private static final long spOffset =
14.806 + objectFieldOffset("sp", ForkJoinWorkerThread.class);
14.807 + private static final long runStateOffset =
14.808 + objectFieldOffset("runState", ForkJoinWorkerThread.class);
14.809 + private static final long qBase;
14.810 + private static final int qShift;
14.811 +
14.812 + static {
14.813 + qBase = UNSAFE.arrayBaseOffset(ForkJoinTask[].class);
14.814 + int s = UNSAFE.arrayIndexScale(ForkJoinTask[].class);
14.815 + if ((s & (s-1)) != 0)
14.816 + throw new Error("data type scale not a power of two");
14.817 + qShift = 31 - Integer.numberOfLeadingZeros(s);
14.818 + }
14.819 +
14.820 + private static long objectFieldOffset(String field, Class<?> klazz) {
14.821 + try {
14.822 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
14.823 + } catch (NoSuchFieldException e) {
14.824 + // Convert Exception to corresponding Error
14.825 + NoSuchFieldError error = new NoSuchFieldError(field);
14.826 + error.initCause(e);
14.827 + throw error;
14.828 + }
14.829 + }
14.830 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Sun Nov 08 14:49:18 2009 -0800
15.3 @@ -0,0 +1,1270 @@
15.4 +/*
15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.6 + *
15.7 + * This code is free software; you can redistribute it and/or modify it
15.8 + * under the terms of the GNU General Public License version 2 only, as
15.9 + * published by the Free Software Foundation. Sun designates this
15.10 + * particular file as subject to the "Classpath" exception as provided
15.11 + * by Sun in the LICENSE file that accompanied this code.
15.12 + *
15.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
15.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15.16 + * version 2 for more details (a copy is included in the LICENSE file that
15.17 + * accompanied this code).
15.18 + *
15.19 + * You should have received a copy of the GNU General Public License version
15.20 + * 2 along with this work; if not, write to the Free Software Foundation,
15.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
15.22 + *
15.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
15.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
15.25 + * have any questions.
15.26 + */
15.27 +
15.28 +/*
15.29 + * This file is available under and governed by the GNU General Public
15.30 + * License version 2 only, as published by the Free Software Foundation.
15.31 + * However, the following notice accompanied the original version of this
15.32 + * file:
15.33 + *
15.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
15.35 + * Expert Group and released to the public domain, as explained at
15.36 + * http://creativecommons.org/licenses/publicdomain
15.37 + */
15.38 +
15.39 +package java.util.concurrent;
15.40 +
15.41 +import java.util.AbstractQueue;
15.42 +import java.util.Collection;
15.43 +import java.util.ConcurrentModificationException;
15.44 +import java.util.Iterator;
15.45 +import java.util.NoSuchElementException;
15.46 +import java.util.Queue;
15.47 +import java.util.concurrent.locks.LockSupport;
15.48 +/**
15.49 + * An unbounded {@link TransferQueue} based on linked nodes.
15.50 + * This queue orders elements FIFO (first-in-first-out) with respect
15.51 + * to any given producer. The <em>head</em> of the queue is that
15.52 + * element that has been on the queue the longest time for some
15.53 + * producer. The <em>tail</em> of the queue is that element that has
15.54 + * been on the queue the shortest time for some producer.
15.55 + *
15.56 + * <p>Beware that, unlike in most collections, the {@code size}
15.57 + * method is <em>NOT</em> a constant-time operation. Because of the
15.58 + * asynchronous nature of these queues, determining the current number
15.59 + * of elements requires a traversal of the elements.
15.60 + *
15.61 + * <p>This class and its iterator implement all of the
15.62 + * <em>optional</em> methods of the {@link Collection} and {@link
15.63 + * Iterator} interfaces.
15.64 + *
15.65 + * <p>Memory consistency effects: As with other concurrent
15.66 + * collections, actions in a thread prior to placing an object into a
15.67 + * {@code LinkedTransferQueue}
15.68 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
15.69 + * actions subsequent to the access or removal of that element from
15.70 + * the {@code LinkedTransferQueue} in another thread.
15.71 + *
15.72 + * <p>This class is a member of the
15.73 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
15.74 + * Java Collections Framework</a>.
15.75 + *
15.76 + * @since 1.7
15.77 + * @author Doug Lea
15.78 + * @param <E> the type of elements held in this collection
15.79 + */
15.80 +public class LinkedTransferQueue<E> extends AbstractQueue<E>
15.81 + implements TransferQueue<E>, java.io.Serializable {
15.82 + private static final long serialVersionUID = -3223113410248163686L;
15.83 +
15.84 + /*
15.85 + * *** Overview of Dual Queues with Slack ***
15.86 + *
15.87 + * Dual Queues, introduced by Scherer and Scott
15.88 + * (http://www.cs.rice.edu/~wns1/papers/2004-DISC-DDS.pdf) are
15.89 + * (linked) queues in which nodes may represent either data or
15.90 + * requests. When a thread tries to enqueue a data node, but
15.91 + * encounters a request node, it instead "matches" and removes it;
15.92 + * and vice versa for enqueuing requests. Blocking Dual Queues
15.93 + * arrange that threads enqueuing unmatched requests block until
15.94 + * other threads provide the match. Dual Synchronous Queues (see
15.95 + * Scherer, Lea, & Scott
15.96 + * http://www.cs.rochester.edu/u/scott/papers/2009_Scherer_CACM_SSQ.pdf)
15.97 + * additionally arrange that threads enqueuing unmatched data also
15.98 + * block. Dual Transfer Queues support all of these modes, as
15.99 + * dictated by callers.
15.100 + *
15.101 + * A FIFO dual queue may be implemented using a variation of the
15.102 + * Michael & Scott (M&S) lock-free queue algorithm
15.103 + * (http://www.cs.rochester.edu/u/scott/papers/1996_PODC_queues.pdf).
15.104 + * It maintains two pointer fields, "head", pointing to a
15.105 + * (matched) node that in turn points to the first actual
15.106 + * (unmatched) queue node (or null if empty); and "tail" that
15.107 + * points to the last node on the queue (or again null if
15.108 + * empty). For example, here is a possible queue with four data
15.109 + * elements:
15.110 + *
15.111 + * head tail
15.112 + * | |
15.113 + * v v
15.114 + * M -> U -> U -> U -> U
15.115 + *
15.116 + * The M&S queue algorithm is known to be prone to scalability and
15.117 + * overhead limitations when maintaining (via CAS) these head and
15.118 + * tail pointers. This has led to the development of
15.119 + * contention-reducing variants such as elimination arrays (see
15.120 + * Moir et al http://portal.acm.org/citation.cfm?id=1074013) and
15.121 + * optimistic back pointers (see Ladan-Mozes & Shavit
15.122 + * http://people.csail.mit.edu/edya/publications/OptimisticFIFOQueue-journal.pdf).
15.123 + * However, the nature of dual queues enables a simpler tactic for
15.124 + * improving M&S-style implementations when dual-ness is needed.
15.125 + *
15.126 + * In a dual queue, each node must atomically maintain its match
15.127 + * status. While there are other possible variants, we implement
15.128 + * this here as: for a data-mode node, matching entails CASing an
15.129 + * "item" field from a non-null data value to null upon match, and
15.130 + * vice-versa for request nodes, CASing from null to a data
15.131 + * value. (Note that the linearization properties of this style of
15.132 + * queue are easy to verify -- elements are made available by
15.133 + * linking, and unavailable by matching.) Compared to plain M&S
15.134 + * queues, this property of dual queues requires one additional
15.135 + * successful atomic operation per enq/deq pair. But it also
15.136 + * enables lower cost variants of queue maintenance mechanics. (A
15.137 + * variation of this idea applies even for non-dual queues that
15.138 + * support deletion of interior elements, such as
15.139 + * j.u.c.ConcurrentLinkedQueue.)
15.140 + *
15.141 + * Once a node is matched, its match status can never again
15.142 + * change. We may thus arrange that the linked list of them
15.143 + * contain a prefix of zero or more matched nodes, followed by a
15.144 + * suffix of zero or more unmatched nodes. (Note that we allow
15.145 + * both the prefix and suffix to be zero length, which in turn
15.146 + * means that we do not use a dummy header.) If we were not
15.147 + * concerned with either time or space efficiency, we could
15.148 + * correctly perform enqueue and dequeue operations by traversing
15.149 + * from a pointer to the initial node; CASing the item of the
15.150 + * first unmatched node on match and CASing the next field of the
15.151 + * trailing node on appends. (Plus some special-casing when
15.152 + * initially empty). While this would be a terrible idea in
15.153 + * itself, it does have the benefit of not requiring ANY atomic
15.154 + * updates on head/tail fields.
15.155 + *
15.156 + * We introduce here an approach that lies between the extremes of
15.157 + * never versus always updating queue (head and tail) pointers.
15.158 + * This offers a tradeoff between sometimes requiring extra
15.159 + * traversal steps to locate the first and/or last unmatched
15.160 + * nodes, versus the reduced overhead and contention of fewer
15.161 + * updates to queue pointers. For example, a possible snapshot of
15.162 + * a queue is:
15.163 + *
15.164 + * head tail
15.165 + * | |
15.166 + * v v
15.167 + * M -> M -> U -> U -> U -> U
15.168 + *
15.169 + * The best value for this "slack" (the targeted maximum distance
15.170 + * between the value of "head" and the first unmatched node, and
15.171 + * similarly for "tail") is an empirical matter. We have found
15.172 + * that using very small constants in the range of 1-3 work best
15.173 + * over a range of platforms. Larger values introduce increasing
15.174 + * costs of cache misses and risks of long traversal chains, while
15.175 + * smaller values increase CAS contention and overhead.
15.176 + *
15.177 + * Dual queues with slack differ from plain M&S dual queues by
15.178 + * virtue of only sometimes updating head or tail pointers when
15.179 + * matching, appending, or even traversing nodes; in order to
15.180 + * maintain a targeted slack. The idea of "sometimes" may be
15.181 + * operationalized in several ways. The simplest is to use a
15.182 + * per-operation counter incremented on each traversal step, and
15.183 + * to try (via CAS) to update the associated queue pointer
15.184 + * whenever the count exceeds a threshold. Another, that requires
15.185 + * more overhead, is to use random number generators to update
15.186 + * with a given probability per traversal step.
15.187 + *
15.188 + * In any strategy along these lines, because CASes updating
15.189 + * fields may fail, the actual slack may exceed targeted
15.190 + * slack. However, they may be retried at any time to maintain
15.191 + * targets. Even when using very small slack values, this
15.192 + * approach works well for dual queues because it allows all
15.193 + * operations up to the point of matching or appending an item
15.194 + * (hence potentially allowing progress by another thread) to be
15.195 + * read-only, thus not introducing any further contention. As
15.196 + * described below, we implement this by performing slack
15.197 + * maintenance retries only after these points.
15.198 + *
15.199 + * As an accompaniment to such techniques, traversal overhead can
15.200 + * be further reduced without increasing contention of head
15.201 + * pointer updates: Threads may sometimes shortcut the "next" link
15.202 + * path from the current "head" node to be closer to the currently
15.203 + * known first unmatched node, and similarly for tail. Again, this
15.204 + * may be triggered with using thresholds or randomization.
15.205 + *
15.206 + * These ideas must be further extended to avoid unbounded amounts
15.207 + * of costly-to-reclaim garbage caused by the sequential "next"
15.208 + * links of nodes starting at old forgotten head nodes: As first
15.209 + * described in detail by Boehm
15.210 + * (http://portal.acm.org/citation.cfm?doid=503272.503282) if a GC
15.211 + * delays noticing that any arbitrarily old node has become
15.212 + * garbage, all newer dead nodes will also be unreclaimed.
15.213 + * (Similar issues arise in non-GC environments.) To cope with
15.214 + * this in our implementation, upon CASing to advance the head
15.215 + * pointer, we set the "next" link of the previous head to point
15.216 + * only to itself; thus limiting the length of connected dead lists.
15.217 + * (We also take similar care to wipe out possibly garbage
15.218 + * retaining values held in other Node fields.) However, doing so
15.219 + * adds some further complexity to traversal: If any "next"
15.220 + * pointer links to itself, it indicates that the current thread
15.221 + * has lagged behind a head-update, and so the traversal must
15.222 + * continue from the "head". Traversals trying to find the
15.223 + * current tail starting from "tail" may also encounter
15.224 + * self-links, in which case they also continue at "head".
15.225 + *
15.226 + * It is tempting in slack-based scheme to not even use CAS for
15.227 + * updates (similarly to Ladan-Mozes & Shavit). However, this
15.228 + * cannot be done for head updates under the above link-forgetting
15.229 + * mechanics because an update may leave head at a detached node.
15.230 + * And while direct writes are possible for tail updates, they
15.231 + * increase the risk of long retraversals, and hence long garbage
15.232 + * chains, which can be much more costly than is worthwhile
15.233 + * considering that the cost difference of performing a CAS vs
15.234 + * write is smaller when they are not triggered on each operation
15.235 + * (especially considering that writes and CASes equally require
15.236 + * additional GC bookkeeping ("write barriers") that are sometimes
15.237 + * more costly than the writes themselves because of contention).
15.238 + *
15.239 + * Removal of interior nodes (due to timed out or interrupted
15.240 + * waits, or calls to remove(x) or Iterator.remove) can use a
15.241 + * scheme roughly similar to that described in Scherer, Lea, and
15.242 + * Scott's SynchronousQueue. Given a predecessor, we can unsplice
15.243 + * any node except the (actual) tail of the queue. To avoid
15.244 + * build-up of cancelled trailing nodes, upon a request to remove
15.245 + * a trailing node, it is placed in field "cleanMe" to be
15.246 + * unspliced upon the next call to unsplice any other node.
15.247 + * Situations needing such mechanics are not common but do occur
15.248 + * in practice; for example when an unbounded series of short
15.249 + * timed calls to poll repeatedly time out but never otherwise
15.250 + * fall off the list because of an untimed call to take at the
15.251 + * front of the queue. Note that maintaining field cleanMe does
15.252 + * not otherwise much impact garbage retention even if never
15.253 + * cleared by some other call because the held node will
15.254 + * eventually either directly or indirectly lead to a self-link
15.255 + * once off the list.
15.256 + *
15.257 + * *** Overview of implementation ***
15.258 + *
15.259 + * We use a threshold-based approach to updates, with a slack
15.260 + * threshold of two -- that is, we update head/tail when the
15.261 + * current pointer appears to be two or more steps away from the
15.262 + * first/last node. The slack value is hard-wired: a path greater
15.263 + * than one is naturally implemented by checking equality of
15.264 + * traversal pointers except when the list has only one element,
15.265 + * in which case we keep slack threshold at one. Avoiding tracking
15.266 + * explicit counts across method calls slightly simplifies an
15.267 + * already-messy implementation. Using randomization would
15.268 + * probably work better if there were a low-quality dirt-cheap
15.269 + * per-thread one available, but even ThreadLocalRandom is too
15.270 + * heavy for these purposes.
15.271 + *
15.272 + * With such a small slack threshold value, it is rarely
15.273 + * worthwhile to augment this with path short-circuiting; i.e.,
15.274 + * unsplicing nodes between head and the first unmatched node, or
15.275 + * similarly for tail, rather than advancing head or tail
15.276 + * proper. However, it is used (in awaitMatch) immediately before
15.277 + * a waiting thread starts to block, as a final bit of helping at
15.278 + * a point when contention with others is extremely unlikely
15.279 + * (since if other threads that could release it are operating,
15.280 + * then the current thread wouldn't be blocking).
15.281 + *
15.282 + * We allow both the head and tail fields to be null before any
15.283 + * nodes are enqueued; initializing upon first append. This
15.284 + * simplifies some other logic, as well as providing more
15.285 + * efficient explicit control paths instead of letting JVMs insert
15.286 + * implicit NullPointerExceptions when they are null. While not
15.287 + * currently fully implemented, we also leave open the possibility
15.288 + * of re-nulling these fields when empty (which is complicated to
15.289 + * arrange, for little benefit.)
15.290 + *
15.291 + * All enqueue/dequeue operations are handled by the single method
15.292 + * "xfer" with parameters indicating whether to act as some form
15.293 + * of offer, put, poll, take, or transfer (each possibly with
15.294 + * timeout). The relative complexity of using one monolithic
15.295 + * method outweighs the code bulk and maintenance problems of
15.296 + * using separate methods for each case.
15.297 + *
15.298 + * Operation consists of up to three phases. The first is
15.299 + * implemented within method xfer, the second in tryAppend, and
15.300 + * the third in method awaitMatch.
15.301 + *
15.302 + * 1. Try to match an existing node
15.303 + *
15.304 + * Starting at head, skip already-matched nodes until finding
15.305 + * an unmatched node of opposite mode, if one exists, in which
15.306 + * case matching it and returning, also if necessary updating
15.307 + * head to one past the matched node (or the node itself if the
15.308 + * list has no other unmatched nodes). If the CAS misses, then
15.309 + * a loop retries advancing head by two steps until either
15.310 + * success or the slack is at most two. By requiring that each
15.311 + * attempt advances head by two (if applicable), we ensure that
15.312 + * the slack does not grow without bound. Traversals also check
15.313 + * if the initial head is now off-list, in which case they
15.314 + * start at the new head.
15.315 + *
15.316 + * If no candidates are found and the call was untimed
15.317 + * poll/offer, (argument "how" is NOW) return.
15.318 + *
15.319 + * 2. Try to append a new node (method tryAppend)
15.320 + *
15.321 + * Starting at current tail pointer, find the actual last node
15.322 + * and try to append a new node (or if head was null, establish
15.323 + * the first node). Nodes can be appended only if their
15.324 + * predecessors are either already matched or are of the same
15.325 + * mode. If we detect otherwise, then a new node with opposite
15.326 + * mode must have been appended during traversal, so we must
15.327 + * restart at phase 1. The traversal and update steps are
15.328 + * otherwise similar to phase 1: Retrying upon CAS misses and
15.329 + * checking for staleness. In particular, if a self-link is
15.330 + * encountered, then we can safely jump to a node on the list
15.331 + * by continuing the traversal at current head.
15.332 + *
15.333 + * On successful append, if the call was ASYNC, return.
15.334 + *
15.335 + * 3. Await match or cancellation (method awaitMatch)
15.336 + *
15.337 + * Wait for another thread to match node; instead cancelling if
15.338 + * the current thread was interrupted or the wait timed out. On
15.339 + * multiprocessors, we use front-of-queue spinning: If a node
15.340 + * appears to be the first unmatched node in the queue, it
15.341 + * spins a bit before blocking. In either case, before blocking
15.342 + * it tries to unsplice any nodes between the current "head"
15.343 + * and the first unmatched node.
15.344 + *
15.345 + * Front-of-queue spinning vastly improves performance of
15.346 + * heavily contended queues. And so long as it is relatively
15.347 + * brief and "quiet", spinning does not much impact performance
15.348 + * of less-contended queues. During spins threads check their
15.349 + * interrupt status and generate a thread-local random number
15.350 + * to decide to occasionally perform a Thread.yield. While
15.351 + * yield has underdefined specs, we assume that might it help,
15.352 + * and will not hurt in limiting impact of spinning on busy
15.353 + * systems. We also use smaller (1/2) spins for nodes that are
15.354 + * not known to be front but whose predecessors have not
15.355 + * blocked -- these "chained" spins avoid artifacts of
15.356 + * front-of-queue rules which otherwise lead to alternating
15.357 + * nodes spinning vs blocking. Further, front threads that
15.358 + * represent phase changes (from data to request node or vice
15.359 + * versa) compared to their predecessors receive additional
15.360 + * chained spins, reflecting longer paths typically required to
15.361 + * unblock threads during phase changes.
15.362 + */
15.363 +
15.364 + /** True if on multiprocessor */
15.365 + private static final boolean MP =
15.366 + Runtime.getRuntime().availableProcessors() > 1;
15.367 +
15.368 + /**
15.369 + * The number of times to spin (with randomly interspersed calls
15.370 + * to Thread.yield) on multiprocessor before blocking when a node
15.371 + * is apparently the first waiter in the queue. See above for
15.372 + * explanation. Must be a power of two. The value is empirically
15.373 + * derived -- it works pretty well across a variety of processors,
15.374 + * numbers of CPUs, and OSes.
15.375 + */
15.376 + private static final int FRONT_SPINS = 1 << 7;
15.377 +
15.378 + /**
15.379 + * The number of times to spin before blocking when a node is
15.380 + * preceded by another node that is apparently spinning. Also
15.381 + * serves as an increment to FRONT_SPINS on phase changes, and as
15.382 + * base average frequency for yielding during spins. Must be a
15.383 + * power of two.
15.384 + */
15.385 + private static final int CHAINED_SPINS = FRONT_SPINS >>> 1;
15.386 +
15.387 + /**
15.388 + * Queue nodes. Uses Object, not E, for items to allow forgetting
15.389 + * them after use. Relies heavily on Unsafe mechanics to minimize
15.390 + * unnecessary ordering constraints: Writes that intrinsically
15.391 + * precede or follow CASes use simple relaxed forms. Other
15.392 + * cleanups use releasing/lazy writes.
15.393 + */
15.394 + static final class Node {
15.395 + final boolean isData; // false if this is a request node
15.396 + volatile Object item; // initially non-null if isData; CASed to match
15.397 + volatile Node next;
15.398 + volatile Thread waiter; // null until waiting
15.399 +
15.400 + // CAS methods for fields
15.401 + final boolean casNext(Node cmp, Node val) {
15.402 + return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
15.403 + }
15.404 +
15.405 + final boolean casItem(Object cmp, Object val) {
15.406 + // assert cmp == null || cmp.getClass() != Node.class;
15.407 + return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
15.408 + }
15.409 +
15.410 + /**
15.411 + * Creates a new node. Uses relaxed write because item can only
15.412 + * be seen if followed by CAS.
15.413 + */
15.414 + Node(Object item, boolean isData) {
15.415 + UNSAFE.putObject(this, itemOffset, item); // relaxed write
15.416 + this.isData = isData;
15.417 + }
15.418 +
15.419 + /**
15.420 + * Links node to itself to avoid garbage retention. Called
15.421 + * only after CASing head field, so uses relaxed write.
15.422 + */
15.423 + final void forgetNext() {
15.424 + UNSAFE.putObject(this, nextOffset, this);
15.425 + }
15.426 +
15.427 + /**
15.428 + * Sets item to self (using a releasing/lazy write) and waiter
15.429 + * to null, to avoid garbage retention after extracting or
15.430 + * cancelling.
15.431 + */
15.432 + final void forgetContents() {
15.433 + UNSAFE.putOrderedObject(this, itemOffset, this);
15.434 + UNSAFE.putOrderedObject(this, waiterOffset, null);
15.435 + }
15.436 +
15.437 + /**
15.438 + * Returns true if this node has been matched, including the
15.439 + * case of artificial matches due to cancellation.
15.440 + */
15.441 + final boolean isMatched() {
15.442 + Object x = item;
15.443 + return (x == this) || ((x == null) == isData);
15.444 + }
15.445 +
15.446 + /**
15.447 + * Returns true if this is an unmatched request node.
15.448 + */
15.449 + final boolean isUnmatchedRequest() {
15.450 + return !isData && item == null;
15.451 + }
15.452 +
15.453 + /**
15.454 + * Returns true if a node with the given mode cannot be
15.455 + * appended to this node because this node is unmatched and
15.456 + * has opposite data mode.
15.457 + */
15.458 + final boolean cannotPrecede(boolean haveData) {
15.459 + boolean d = isData;
15.460 + Object x;
15.461 + return d != haveData && (x = item) != this && (x != null) == d;
15.462 + }
15.463 +
15.464 + /**
15.465 + * Tries to artificially match a data node -- used by remove.
15.466 + */
15.467 + final boolean tryMatchData() {
15.468 + // assert isData;
15.469 + Object x = item;
15.470 + if (x != null && x != this && casItem(x, null)) {
15.471 + LockSupport.unpark(waiter);
15.472 + return true;
15.473 + }
15.474 + return false;
15.475 + }
15.476 +
15.477 + // Unsafe mechanics
15.478 + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
15.479 + private static final long nextOffset =
15.480 + objectFieldOffset(UNSAFE, "next", Node.class);
15.481 + private static final long itemOffset =
15.482 + objectFieldOffset(UNSAFE, "item", Node.class);
15.483 + private static final long waiterOffset =
15.484 + objectFieldOffset(UNSAFE, "waiter", Node.class);
15.485 +
15.486 + private static final long serialVersionUID = -3375979862319811754L;
15.487 + }
15.488 +
15.489 + /** head of the queue; null until first enqueue */
15.490 + transient volatile Node head;
15.491 +
15.492 + /** predecessor of dangling unspliceable node */
15.493 + private transient volatile Node cleanMe; // decl here reduces contention
15.494 +
15.495 + /** tail of the queue; null until first append */
15.496 + private transient volatile Node tail;
15.497 +
15.498 + // CAS methods for fields
15.499 + private boolean casTail(Node cmp, Node val) {
15.500 + return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
15.501 + }
15.502 +
15.503 + private boolean casHead(Node cmp, Node val) {
15.504 + return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
15.505 + }
15.506 +
15.507 + private boolean casCleanMe(Node cmp, Node val) {
15.508 + return UNSAFE.compareAndSwapObject(this, cleanMeOffset, cmp, val);
15.509 + }
15.510 +
15.511 + /*
15.512 + * Possible values for "how" argument in xfer method.
15.513 + */
15.514 + private static final int NOW = 0; // for untimed poll, tryTransfer
15.515 + private static final int ASYNC = 1; // for offer, put, add
15.516 + private static final int SYNC = 2; // for transfer, take
15.517 + private static final int TIMED = 3; // for timed poll, tryTransfer
15.518 +
15.519 + @SuppressWarnings("unchecked")
15.520 + static <E> E cast(Object item) {
15.521 + // assert item == null || item.getClass() != Node.class;
15.522 + return (E) item;
15.523 + }
15.524 +
15.525 + /**
15.526 + * Implements all queuing methods. See above for explanation.
15.527 + *
15.528 + * @param e the item or null for take
15.529 + * @param haveData true if this is a put, else a take
15.530 + * @param how NOW, ASYNC, SYNC, or TIMED
15.531 + * @param nanos timeout in nanosecs, used only if mode is TIMED
15.532 + * @return an item if matched, else e
15.533 + * @throws NullPointerException if haveData mode but e is null
15.534 + */
15.535 + private E xfer(E e, boolean haveData, int how, long nanos) {
15.536 + if (haveData && (e == null))
15.537 + throw new NullPointerException();
15.538 + Node s = null; // the node to append, if needed
15.539 +
15.540 + retry: for (;;) { // restart on append race
15.541 +
15.542 + for (Node h = head, p = h; p != null;) { // find & match first node
15.543 + boolean isData = p.isData;
15.544 + Object item = p.item;
15.545 + if (item != p && (item != null) == isData) { // unmatched
15.546 + if (isData == haveData) // can't match
15.547 + break;
15.548 + if (p.casItem(item, e)) { // match
15.549 + for (Node q = p; q != h;) {
15.550 + Node n = q.next; // update head by 2
15.551 + if (n != null) // unless singleton
15.552 + q = n;
15.553 + if (head == h && casHead(h, q)) {
15.554 + h.forgetNext();
15.555 + break;
15.556 + } // advance and retry
15.557 + if ((h = head) == null ||
15.558 + (q = h.next) == null || !q.isMatched())
15.559 + break; // unless slack < 2
15.560 + }
15.561 + LockSupport.unpark(p.waiter);
15.562 + return this.<E>cast(item);
15.563 + }
15.564 + }
15.565 + Node n = p.next;
15.566 + p = (p != n) ? n : (h = head); // Use head if p offlist
15.567 + }
15.568 +
15.569 + if (how != NOW) { // No matches available
15.570 + if (s == null)
15.571 + s = new Node(e, haveData);
15.572 + Node pred = tryAppend(s, haveData);
15.573 + if (pred == null)
15.574 + continue retry; // lost race vs opposite mode
15.575 + if (how != ASYNC)
15.576 + return awaitMatch(s, pred, e, (how == TIMED), nanos);
15.577 + }
15.578 + return e; // not waiting
15.579 + }
15.580 + }
15.581 +
15.582 + /**
15.583 + * Tries to append node s as tail.
15.584 + *
15.585 + * @param s the node to append
15.586 + * @param haveData true if appending in data mode
15.587 + * @return null on failure due to losing race with append in
15.588 + * different mode, else s's predecessor, or s itself if no
15.589 + * predecessor
15.590 + */
15.591 + private Node tryAppend(Node s, boolean haveData) {
15.592 + for (Node t = tail, p = t;;) { // move p to last node and append
15.593 + Node n, u; // temps for reads of next & tail
15.594 + if (p == null && (p = head) == null) {
15.595 + if (casHead(null, s))
15.596 + return s; // initialize
15.597 + }
15.598 + else if (p.cannotPrecede(haveData))
15.599 + return null; // lost race vs opposite mode
15.600 + else if ((n = p.next) != null) // not last; keep traversing
15.601 + p = p != t && t != (u = tail) ? (t = u) : // stale tail
15.602 + (p != n) ? n : null; // restart if off list
15.603 + else if (!p.casNext(null, s))
15.604 + p = p.next; // re-read on CAS failure
15.605 + else {
15.606 + if (p != t) { // update if slack now >= 2
15.607 + while ((tail != t || !casTail(t, s)) &&
15.608 + (t = tail) != null &&
15.609 + (s = t.next) != null && // advance and retry
15.610 + (s = s.next) != null && s != t);
15.611 + }
15.612 + return p;
15.613 + }
15.614 + }
15.615 + }
15.616 +
15.617 + /**
15.618 + * Spins/yields/blocks until node s is matched or caller gives up.
15.619 + *
15.620 + * @param s the waiting node
15.621 + * @param pred the predecessor of s, or s itself if it has no
15.622 + * predecessor, or null if unknown (the null case does not occur
15.623 + * in any current calls but may in possible future extensions)
15.624 + * @param e the comparison value for checking match
15.625 + * @param timed if true, wait only until timeout elapses
15.626 + * @param nanos timeout in nanosecs, used only if timed is true
15.627 + * @return matched item, or e if unmatched on interrupt or timeout
15.628 + */
15.629 + private E awaitMatch(Node s, Node pred, E e, boolean timed, long nanos) {
15.630 + long lastTime = timed ? System.nanoTime() : 0L;
15.631 + Thread w = Thread.currentThread();
15.632 + int spins = -1; // initialized after first item and cancel checks
15.633 + ThreadLocalRandom randomYields = null; // bound if needed
15.634 +
15.635 + for (;;) {
15.636 + Object item = s.item;
15.637 + if (item != e) { // matched
15.638 + // assert item != s;
15.639 + s.forgetContents(); // avoid garbage
15.640 + return this.<E>cast(item);
15.641 + }
15.642 + if ((w.isInterrupted() || (timed && nanos <= 0)) &&
15.643 + s.casItem(e, s)) { // cancel
15.644 + unsplice(pred, s);
15.645 + return e;
15.646 + }
15.647 +
15.648 + if (spins < 0) { // establish spins at/near front
15.649 + if ((spins = spinsFor(pred, s.isData)) > 0)
15.650 + randomYields = ThreadLocalRandom.current();
15.651 + }
15.652 + else if (spins > 0) { // spin
15.653 + if (--spins == 0)
15.654 + shortenHeadPath(); // reduce slack before blocking
15.655 + else if (randomYields.nextInt(CHAINED_SPINS) == 0)
15.656 + Thread.yield(); // occasionally yield
15.657 + }
15.658 + else if (s.waiter == null) {
15.659 + s.waiter = w; // request unpark then recheck
15.660 + }
15.661 + else if (timed) {
15.662 + long now = System.nanoTime();
15.663 + if ((nanos -= now - lastTime) > 0)
15.664 + LockSupport.parkNanos(this, nanos);
15.665 + lastTime = now;
15.666 + }
15.667 + else {
15.668 + LockSupport.park(this);
15.669 + s.waiter = null;
15.670 + spins = -1; // spin if front upon wakeup
15.671 + }
15.672 + }
15.673 + }
15.674 +
15.675 + /**
15.676 + * Returns spin/yield value for a node with given predecessor and
15.677 + * data mode. See above for explanation.
15.678 + */
15.679 + private static int spinsFor(Node pred, boolean haveData) {
15.680 + if (MP && pred != null) {
15.681 + if (pred.isData != haveData) // phase change
15.682 + return FRONT_SPINS + CHAINED_SPINS;
15.683 + if (pred.isMatched()) // probably at front
15.684 + return FRONT_SPINS;
15.685 + if (pred.waiter == null) // pred apparently spinning
15.686 + return CHAINED_SPINS;
15.687 + }
15.688 + return 0;
15.689 + }
15.690 +
15.691 + /**
15.692 + * Tries (once) to unsplice nodes between head and first unmatched
15.693 + * or trailing node; failing on contention.
15.694 + */
15.695 + private void shortenHeadPath() {
15.696 + Node h, hn, p, q;
15.697 + if ((p = h = head) != null && h.isMatched() &&
15.698 + (q = hn = h.next) != null) {
15.699 + Node n;
15.700 + while ((n = q.next) != q) {
15.701 + if (n == null || !q.isMatched()) {
15.702 + if (hn != q && h.next == hn)
15.703 + h.casNext(hn, q);
15.704 + break;
15.705 + }
15.706 + p = q;
15.707 + q = n;
15.708 + }
15.709 + }
15.710 + }
15.711 +
15.712 + /* -------------- Traversal methods -------------- */
15.713 +
15.714 + /**
15.715 + * Returns the successor of p, or the head node if p.next has been
15.716 + * linked to self, which will only be true if traversing with a
15.717 + * stale pointer that is now off the list.
15.718 + */
15.719 + final Node succ(Node p) {
15.720 + Node next = p.next;
15.721 + return (p == next) ? head : next;
15.722 + }
15.723 +
15.724 + /**
15.725 + * Returns the first unmatched node of the given mode, or null if
15.726 + * none. Used by methods isEmpty, hasWaitingConsumer.
15.727 + */
15.728 + private Node firstOfMode(boolean isData) {
15.729 + for (Node p = head; p != null; p = succ(p)) {
15.730 + if (!p.isMatched())
15.731 + return (p.isData == isData) ? p : null;
15.732 + }
15.733 + return null;
15.734 + }
15.735 +
15.736 + /**
15.737 + * Returns the item in the first unmatched node with isData; or
15.738 + * null if none. Used by peek.
15.739 + */
15.740 + private E firstDataItem() {
15.741 + for (Node p = head; p != null; p = succ(p)) {
15.742 + Object item = p.item;
15.743 + if (p.isData) {
15.744 + if (item != null && item != p)
15.745 + return this.<E>cast(item);
15.746 + }
15.747 + else if (item == null)
15.748 + return null;
15.749 + }
15.750 + return null;
15.751 + }
15.752 +
15.753 + /**
15.754 + * Traverses and counts unmatched nodes of the given mode.
15.755 + * Used by methods size and getWaitingConsumerCount.
15.756 + */
15.757 + private int countOfMode(boolean data) {
15.758 + int count = 0;
15.759 + for (Node p = head; p != null; ) {
15.760 + if (!p.isMatched()) {
15.761 + if (p.isData != data)
15.762 + return 0;
15.763 + if (++count == Integer.MAX_VALUE) // saturated
15.764 + break;
15.765 + }
15.766 + Node n = p.next;
15.767 + if (n != p)
15.768 + p = n;
15.769 + else {
15.770 + count = 0;
15.771 + p = head;
15.772 + }
15.773 + }
15.774 + return count;
15.775 + }
15.776 +
15.777 + final class Itr implements Iterator<E> {
15.778 + private Node nextNode; // next node to return item for
15.779 + private E nextItem; // the corresponding item
15.780 + private Node lastRet; // last returned node, to support remove
15.781 + private Node lastPred; // predecessor to unlink lastRet
15.782 +
15.783 + /**
15.784 + * Moves to next node after prev, or first node if prev null.
15.785 + */
15.786 + private void advance(Node prev) {
15.787 + lastPred = lastRet;
15.788 + lastRet = prev;
15.789 + for (Node p = (prev == null) ? head : succ(prev);
15.790 + p != null; p = succ(p)) {
15.791 + Object item = p.item;
15.792 + if (p.isData) {
15.793 + if (item != null && item != p) {
15.794 + nextItem = LinkedTransferQueue.this.<E>cast(item);
15.795 + nextNode = p;
15.796 + return;
15.797 + }
15.798 + }
15.799 + else if (item == null)
15.800 + break;
15.801 + }
15.802 + nextNode = null;
15.803 + }
15.804 +
15.805 + Itr() {
15.806 + advance(null);
15.807 + }
15.808 +
15.809 + public final boolean hasNext() {
15.810 + return nextNode != null;
15.811 + }
15.812 +
15.813 + public final E next() {
15.814 + Node p = nextNode;
15.815 + if (p == null) throw new NoSuchElementException();
15.816 + E e = nextItem;
15.817 + advance(p);
15.818 + return e;
15.819 + }
15.820 +
15.821 + public final void remove() {
15.822 + Node p = lastRet;
15.823 + if (p == null) throw new IllegalStateException();
15.824 + findAndRemoveDataNode(lastPred, p);
15.825 + }
15.826 + }
15.827 +
15.828 + /* -------------- Removal methods -------------- */
15.829 +
15.830 + /**
15.831 + * Unsplices (now or later) the given deleted/cancelled node with
15.832 + * the given predecessor.
15.833 + *
15.834 + * @param pred predecessor of node to be unspliced
15.835 + * @param s the node to be unspliced
15.836 + */
15.837 + private void unsplice(Node pred, Node s) {
15.838 + s.forgetContents(); // clear unneeded fields
15.839 + /*
15.840 + * At any given time, exactly one node on list cannot be
15.841 + * unlinked -- the last inserted node. To accommodate this, if
15.842 + * we cannot unlink s, we save its predecessor as "cleanMe",
15.843 + * processing the previously saved version first. Because only
15.844 + * one node in the list can have a null next, at least one of
15.845 + * node s or the node previously saved can always be
15.846 + * processed, so this always terminates.
15.847 + */
15.848 + if (pred != null && pred != s) {
15.849 + while (pred.next == s) {
15.850 + Node oldpred = (cleanMe == null) ? null : reclean();
15.851 + Node n = s.next;
15.852 + if (n != null) {
15.853 + if (n != s)
15.854 + pred.casNext(s, n);
15.855 + break;
15.856 + }
15.857 + if (oldpred == pred || // Already saved
15.858 + ((oldpred == null || oldpred.next == s) &&
15.859 + casCleanMe(oldpred, pred))) {
15.860 + break;
15.861 + }
15.862 + }
15.863 + }
15.864 + }
15.865 +
15.866 + /**
15.867 + * Tries to unsplice the deleted/cancelled node held in cleanMe
15.868 + * that was previously uncleanable because it was at tail.
15.869 + *
15.870 + * @return current cleanMe node (or null)
15.871 + */
15.872 + private Node reclean() {
15.873 + /*
15.874 + * cleanMe is, or at one time was, predecessor of a cancelled
15.875 + * node s that was the tail so could not be unspliced. If it
15.876 + * is no longer the tail, try to unsplice if necessary and
15.877 + * make cleanMe slot available. This differs from similar
15.878 + * code in unsplice() because we must check that pred still
15.879 + * points to a matched node that can be unspliced -- if not,
15.880 + * we can (must) clear cleanMe without unsplicing. This can
15.881 + * loop only due to contention.
15.882 + */
15.883 + Node pred;
15.884 + while ((pred = cleanMe) != null) {
15.885 + Node s = pred.next;
15.886 + Node n;
15.887 + if (s == null || s == pred || !s.isMatched())
15.888 + casCleanMe(pred, null); // already gone
15.889 + else if ((n = s.next) != null) {
15.890 + if (n != s)
15.891 + pred.casNext(s, n);
15.892 + casCleanMe(pred, null);
15.893 + }
15.894 + else
15.895 + break;
15.896 + }
15.897 + return pred;
15.898 + }
15.899 +
15.900 + /**
15.901 + * Main implementation of Iterator.remove(). Finds
15.902 + * and unsplices the given data node.
15.903 + *
15.904 + * @param possiblePred possible predecessor of s
15.905 + * @param s the node to remove
15.906 + */
15.907 + final void findAndRemoveDataNode(Node possiblePred, Node s) {
15.908 + // assert s.isData;
15.909 + if (s.tryMatchData()) {
15.910 + if (possiblePred != null && possiblePred.next == s)
15.911 + unsplice(possiblePred, s); // was actual predecessor
15.912 + else {
15.913 + for (Node pred = null, p = head; p != null; ) {
15.914 + if (p == s) {
15.915 + unsplice(pred, p);
15.916 + break;
15.917 + }
15.918 + if (p.isUnmatchedRequest())
15.919 + break;
15.920 + pred = p;
15.921 + if ((p = p.next) == pred) { // stale
15.922 + pred = null;
15.923 + p = head;
15.924 + }
15.925 + }
15.926 + }
15.927 + }
15.928 + }
15.929 +
15.930 + /**
15.931 + * Main implementation of remove(Object)
15.932 + */
15.933 + private boolean findAndRemove(Object e) {
15.934 + if (e != null) {
15.935 + for (Node pred = null, p = head; p != null; ) {
15.936 + Object item = p.item;
15.937 + if (p.isData) {
15.938 + if (item != null && item != p && e.equals(item) &&
15.939 + p.tryMatchData()) {
15.940 + unsplice(pred, p);
15.941 + return true;
15.942 + }
15.943 + }
15.944 + else if (item == null)
15.945 + break;
15.946 + pred = p;
15.947 + if ((p = p.next) == pred) { // stale
15.948 + pred = null;
15.949 + p = head;
15.950 + }
15.951 + }
15.952 + }
15.953 + return false;
15.954 + }
15.955 +
15.956 +
15.957 + /**
15.958 + * Creates an initially empty {@code LinkedTransferQueue}.
15.959 + */
15.960 + public LinkedTransferQueue() {
15.961 + }
15.962 +
15.963 + /**
15.964 + * Creates a {@code LinkedTransferQueue}
15.965 + * initially containing the elements of the given collection,
15.966 + * added in traversal order of the collection's iterator.
15.967 + *
15.968 + * @param c the collection of elements to initially contain
15.969 + * @throws NullPointerException if the specified collection or any
15.970 + * of its elements are null
15.971 + */
15.972 + public LinkedTransferQueue(Collection<? extends E> c) {
15.973 + this();
15.974 + addAll(c);
15.975 + }
15.976 +
15.977 + /**
15.978 + * Inserts the specified element at the tail of this queue.
15.979 + * As the queue is unbounded, this method will never block.
15.980 + *
15.981 + * @throws NullPointerException if the specified element is null
15.982 + */
15.983 + public void put(E e) {
15.984 + xfer(e, true, ASYNC, 0);
15.985 + }
15.986 +
15.987 + /**
15.988 + * Inserts the specified element at the tail of this queue.
15.989 + * As the queue is unbounded, this method will never block or
15.990 + * return {@code false}.
15.991 + *
15.992 + * @return {@code true} (as specified by
15.993 + * {@link BlockingQueue#offer(Object,long,TimeUnit) BlockingQueue.offer})
15.994 + * @throws NullPointerException if the specified element is null
15.995 + */
15.996 + public boolean offer(E e, long timeout, TimeUnit unit) {
15.997 + xfer(e, true, ASYNC, 0);
15.998 + return true;
15.999 + }
15.1000 +
15.1001 + /**
15.1002 + * Inserts the specified element at the tail of this queue.
15.1003 + * As the queue is unbounded, this method will never return {@code false}.
15.1004 + *
15.1005 + * @return {@code true} (as specified by
15.1006 + * {@link BlockingQueue#offer(Object) BlockingQueue.offer})
15.1007 + * @throws NullPointerException if the specified element is null
15.1008 + */
15.1009 + public boolean offer(E e) {
15.1010 + xfer(e, true, ASYNC, 0);
15.1011 + return true;
15.1012 + }
15.1013 +
15.1014 + /**
15.1015 + * Inserts the specified element at the tail of this queue.
15.1016 + * As the queue is unbounded, this method will never throw
15.1017 + * {@link IllegalStateException} or return {@code false}.
15.1018 + *
15.1019 + * @return {@code true} (as specified by {@link Collection#add})
15.1020 + * @throws NullPointerException if the specified element is null
15.1021 + */
15.1022 + public boolean add(E e) {
15.1023 + xfer(e, true, ASYNC, 0);
15.1024 + return true;
15.1025 + }
15.1026 +
15.1027 + /**
15.1028 + * Transfers the element to a waiting consumer immediately, if possible.
15.1029 + *
15.1030 + * <p>More precisely, transfers the specified element immediately
15.1031 + * if there exists a consumer already waiting to receive it (in
15.1032 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
15.1033 + * otherwise returning {@code false} without enqueuing the element.
15.1034 + *
15.1035 + * @throws NullPointerException if the specified element is null
15.1036 + */
15.1037 + public boolean tryTransfer(E e) {
15.1038 + return xfer(e, true, NOW, 0) == null;
15.1039 + }
15.1040 +
15.1041 + /**
15.1042 + * Transfers the element to a consumer, waiting if necessary to do so.
15.1043 + *
15.1044 + * <p>More precisely, transfers the specified element immediately
15.1045 + * if there exists a consumer already waiting to receive it (in
15.1046 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
15.1047 + * else inserts the specified element at the tail of this queue
15.1048 + * and waits until the element is received by a consumer.
15.1049 + *
15.1050 + * @throws NullPointerException if the specified element is null
15.1051 + */
15.1052 + public void transfer(E e) throws InterruptedException {
15.1053 + if (xfer(e, true, SYNC, 0) != null) {
15.1054 + Thread.interrupted(); // failure possible only due to interrupt
15.1055 + throw new InterruptedException();
15.1056 + }
15.1057 + }
15.1058 +
15.1059 + /**
15.1060 + * Transfers the element to a consumer if it is possible to do so
15.1061 + * before the timeout elapses.
15.1062 + *
15.1063 + * <p>More precisely, transfers the specified element immediately
15.1064 + * if there exists a consumer already waiting to receive it (in
15.1065 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
15.1066 + * else inserts the specified element at the tail of this queue
15.1067 + * and waits until the element is received by a consumer,
15.1068 + * returning {@code false} if the specified wait time elapses
15.1069 + * before the element can be transferred.
15.1070 + *
15.1071 + * @throws NullPointerException if the specified element is null
15.1072 + */
15.1073 + public boolean tryTransfer(E e, long timeout, TimeUnit unit)
15.1074 + throws InterruptedException {
15.1075 + if (xfer(e, true, TIMED, unit.toNanos(timeout)) == null)
15.1076 + return true;
15.1077 + if (!Thread.interrupted())
15.1078 + return false;
15.1079 + throw new InterruptedException();
15.1080 + }
15.1081 +
15.1082 + public E take() throws InterruptedException {
15.1083 + E e = xfer(null, false, SYNC, 0);
15.1084 + if (e != null)
15.1085 + return e;
15.1086 + Thread.interrupted();
15.1087 + throw new InterruptedException();
15.1088 + }
15.1089 +
15.1090 + public E poll(long timeout, TimeUnit unit) throws InterruptedException {
15.1091 + E e = xfer(null, false, TIMED, unit.toNanos(timeout));
15.1092 + if (e != null || !Thread.interrupted())
15.1093 + return e;
15.1094 + throw new InterruptedException();
15.1095 + }
15.1096 +
15.1097 + public E poll() {
15.1098 + return xfer(null, false, NOW, 0);
15.1099 + }
15.1100 +
15.1101 + /**
15.1102 + * @throws NullPointerException {@inheritDoc}
15.1103 + * @throws IllegalArgumentException {@inheritDoc}
15.1104 + */
15.1105 + public int drainTo(Collection<? super E> c) {
15.1106 + if (c == null)
15.1107 + throw new NullPointerException();
15.1108 + if (c == this)
15.1109 + throw new IllegalArgumentException();
15.1110 + int n = 0;
15.1111 + E e;
15.1112 + while ( (e = poll()) != null) {
15.1113 + c.add(e);
15.1114 + ++n;
15.1115 + }
15.1116 + return n;
15.1117 + }
15.1118 +
15.1119 + /**
15.1120 + * @throws NullPointerException {@inheritDoc}
15.1121 + * @throws IllegalArgumentException {@inheritDoc}
15.1122 + */
15.1123 + public int drainTo(Collection<? super E> c, int maxElements) {
15.1124 + if (c == null)
15.1125 + throw new NullPointerException();
15.1126 + if (c == this)
15.1127 + throw new IllegalArgumentException();
15.1128 + int n = 0;
15.1129 + E e;
15.1130 + while (n < maxElements && (e = poll()) != null) {
15.1131 + c.add(e);
15.1132 + ++n;
15.1133 + }
15.1134 + return n;
15.1135 + }
15.1136 +
15.1137 + /**
15.1138 + * Returns an iterator over the elements in this queue in proper
15.1139 + * sequence, from head to tail.
15.1140 + *
15.1141 + * <p>The returned iterator is a "weakly consistent" iterator that
15.1142 + * will never throw
15.1143 + * {@link ConcurrentModificationException ConcurrentModificationException},
15.1144 + * and guarantees to traverse elements as they existed upon
15.1145 + * construction of the iterator, and may (but is not guaranteed
15.1146 + * to) reflect any modifications subsequent to construction.
15.1147 + *
15.1148 + * @return an iterator over the elements in this queue in proper sequence
15.1149 + */
15.1150 + public Iterator<E> iterator() {
15.1151 + return new Itr();
15.1152 + }
15.1153 +
15.1154 + public E peek() {
15.1155 + return firstDataItem();
15.1156 + }
15.1157 +
15.1158 + /**
15.1159 + * Returns {@code true} if this queue contains no elements.
15.1160 + *
15.1161 + * @return {@code true} if this queue contains no elements
15.1162 + */
15.1163 + public boolean isEmpty() {
15.1164 + return firstOfMode(true) == null;
15.1165 + }
15.1166 +
15.1167 + public boolean hasWaitingConsumer() {
15.1168 + return firstOfMode(false) != null;
15.1169 + }
15.1170 +
15.1171 + /**
15.1172 + * Returns the number of elements in this queue. If this queue
15.1173 + * contains more than {@code Integer.MAX_VALUE} elements, returns
15.1174 + * {@code Integer.MAX_VALUE}.
15.1175 + *
15.1176 + * <p>Beware that, unlike in most collections, this method is
15.1177 + * <em>NOT</em> a constant-time operation. Because of the
15.1178 + * asynchronous nature of these queues, determining the current
15.1179 + * number of elements requires an O(n) traversal.
15.1180 + *
15.1181 + * @return the number of elements in this queue
15.1182 + */
15.1183 + public int size() {
15.1184 + return countOfMode(true);
15.1185 + }
15.1186 +
15.1187 + public int getWaitingConsumerCount() {
15.1188 + return countOfMode(false);
15.1189 + }
15.1190 +
15.1191 + /**
15.1192 + * Removes a single instance of the specified element from this queue,
15.1193 + * if it is present. More formally, removes an element {@code e} such
15.1194 + * that {@code o.equals(e)}, if this queue contains one or more such
15.1195 + * elements.
15.1196 + * Returns {@code true} if this queue contained the specified element
15.1197 + * (or equivalently, if this queue changed as a result of the call).
15.1198 + *
15.1199 + * @param o element to be removed from this queue, if present
15.1200 + * @return {@code true} if this queue changed as a result of the call
15.1201 + */
15.1202 + public boolean remove(Object o) {
15.1203 + return findAndRemove(o);
15.1204 + }
15.1205 +
15.1206 + /**
15.1207 + * Always returns {@code Integer.MAX_VALUE} because a
15.1208 + * {@code LinkedTransferQueue} is not capacity constrained.
15.1209 + *
15.1210 + * @return {@code Integer.MAX_VALUE} (as specified by
15.1211 + * {@link BlockingQueue#remainingCapacity()})
15.1212 + */
15.1213 + public int remainingCapacity() {
15.1214 + return Integer.MAX_VALUE;
15.1215 + }
15.1216 +
15.1217 + /**
15.1218 + * Saves the state to a stream (that is, serializes it).
15.1219 + *
15.1220 + * @serialData All of the elements (each an {@code E}) in
15.1221 + * the proper order, followed by a null
15.1222 + * @param s the stream
15.1223 + */
15.1224 + private void writeObject(java.io.ObjectOutputStream s)
15.1225 + throws java.io.IOException {
15.1226 + s.defaultWriteObject();
15.1227 + for (E e : this)
15.1228 + s.writeObject(e);
15.1229 + // Use trailing null as sentinel
15.1230 + s.writeObject(null);
15.1231 + }
15.1232 +
15.1233 + /**
15.1234 + * Reconstitutes the Queue instance from a stream (that is,
15.1235 + * deserializes it).
15.1236 + *
15.1237 + * @param s the stream
15.1238 + */
15.1239 + private void readObject(java.io.ObjectInputStream s)
15.1240 + throws java.io.IOException, ClassNotFoundException {
15.1241 + s.defaultReadObject();
15.1242 + for (;;) {
15.1243 + @SuppressWarnings("unchecked") E item = (E) s.readObject();
15.1244 + if (item == null)
15.1245 + break;
15.1246 + else
15.1247 + offer(item);
15.1248 + }
15.1249 + }
15.1250 +
15.1251 + // Unsafe mechanics
15.1252 +
15.1253 + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
15.1254 + private static final long headOffset =
15.1255 + objectFieldOffset(UNSAFE, "head", LinkedTransferQueue.class);
15.1256 + private static final long tailOffset =
15.1257 + objectFieldOffset(UNSAFE, "tail", LinkedTransferQueue.class);
15.1258 + private static final long cleanMeOffset =
15.1259 + objectFieldOffset(UNSAFE, "cleanMe", LinkedTransferQueue.class);
15.1260 +
15.1261 + static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
15.1262 + String field, Class<?> klazz) {
15.1263 + try {
15.1264 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
15.1265 + } catch (NoSuchFieldException e) {
15.1266 + // Convert Exception to corresponding Error
15.1267 + NoSuchFieldError error = new NoSuchFieldError(field);
15.1268 + error.initCause(e);
15.1269 + throw error;
15.1270 + }
15.1271 + }
15.1272 +
15.1273 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/src/share/classes/java/util/concurrent/Phaser.java Sun Nov 08 14:49:18 2009 -0800
16.3 @@ -0,0 +1,1042 @@
16.4 +/*
16.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.6 + *
16.7 + * This code is free software; you can redistribute it and/or modify it
16.8 + * under the terms of the GNU General Public License version 2 only, as
16.9 + * published by the Free Software Foundation. Sun designates this
16.10 + * particular file as subject to the "Classpath" exception as provided
16.11 + * by Sun in the LICENSE file that accompanied this code.
16.12 + *
16.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
16.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16.16 + * version 2 for more details (a copy is included in the LICENSE file that
16.17 + * accompanied this code).
16.18 + *
16.19 + * You should have received a copy of the GNU General Public License version
16.20 + * 2 along with this work; if not, write to the Free Software Foundation,
16.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16.22 + *
16.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
16.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
16.25 + * have any questions.
16.26 + */
16.27 +
16.28 +/*
16.29 + * This file is available under and governed by the GNU General Public
16.30 + * License version 2 only, as published by the Free Software Foundation.
16.31 + * However, the following notice accompanied the original version of this
16.32 + * file:
16.33 + *
16.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
16.35 + * Expert Group and released to the public domain, as explained at
16.36 + * http://creativecommons.org/licenses/publicdomain
16.37 + */
16.38 +
16.39 +package java.util.concurrent;
16.40 +
16.41 +import java.util.concurrent.atomic.AtomicReference;
16.42 +import java.util.concurrent.locks.LockSupport;
16.43 +
16.44 +/**
16.45 + * A reusable synchronization barrier, similar in functionality to
16.46 + * {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and
16.47 + * {@link java.util.concurrent.CountDownLatch CountDownLatch}
16.48 + * but supporting more flexible usage.
16.49 + *
16.50 + * <p> <b>Registration.</b> Unlike the case for other barriers, the
16.51 + * number of parties <em>registered</em> to synchronize on a phaser
16.52 + * may vary over time. Tasks may be registered at any time (using
16.53 + * methods {@link #register}, {@link #bulkRegister}, or forms of
16.54 + * constructors establishing initial numbers of parties), and
16.55 + * optionally deregistered upon any arrival (using {@link
16.56 + * #arriveAndDeregister}). As is the case with most basic
16.57 + * synchronization constructs, registration and deregistration affect
16.58 + * only internal counts; they do not establish any further internal
16.59 + * bookkeeping, so tasks cannot query whether they are registered.
16.60 + * (However, you can introduce such bookkeeping by subclassing this
16.61 + * class.)
16.62 + *
16.63 + * <p> <b>Synchronization.</b> Like a {@code CyclicBarrier}, a {@code
16.64 + * Phaser} may be repeatedly awaited. Method {@link
16.65 + * #arriveAndAwaitAdvance} has effect analogous to {@link
16.66 + * java.util.concurrent.CyclicBarrier#await CyclicBarrier.await}. Each
16.67 + * generation of a {@code Phaser} has an associated phase number. The
16.68 + * phase number starts at zero, and advances when all parties arrive
16.69 + * at the barrier, wrapping around to zero after reaching {@code
16.70 + * Integer.MAX_VALUE}. The use of phase numbers enables independent
16.71 + * control of actions upon arrival at a barrier and upon awaiting
16.72 + * others, via two kinds of methods that may be invoked by any
16.73 + * registered party:
16.74 + *
16.75 + * <ul>
16.76 + *
16.77 + * <li> <b>Arrival.</b> Methods {@link #arrive} and
16.78 + * {@link #arriveAndDeregister} record arrival at a
16.79 + * barrier. These methods do not block, but return an associated
16.80 + * <em>arrival phase number</em>; that is, the phase number of
16.81 + * the barrier to which the arrival applied. When the final
16.82 + * party for a given phase arrives, an optional barrier action
16.83 + * is performed and the phase advances. Barrier actions,
16.84 + * performed by the party triggering a phase advance, are
16.85 + * arranged by overriding method {@link #onAdvance(int, int)},
16.86 + * which also controls termination. Overriding this method is
16.87 + * similar to, but more flexible than, providing a barrier
16.88 + * action to a {@code CyclicBarrier}.
16.89 + *
16.90 + * <li> <b>Waiting.</b> Method {@link #awaitAdvance} requires an
16.91 + * argument indicating an arrival phase number, and returns when
16.92 + * the barrier advances to (or is already at) a different phase.
16.93 + * Unlike similar constructions using {@code CyclicBarrier},
16.94 + * method {@code awaitAdvance} continues to wait even if the
16.95 + * waiting thread is interrupted. Interruptible and timeout
16.96 + * versions are also available, but exceptions encountered while
16.97 + * tasks wait interruptibly or with timeout do not change the
16.98 + * state of the barrier. If necessary, you can perform any
16.99 + * associated recovery within handlers of those exceptions,
16.100 + * often after invoking {@code forceTermination}. Phasers may
16.101 + * also be used by tasks executing in a {@link ForkJoinPool},
16.102 + * which will ensure sufficient parallelism to execute tasks
16.103 + * when others are blocked waiting for a phase to advance.
16.104 + *
16.105 + * </ul>
16.106 + *
16.107 + * <p> <b>Termination.</b> A {@code Phaser} may enter a
16.108 + * <em>termination</em> state in which all synchronization methods
16.109 + * immediately return without updating phaser state or waiting for
16.110 + * advance, and indicating (via a negative phase value) that execution
16.111 + * is complete. Termination is triggered when an invocation of {@code
16.112 + * onAdvance} returns {@code true}. As illustrated below, when
16.113 + * phasers control actions with a fixed number of iterations, it is
16.114 + * often convenient to override this method to cause termination when
16.115 + * the current phase number reaches a threshold. Method {@link
16.116 + * #forceTermination} is also available to abruptly release waiting
16.117 + * threads and allow them to terminate.
16.118 + *
16.119 + * <p> <b>Tiering.</b> Phasers may be <em>tiered</em> (i.e., arranged
16.120 + * in tree structures) to reduce contention. Phasers with large
16.121 + * numbers of parties that would otherwise experience heavy
16.122 + * synchronization contention costs may instead be set up so that
16.123 + * groups of sub-phasers share a common parent. This may greatly
16.124 + * increase throughput even though it incurs greater per-operation
16.125 + * overhead.
16.126 + *
16.127 + * <p><b>Monitoring.</b> While synchronization methods may be invoked
16.128 + * only by registered parties, the current state of a phaser may be
16.129 + * monitored by any caller. At any given moment there are {@link
16.130 + * #getRegisteredParties} parties in total, of which {@link
16.131 + * #getArrivedParties} have arrived at the current phase ({@link
16.132 + * #getPhase}). When the remaining ({@link #getUnarrivedParties})
16.133 + * parties arrive, the phase advances. The values returned by these
16.134 + * methods may reflect transient states and so are not in general
16.135 + * useful for synchronization control. Method {@link #toString}
16.136 + * returns snapshots of these state queries in a form convenient for
16.137 + * informal monitoring.
16.138 + *
16.139 + * <p><b>Sample usages:</b>
16.140 + *
16.141 + * <p>A {@code Phaser} may be used instead of a {@code CountDownLatch}
16.142 + * to control a one-shot action serving a variable number of
16.143 + * parties. The typical idiom is for the method setting this up to
16.144 + * first register, then start the actions, then deregister, as in:
16.145 + *
16.146 + * <pre> {@code
16.147 + * void runTasks(List<Runnable> tasks) {
16.148 + * final Phaser phaser = new Phaser(1); // "1" to register self
16.149 + * // create and start threads
16.150 + * for (Runnable task : tasks) {
16.151 + * phaser.register();
16.152 + * new Thread() {
16.153 + * public void run() {
16.154 + * phaser.arriveAndAwaitAdvance(); // await all creation
16.155 + * task.run();
16.156 + * }
16.157 + * }.start();
16.158 + * }
16.159 + *
16.160 + * // allow threads to start and deregister self
16.161 + * phaser.arriveAndDeregister();
16.162 + * }}</pre>
16.163 + *
16.164 + * <p>One way to cause a set of threads to repeatedly perform actions
16.165 + * for a given number of iterations is to override {@code onAdvance}:
16.166 + *
16.167 + * <pre> {@code
16.168 + * void startTasks(List<Runnable> tasks, final int iterations) {
16.169 + * final Phaser phaser = new Phaser() {
16.170 + * protected boolean onAdvance(int phase, int registeredParties) {
16.171 + * return phase >= iterations || registeredParties == 0;
16.172 + * }
16.173 + * };
16.174 + * phaser.register();
16.175 + * for (final Runnable task : tasks) {
16.176 + * phaser.register();
16.177 + * new Thread() {
16.178 + * public void run() {
16.179 + * do {
16.180 + * task.run();
16.181 + * phaser.arriveAndAwaitAdvance();
16.182 + * } while (!phaser.isTerminated());
16.183 + * }
16.184 + * }.start();
16.185 + * }
16.186 + * phaser.arriveAndDeregister(); // deregister self, don't wait
16.187 + * }}</pre>
16.188 + *
16.189 + * If the main task must later await termination, it
16.190 + * may re-register and then execute a similar loop:
16.191 + * <pre> {@code
16.192 + * // ...
16.193 + * phaser.register();
16.194 + * while (!phaser.isTerminated())
16.195 + * phaser.arriveAndAwaitAdvance();}</pre>
16.196 + *
16.197 + * <p>Related constructions may be used to await particular phase numbers
16.198 + * in contexts where you are sure that the phase will never wrap around
16.199 + * {@code Integer.MAX_VALUE}. For example:
16.200 + *
16.201 + * <pre> {@code
16.202 + * void awaitPhase(Phaser phaser, int phase) {
16.203 + * int p = phaser.register(); // assumes caller not already registered
16.204 + * while (p < phase) {
16.205 + * if (phaser.isTerminated())
16.206 + * // ... deal with unexpected termination
16.207 + * else
16.208 + * p = phaser.arriveAndAwaitAdvance();
16.209 + * }
16.210 + * phaser.arriveAndDeregister();
16.211 + * }}</pre>
16.212 + *
16.213 + *
16.214 + * <p>To create a set of tasks using a tree of phasers,
16.215 + * you could use code of the following form, assuming a
16.216 + * Task class with a constructor accepting a phaser that
16.217 + * it registers for upon construction:
16.218 + *
16.219 + * <pre> {@code
16.220 + * void build(Task[] actions, int lo, int hi, Phaser ph) {
16.221 + * if (hi - lo > TASKS_PER_PHASER) {
16.222 + * for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
16.223 + * int j = Math.min(i + TASKS_PER_PHASER, hi);
16.224 + * build(actions, i, j, new Phaser(ph));
16.225 + * }
16.226 + * } else {
16.227 + * for (int i = lo; i < hi; ++i)
16.228 + * actions[i] = new Task(ph);
16.229 + * // assumes new Task(ph) performs ph.register()
16.230 + * }
16.231 + * }
16.232 + * // .. initially called, for n tasks via
16.233 + * build(new Task[n], 0, n, new Phaser());}</pre>
16.234 + *
16.235 + * The best value of {@code TASKS_PER_PHASER} depends mainly on
16.236 + * expected barrier synchronization rates. A value as low as four may
16.237 + * be appropriate for extremely small per-barrier task bodies (thus
16.238 + * high rates), or up to hundreds for extremely large ones.
16.239 + *
16.240 + * </pre>
16.241 + *
16.242 + * <p><b>Implementation notes</b>: This implementation restricts the
16.243 + * maximum number of parties to 65535. Attempts to register additional
16.244 + * parties result in {@code IllegalStateException}. However, you can and
16.245 + * should create tiered phasers to accommodate arbitrarily large sets
16.246 + * of participants.
16.247 + *
16.248 + * @since 1.7
16.249 + * @author Doug Lea
16.250 + */
16.251 +public class Phaser {
16.252 + /*
16.253 + * This class implements an extension of X10 "clocks". Thanks to
16.254 + * Vijay Saraswat for the idea, and to Vivek Sarkar for
16.255 + * enhancements to extend functionality.
16.256 + */
16.257 +
16.258 + /**
16.259 + * Barrier state representation. Conceptually, a barrier contains
16.260 + * four values:
16.261 + *
16.262 + * * parties -- the number of parties to wait (16 bits)
16.263 + * * unarrived -- the number of parties yet to hit barrier (16 bits)
16.264 + * * phase -- the generation of the barrier (31 bits)
16.265 + * * terminated -- set if barrier is terminated (1 bit)
16.266 + *
16.267 + * However, to efficiently maintain atomicity, these values are
16.268 + * packed into a single (atomic) long. Termination uses the sign
16.269 + * bit of 32 bit representation of phase, so phase is set to -1 on
16.270 + * termination. Good performance relies on keeping state decoding
16.271 + * and encoding simple, and keeping race windows short.
16.272 + *
16.273 + * Note: there are some cheats in arrive() that rely on unarrived
16.274 + * count being lowest 16 bits.
16.275 + */
16.276 + private volatile long state;
16.277 +
16.278 + private static final int ushortMask = 0xffff;
16.279 + private static final int phaseMask = 0x7fffffff;
16.280 +
16.281 + private static int unarrivedOf(long s) {
16.282 + return (int) (s & ushortMask);
16.283 + }
16.284 +
16.285 + private static int partiesOf(long s) {
16.286 + return ((int) s) >>> 16;
16.287 + }
16.288 +
16.289 + private static int phaseOf(long s) {
16.290 + return (int) (s >>> 32);
16.291 + }
16.292 +
16.293 + private static int arrivedOf(long s) {
16.294 + return partiesOf(s) - unarrivedOf(s);
16.295 + }
16.296 +
16.297 + private static long stateFor(int phase, int parties, int unarrived) {
16.298 + return ((((long) phase) << 32) | (((long) parties) << 16) |
16.299 + (long) unarrived);
16.300 + }
16.301 +
16.302 + private static long trippedStateFor(int phase, int parties) {
16.303 + long lp = (long) parties;
16.304 + return (((long) phase) << 32) | (lp << 16) | lp;
16.305 + }
16.306 +
16.307 + /**
16.308 + * Returns message string for bad bounds exceptions.
16.309 + */
16.310 + private static String badBounds(int parties, int unarrived) {
16.311 + return ("Attempt to set " + unarrived +
16.312 + " unarrived of " + parties + " parties");
16.313 + }
16.314 +
16.315 + /**
16.316 + * The parent of this phaser, or null if none
16.317 + */
16.318 + private final Phaser parent;
16.319 +
16.320 + /**
16.321 + * The root of phaser tree. Equals this if not in a tree. Used to
16.322 + * support faster state push-down.
16.323 + */
16.324 + private final Phaser root;
16.325 +
16.326 + // Wait queues
16.327 +
16.328 + /**
16.329 + * Heads of Treiber stacks for waiting threads. To eliminate
16.330 + * contention while releasing some threads while adding others, we
16.331 + * use two of them, alternating across even and odd phases.
16.332 + */
16.333 + private final AtomicReference<QNode> evenQ = new AtomicReference<QNode>();
16.334 + private final AtomicReference<QNode> oddQ = new AtomicReference<QNode>();
16.335 +
16.336 + private AtomicReference<QNode> queueFor(int phase) {
16.337 + return ((phase & 1) == 0) ? evenQ : oddQ;
16.338 + }
16.339 +
16.340 + /**
16.341 + * Returns current state, first resolving lagged propagation from
16.342 + * root if necessary.
16.343 + */
16.344 + private long getReconciledState() {
16.345 + return (parent == null) ? state : reconcileState();
16.346 + }
16.347 +
16.348 + /**
16.349 + * Recursively resolves state.
16.350 + */
16.351 + private long reconcileState() {
16.352 + Phaser p = parent;
16.353 + long s = state;
16.354 + if (p != null) {
16.355 + while (unarrivedOf(s) == 0 && phaseOf(s) != phaseOf(root.state)) {
16.356 + long parentState = p.getReconciledState();
16.357 + int parentPhase = phaseOf(parentState);
16.358 + int phase = phaseOf(s = state);
16.359 + if (phase != parentPhase) {
16.360 + long next = trippedStateFor(parentPhase, partiesOf(s));
16.361 + if (casState(s, next)) {
16.362 + releaseWaiters(phase);
16.363 + s = next;
16.364 + }
16.365 + }
16.366 + }
16.367 + }
16.368 + return s;
16.369 + }
16.370 +
16.371 + /**
16.372 + * Creates a new phaser without any initially registered parties,
16.373 + * initial phase number 0, and no parent. Any thread using this
16.374 + * phaser will need to first register for it.
16.375 + */
16.376 + public Phaser() {
16.377 + this(null);
16.378 + }
16.379 +
16.380 + /**
16.381 + * Creates a new phaser with the given numbers of registered
16.382 + * unarrived parties, initial phase number 0, and no parent.
16.383 + *
16.384 + * @param parties the number of parties required to trip barrier
16.385 + * @throws IllegalArgumentException if parties less than zero
16.386 + * or greater than the maximum number of parties supported
16.387 + */
16.388 + public Phaser(int parties) {
16.389 + this(null, parties);
16.390 + }
16.391 +
16.392 + /**
16.393 + * Creates a new phaser with the given parent, without any
16.394 + * initially registered parties. If parent is non-null this phaser
16.395 + * is registered with the parent and its initial phase number is
16.396 + * the same as that of parent phaser.
16.397 + *
16.398 + * @param parent the parent phaser
16.399 + */
16.400 + public Phaser(Phaser parent) {
16.401 + int phase = 0;
16.402 + this.parent = parent;
16.403 + if (parent != null) {
16.404 + this.root = parent.root;
16.405 + phase = parent.register();
16.406 + }
16.407 + else
16.408 + this.root = this;
16.409 + this.state = trippedStateFor(phase, 0);
16.410 + }
16.411 +
16.412 + /**
16.413 + * Creates a new phaser with the given parent and numbers of
16.414 + * registered unarrived parties. If parent is non-null, this phaser
16.415 + * is registered with the parent and its initial phase number is
16.416 + * the same as that of parent phaser.
16.417 + *
16.418 + * @param parent the parent phaser
16.419 + * @param parties the number of parties required to trip barrier
16.420 + * @throws IllegalArgumentException if parties less than zero
16.421 + * or greater than the maximum number of parties supported
16.422 + */
16.423 + public Phaser(Phaser parent, int parties) {
16.424 + if (parties < 0 || parties > ushortMask)
16.425 + throw new IllegalArgumentException("Illegal number of parties");
16.426 + int phase = 0;
16.427 + this.parent = parent;
16.428 + if (parent != null) {
16.429 + this.root = parent.root;
16.430 + phase = parent.register();
16.431 + }
16.432 + else
16.433 + this.root = this;
16.434 + this.state = trippedStateFor(phase, parties);
16.435 + }
16.436 +
16.437 + /**
16.438 + * Adds a new unarrived party to this phaser.
16.439 + *
16.440 + * @return the arrival phase number to which this registration applied
16.441 + * @throws IllegalStateException if attempting to register more
16.442 + * than the maximum supported number of parties
16.443 + */
16.444 + public int register() {
16.445 + return doRegister(1);
16.446 + }
16.447 +
16.448 + /**
16.449 + * Adds the given number of new unarrived parties to this phaser.
16.450 + *
16.451 + * @param parties the number of parties required to trip barrier
16.452 + * @return the arrival phase number to which this registration applied
16.453 + * @throws IllegalStateException if attempting to register more
16.454 + * than the maximum supported number of parties
16.455 + */
16.456 + public int bulkRegister(int parties) {
16.457 + if (parties < 0)
16.458 + throw new IllegalArgumentException();
16.459 + if (parties == 0)
16.460 + return getPhase();
16.461 + return doRegister(parties);
16.462 + }
16.463 +
16.464 + /**
16.465 + * Shared code for register, bulkRegister
16.466 + */
16.467 + private int doRegister(int registrations) {
16.468 + int phase;
16.469 + for (;;) {
16.470 + long s = getReconciledState();
16.471 + phase = phaseOf(s);
16.472 + int unarrived = unarrivedOf(s) + registrations;
16.473 + int parties = partiesOf(s) + registrations;
16.474 + if (phase < 0)
16.475 + break;
16.476 + if (parties > ushortMask || unarrived > ushortMask)
16.477 + throw new IllegalStateException(badBounds(parties, unarrived));
16.478 + if (phase == phaseOf(root.state) &&
16.479 + casState(s, stateFor(phase, parties, unarrived)))
16.480 + break;
16.481 + }
16.482 + return phase;
16.483 + }
16.484 +
16.485 + /**
16.486 + * Arrives at the barrier, but does not wait for others. (You can
16.487 + * in turn wait for others via {@link #awaitAdvance}). It is an
16.488 + * unenforced usage error for an unregistered party to invoke this
16.489 + * method.
16.490 + *
16.491 + * @return the arrival phase number, or a negative value if terminated
16.492 + * @throws IllegalStateException if not terminated and the number
16.493 + * of unarrived parties would become negative
16.494 + */
16.495 + public int arrive() {
16.496 + int phase;
16.497 + for (;;) {
16.498 + long s = state;
16.499 + phase = phaseOf(s);
16.500 + if (phase < 0)
16.501 + break;
16.502 + int parties = partiesOf(s);
16.503 + int unarrived = unarrivedOf(s) - 1;
16.504 + if (unarrived > 0) { // Not the last arrival
16.505 + if (casState(s, s - 1)) // s-1 adds one arrival
16.506 + break;
16.507 + }
16.508 + else if (unarrived == 0) { // the last arrival
16.509 + Phaser par = parent;
16.510 + if (par == null) { // directly trip
16.511 + if (casState
16.512 + (s,
16.513 + trippedStateFor(onAdvance(phase, parties) ? -1 :
16.514 + ((phase + 1) & phaseMask), parties))) {
16.515 + releaseWaiters(phase);
16.516 + break;
16.517 + }
16.518 + }
16.519 + else { // cascade to parent
16.520 + if (casState(s, s - 1)) { // zeroes unarrived
16.521 + par.arrive();
16.522 + reconcileState();
16.523 + break;
16.524 + }
16.525 + }
16.526 + }
16.527 + else if (phase != phaseOf(root.state)) // or if unreconciled
16.528 + reconcileState();
16.529 + else
16.530 + throw new IllegalStateException(badBounds(parties, unarrived));
16.531 + }
16.532 + return phase;
16.533 + }
16.534 +
16.535 + /**
16.536 + * Arrives at the barrier and deregisters from it without waiting
16.537 + * for others. Deregistration reduces the number of parties
16.538 + * required to trip the barrier in future phases. If this phaser
16.539 + * has a parent, and deregistration causes this phaser to have
16.540 + * zero parties, this phaser also arrives at and is deregistered
16.541 + * from its parent. It is an unenforced usage error for an
16.542 + * unregistered party to invoke this method.
16.543 + *
16.544 + * @return the arrival phase number, or a negative value if terminated
16.545 + * @throws IllegalStateException if not terminated and the number
16.546 + * of registered or unarrived parties would become negative
16.547 + */
16.548 + public int arriveAndDeregister() {
16.549 + // similar code to arrive, but too different to merge
16.550 + Phaser par = parent;
16.551 + int phase;
16.552 + for (;;) {
16.553 + long s = state;
16.554 + phase = phaseOf(s);
16.555 + if (phase < 0)
16.556 + break;
16.557 + int parties = partiesOf(s) - 1;
16.558 + int unarrived = unarrivedOf(s) - 1;
16.559 + if (parties >= 0) {
16.560 + if (unarrived > 0 || (unarrived == 0 && par != null)) {
16.561 + if (casState
16.562 + (s,
16.563 + stateFor(phase, parties, unarrived))) {
16.564 + if (unarrived == 0) {
16.565 + par.arriveAndDeregister();
16.566 + reconcileState();
16.567 + }
16.568 + break;
16.569 + }
16.570 + continue;
16.571 + }
16.572 + if (unarrived == 0) {
16.573 + if (casState
16.574 + (s,
16.575 + trippedStateFor(onAdvance(phase, parties) ? -1 :
16.576 + ((phase + 1) & phaseMask), parties))) {
16.577 + releaseWaiters(phase);
16.578 + break;
16.579 + }
16.580 + continue;
16.581 + }
16.582 + if (par != null && phase != phaseOf(root.state)) {
16.583 + reconcileState();
16.584 + continue;
16.585 + }
16.586 + }
16.587 + throw new IllegalStateException(badBounds(parties, unarrived));
16.588 + }
16.589 + return phase;
16.590 + }
16.591 +
16.592 + /**
16.593 + * Arrives at the barrier and awaits others. Equivalent in effect
16.594 + * to {@code awaitAdvance(arrive())}. If you need to await with
16.595 + * interruption or timeout, you can arrange this with an analogous
16.596 + * construction using one of the other forms of the awaitAdvance
16.597 + * method. If instead you need to deregister upon arrival use
16.598 + * {@code arriveAndDeregister}. It is an unenforced usage error
16.599 + * for an unregistered party to invoke this method.
16.600 + *
16.601 + * @return the arrival phase number, or a negative number if terminated
16.602 + * @throws IllegalStateException if not terminated and the number
16.603 + * of unarrived parties would become negative
16.604 + */
16.605 + public int arriveAndAwaitAdvance() {
16.606 + return awaitAdvance(arrive());
16.607 + }
16.608 +
16.609 + /**
16.610 + * Awaits the phase of the barrier to advance from the given phase
16.611 + * value, returning immediately if the current phase of the
16.612 + * barrier is not equal to the given phase value or this barrier
16.613 + * is terminated. It is an unenforced usage error for an
16.614 + * unregistered party to invoke this method.
16.615 + *
16.616 + * @param phase an arrival phase number, or negative value if
16.617 + * terminated; this argument is normally the value returned by a
16.618 + * previous call to {@code arrive} or its variants
16.619 + * @return the next arrival phase number, or a negative value
16.620 + * if terminated or argument is negative
16.621 + */
16.622 + public int awaitAdvance(int phase) {
16.623 + if (phase < 0)
16.624 + return phase;
16.625 + long s = getReconciledState();
16.626 + int p = phaseOf(s);
16.627 + if (p != phase)
16.628 + return p;
16.629 + if (unarrivedOf(s) == 0 && parent != null)
16.630 + parent.awaitAdvance(phase);
16.631 + // Fall here even if parent waited, to reconcile and help release
16.632 + return untimedWait(phase);
16.633 + }
16.634 +
16.635 + /**
16.636 + * Awaits the phase of the barrier to advance from the given phase
16.637 + * value, throwing {@code InterruptedException} if interrupted
16.638 + * while waiting, or returning immediately if the current phase of
16.639 + * the barrier is not equal to the given phase value or this
16.640 + * barrier is terminated. It is an unenforced usage error for an
16.641 + * unregistered party to invoke this method.
16.642 + *
16.643 + * @param phase an arrival phase number, or negative value if
16.644 + * terminated; this argument is normally the value returned by a
16.645 + * previous call to {@code arrive} or its variants
16.646 + * @return the next arrival phase number, or a negative value
16.647 + * if terminated or argument is negative
16.648 + * @throws InterruptedException if thread interrupted while waiting
16.649 + */
16.650 + public int awaitAdvanceInterruptibly(int phase)
16.651 + throws InterruptedException {
16.652 + if (phase < 0)
16.653 + return phase;
16.654 + long s = getReconciledState();
16.655 + int p = phaseOf(s);
16.656 + if (p != phase)
16.657 + return p;
16.658 + if (unarrivedOf(s) == 0 && parent != null)
16.659 + parent.awaitAdvanceInterruptibly(phase);
16.660 + return interruptibleWait(phase);
16.661 + }
16.662 +
16.663 + /**
16.664 + * Awaits the phase of the barrier to advance from the given phase
16.665 + * value or the given timeout to elapse, throwing {@code
16.666 + * InterruptedException} if interrupted while waiting, or
16.667 + * returning immediately if the current phase of the barrier is
16.668 + * not equal to the given phase value or this barrier is
16.669 + * terminated. It is an unenforced usage error for an
16.670 + * unregistered party to invoke this method.
16.671 + *
16.672 + * @param phase an arrival phase number, or negative value if
16.673 + * terminated; this argument is normally the value returned by a
16.674 + * previous call to {@code arrive} or its variants
16.675 + * @param timeout how long to wait before giving up, in units of
16.676 + * {@code unit}
16.677 + * @param unit a {@code TimeUnit} determining how to interpret the
16.678 + * {@code timeout} parameter
16.679 + * @return the next arrival phase number, or a negative value
16.680 + * if terminated or argument is negative
16.681 + * @throws InterruptedException if thread interrupted while waiting
16.682 + * @throws TimeoutException if timed out while waiting
16.683 + */
16.684 + public int awaitAdvanceInterruptibly(int phase,
16.685 + long timeout, TimeUnit unit)
16.686 + throws InterruptedException, TimeoutException {
16.687 + if (phase < 0)
16.688 + return phase;
16.689 + long s = getReconciledState();
16.690 + int p = phaseOf(s);
16.691 + if (p != phase)
16.692 + return p;
16.693 + if (unarrivedOf(s) == 0 && parent != null)
16.694 + parent.awaitAdvanceInterruptibly(phase, timeout, unit);
16.695 + return timedWait(phase, unit.toNanos(timeout));
16.696 + }
16.697 +
16.698 + /**
16.699 + * Forces this barrier to enter termination state. Counts of
16.700 + * arrived and registered parties are unaffected. If this phaser
16.701 + * has a parent, it too is terminated. This method may be useful
16.702 + * for coordinating recovery after one or more tasks encounter
16.703 + * unexpected exceptions.
16.704 + */
16.705 + public void forceTermination() {
16.706 + for (;;) {
16.707 + long s = getReconciledState();
16.708 + int phase = phaseOf(s);
16.709 + int parties = partiesOf(s);
16.710 + int unarrived = unarrivedOf(s);
16.711 + if (phase < 0 ||
16.712 + casState(s, stateFor(-1, parties, unarrived))) {
16.713 + releaseWaiters(0);
16.714 + releaseWaiters(1);
16.715 + if (parent != null)
16.716 + parent.forceTermination();
16.717 + return;
16.718 + }
16.719 + }
16.720 + }
16.721 +
16.722 + /**
16.723 + * Returns the current phase number. The maximum phase number is
16.724 + * {@code Integer.MAX_VALUE}, after which it restarts at
16.725 + * zero. Upon termination, the phase number is negative.
16.726 + *
16.727 + * @return the phase number, or a negative value if terminated
16.728 + */
16.729 + public final int getPhase() {
16.730 + return phaseOf(getReconciledState());
16.731 + }
16.732 +
16.733 + /**
16.734 + * Returns the number of parties registered at this barrier.
16.735 + *
16.736 + * @return the number of parties
16.737 + */
16.738 + public int getRegisteredParties() {
16.739 + return partiesOf(state);
16.740 + }
16.741 +
16.742 + /**
16.743 + * Returns the number of registered parties that have arrived at
16.744 + * the current phase of this barrier.
16.745 + *
16.746 + * @return the number of arrived parties
16.747 + */
16.748 + public int getArrivedParties() {
16.749 + return arrivedOf(state);
16.750 + }
16.751 +
16.752 + /**
16.753 + * Returns the number of registered parties that have not yet
16.754 + * arrived at the current phase of this barrier.
16.755 + *
16.756 + * @return the number of unarrived parties
16.757 + */
16.758 + public int getUnarrivedParties() {
16.759 + return unarrivedOf(state);
16.760 + }
16.761 +
16.762 + /**
16.763 + * Returns the parent of this phaser, or {@code null} if none.
16.764 + *
16.765 + * @return the parent of this phaser, or {@code null} if none
16.766 + */
16.767 + public Phaser getParent() {
16.768 + return parent;
16.769 + }
16.770 +
16.771 + /**
16.772 + * Returns the root ancestor of this phaser, which is the same as
16.773 + * this phaser if it has no parent.
16.774 + *
16.775 + * @return the root ancestor of this phaser
16.776 + */
16.777 + public Phaser getRoot() {
16.778 + return root;
16.779 + }
16.780 +
16.781 + /**
16.782 + * Returns {@code true} if this barrier has been terminated.
16.783 + *
16.784 + * @return {@code true} if this barrier has been terminated
16.785 + */
16.786 + public boolean isTerminated() {
16.787 + return getPhase() < 0;
16.788 + }
16.789 +
16.790 + /**
16.791 + * Overridable method to perform an action upon impending phase
16.792 + * advance, and to control termination. This method is invoked
16.793 + * upon arrival of the party tripping the barrier (when all other
16.794 + * waiting parties are dormant). If this method returns {@code
16.795 + * true}, then, rather than advance the phase number, this barrier
16.796 + * will be set to a final termination state, and subsequent calls
16.797 + * to {@link #isTerminated} will return true. Any (unchecked)
16.798 + * Exception or Error thrown by an invocation of this method is
16.799 + * propagated to the party attempting to trip the barrier, in
16.800 + * which case no advance occurs.
16.801 + *
16.802 + * <p>The arguments to this method provide the state of the phaser
16.803 + * prevailing for the current transition. (When called from within
16.804 + * an implementation of {@code onAdvance} the values returned by
16.805 + * methods such as {@code getPhase} may or may not reliably
16.806 + * indicate the state to which this transition applies.)
16.807 + *
16.808 + * <p>The default version returns {@code true} when the number of
16.809 + * registered parties is zero. Normally, overrides that arrange
16.810 + * termination for other reasons should also preserve this
16.811 + * property.
16.812 + *
16.813 + * <p>You may override this method to perform an action with side
16.814 + * effects visible to participating tasks, but it is only sensible
16.815 + * to do so in designs where all parties register before any
16.816 + * arrive, and all {@link #awaitAdvance} at each phase.
16.817 + * Otherwise, you cannot ensure lack of interference from other
16.818 + * parties during the invocation of this method. Additionally,
16.819 + * method {@code onAdvance} may be invoked more than once per
16.820 + * transition if registrations are intermixed with arrivals.
16.821 + *
16.822 + * @param phase the phase number on entering the barrier
16.823 + * @param registeredParties the current number of registered parties
16.824 + * @return {@code true} if this barrier should terminate
16.825 + */
16.826 + protected boolean onAdvance(int phase, int registeredParties) {
16.827 + return registeredParties <= 0;
16.828 + }
16.829 +
16.830 + /**
16.831 + * Returns a string identifying this phaser, as well as its
16.832 + * state. The state, in brackets, includes the String {@code
16.833 + * "phase = "} followed by the phase number, {@code "parties = "}
16.834 + * followed by the number of registered parties, and {@code
16.835 + * "arrived = "} followed by the number of arrived parties.
16.836 + *
16.837 + * @return a string identifying this barrier, as well as its state
16.838 + */
16.839 + public String toString() {
16.840 + long s = getReconciledState();
16.841 + return super.toString() +
16.842 + "[phase = " + phaseOf(s) +
16.843 + " parties = " + partiesOf(s) +
16.844 + " arrived = " + arrivedOf(s) + "]";
16.845 + }
16.846 +
16.847 + // methods for waiting
16.848 +
16.849 + /**
16.850 + * Wait nodes for Treiber stack representing wait queue
16.851 + */
16.852 + static final class QNode implements ForkJoinPool.ManagedBlocker {
16.853 + final Phaser phaser;
16.854 + final int phase;
16.855 + final long startTime;
16.856 + final long nanos;
16.857 + final boolean timed;
16.858 + final boolean interruptible;
16.859 + volatile boolean wasInterrupted = false;
16.860 + volatile Thread thread; // nulled to cancel wait
16.861 + QNode next;
16.862 + QNode(Phaser phaser, int phase, boolean interruptible,
16.863 + boolean timed, long startTime, long nanos) {
16.864 + this.phaser = phaser;
16.865 + this.phase = phase;
16.866 + this.timed = timed;
16.867 + this.interruptible = interruptible;
16.868 + this.startTime = startTime;
16.869 + this.nanos = nanos;
16.870 + thread = Thread.currentThread();
16.871 + }
16.872 + public boolean isReleasable() {
16.873 + return (thread == null ||
16.874 + phaser.getPhase() != phase ||
16.875 + (interruptible && wasInterrupted) ||
16.876 + (timed && (nanos - (System.nanoTime() - startTime)) <= 0));
16.877 + }
16.878 + public boolean block() {
16.879 + if (Thread.interrupted()) {
16.880 + wasInterrupted = true;
16.881 + if (interruptible)
16.882 + return true;
16.883 + }
16.884 + if (!timed)
16.885 + LockSupport.park(this);
16.886 + else {
16.887 + long waitTime = nanos - (System.nanoTime() - startTime);
16.888 + if (waitTime <= 0)
16.889 + return true;
16.890 + LockSupport.parkNanos(this, waitTime);
16.891 + }
16.892 + return isReleasable();
16.893 + }
16.894 + void signal() {
16.895 + Thread t = thread;
16.896 + if (t != null) {
16.897 + thread = null;
16.898 + LockSupport.unpark(t);
16.899 + }
16.900 + }
16.901 + boolean doWait() {
16.902 + if (thread != null) {
16.903 + try {
16.904 + ForkJoinPool.managedBlock(this, false);
16.905 + } catch (InterruptedException ie) {
16.906 + }
16.907 + }
16.908 + return wasInterrupted;
16.909 + }
16.910 +
16.911 + }
16.912 +
16.913 + /**
16.914 + * Removes and signals waiting threads from wait queue.
16.915 + */
16.916 + private void releaseWaiters(int phase) {
16.917 + AtomicReference<QNode> head = queueFor(phase);
16.918 + QNode q;
16.919 + while ((q = head.get()) != null) {
16.920 + if (head.compareAndSet(q, q.next))
16.921 + q.signal();
16.922 + }
16.923 + }
16.924 +
16.925 + /**
16.926 + * Tries to enqueue given node in the appropriate wait queue.
16.927 + *
16.928 + * @return true if successful
16.929 + */
16.930 + private boolean tryEnqueue(QNode node) {
16.931 + AtomicReference<QNode> head = queueFor(node.phase);
16.932 + return head.compareAndSet(node.next = head.get(), node);
16.933 + }
16.934 +
16.935 + /**
16.936 + * Enqueues node and waits unless aborted or signalled.
16.937 + *
16.938 + * @return current phase
16.939 + */
16.940 + private int untimedWait(int phase) {
16.941 + QNode node = null;
16.942 + boolean queued = false;
16.943 + boolean interrupted = false;
16.944 + int p;
16.945 + while ((p = getPhase()) == phase) {
16.946 + if (Thread.interrupted())
16.947 + interrupted = true;
16.948 + else if (node == null)
16.949 + node = new QNode(this, phase, false, false, 0, 0);
16.950 + else if (!queued)
16.951 + queued = tryEnqueue(node);
16.952 + else
16.953 + interrupted = node.doWait();
16.954 + }
16.955 + if (node != null)
16.956 + node.thread = null;
16.957 + releaseWaiters(phase);
16.958 + if (interrupted)
16.959 + Thread.currentThread().interrupt();
16.960 + return p;
16.961 + }
16.962 +
16.963 + /**
16.964 + * Interruptible version
16.965 + * @return current phase
16.966 + */
16.967 + private int interruptibleWait(int phase) throws InterruptedException {
16.968 + QNode node = null;
16.969 + boolean queued = false;
16.970 + boolean interrupted = false;
16.971 + int p;
16.972 + while ((p = getPhase()) == phase && !interrupted) {
16.973 + if (Thread.interrupted())
16.974 + interrupted = true;
16.975 + else if (node == null)
16.976 + node = new QNode(this, phase, true, false, 0, 0);
16.977 + else if (!queued)
16.978 + queued = tryEnqueue(node);
16.979 + else
16.980 + interrupted = node.doWait();
16.981 + }
16.982 + if (node != null)
16.983 + node.thread = null;
16.984 + if (p != phase || (p = getPhase()) != phase)
16.985 + releaseWaiters(phase);
16.986 + if (interrupted)
16.987 + throw new InterruptedException();
16.988 + return p;
16.989 + }
16.990 +
16.991 + /**
16.992 + * Timeout version.
16.993 + * @return current phase
16.994 + */
16.995 + private int timedWait(int phase, long nanos)
16.996 + throws InterruptedException, TimeoutException {
16.997 + long startTime = System.nanoTime();
16.998 + QNode node = null;
16.999 + boolean queued = false;
16.1000 + boolean interrupted = false;
16.1001 + int p;
16.1002 + while ((p = getPhase()) == phase && !interrupted) {
16.1003 + if (Thread.interrupted())
16.1004 + interrupted = true;
16.1005 + else if (nanos - (System.nanoTime() - startTime) <= 0)
16.1006 + break;
16.1007 + else if (node == null)
16.1008 + node = new QNode(this, phase, true, true, startTime, nanos);
16.1009 + else if (!queued)
16.1010 + queued = tryEnqueue(node);
16.1011 + else
16.1012 + interrupted = node.doWait();
16.1013 + }
16.1014 + if (node != null)
16.1015 + node.thread = null;
16.1016 + if (p != phase || (p = getPhase()) != phase)
16.1017 + releaseWaiters(phase);
16.1018 + if (interrupted)
16.1019 + throw new InterruptedException();
16.1020 + if (p == phase)
16.1021 + throw new TimeoutException();
16.1022 + return p;
16.1023 + }
16.1024 +
16.1025 + // Unsafe mechanics
16.1026 +
16.1027 + private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
16.1028 + private static final long stateOffset =
16.1029 + objectFieldOffset("state", Phaser.class);
16.1030 +
16.1031 + private final boolean casState(long cmp, long val) {
16.1032 + return UNSAFE.compareAndSwapLong(this, stateOffset, cmp, val);
16.1033 + }
16.1034 +
16.1035 + private static long objectFieldOffset(String field, Class<?> klazz) {
16.1036 + try {
16.1037 + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
16.1038 + } catch (NoSuchFieldException e) {
16.1039 + // Convert Exception to corresponding Error
16.1040 + NoSuchFieldError error = new NoSuchFieldError(field);
16.1041 + error.initCause(e);
16.1042 + throw error;
16.1043 + }
16.1044 + }
16.1045 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/src/share/classes/java/util/concurrent/RecursiveAction.java Sun Nov 08 14:49:18 2009 -0800
17.3 @@ -0,0 +1,179 @@
17.4 +/*
17.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.6 + *
17.7 + * This code is free software; you can redistribute it and/or modify it
17.8 + * under the terms of the GNU General Public License version 2 only, as
17.9 + * published by the Free Software Foundation. Sun designates this
17.10 + * particular file as subject to the "Classpath" exception as provided
17.11 + * by Sun in the LICENSE file that accompanied this code.
17.12 + *
17.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
17.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.16 + * version 2 for more details (a copy is included in the LICENSE file that
17.17 + * accompanied this code).
17.18 + *
17.19 + * You should have received a copy of the GNU General Public License version
17.20 + * 2 along with this work; if not, write to the Free Software Foundation,
17.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.22 + *
17.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
17.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
17.25 + * have any questions.
17.26 + */
17.27 +
17.28 +/*
17.29 + * This file is available under and governed by the GNU General Public
17.30 + * License version 2 only, as published by the Free Software Foundation.
17.31 + * However, the following notice accompanied the original version of this
17.32 + * file:
17.33 + *
17.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
17.35 + * Expert Group and released to the public domain, as explained at
17.36 + * http://creativecommons.org/licenses/publicdomain
17.37 + */
17.38 +
17.39 +package java.util.concurrent;
17.40 +
17.41 +/**
17.42 + * A recursive resultless {@link ForkJoinTask}. This class
17.43 + * establishes conventions to parameterize resultless actions as
17.44 + * {@code Void} {@code ForkJoinTask}s. Because {@code null} is the
17.45 + * only valid value of type {@code Void}, methods such as join always
17.46 + * return {@code null} upon completion.
17.47 + *
17.48 + * <p><b>Sample Usages.</b> Here is a sketch of a ForkJoin sort that
17.49 + * sorts a given {@code long[]} array:
17.50 + *
17.51 + * <pre> {@code
17.52 + * class SortTask extends RecursiveAction {
17.53 + * final long[] array; final int lo; final int hi;
17.54 + * SortTask(long[] array, int lo, int hi) {
17.55 + * this.array = array; this.lo = lo; this.hi = hi;
17.56 + * }
17.57 + * protected void compute() {
17.58 + * if (hi - lo < THRESHOLD)
17.59 + * sequentiallySort(array, lo, hi);
17.60 + * else {
17.61 + * int mid = (lo + hi) >>> 1;
17.62 + * invokeAll(new SortTask(array, lo, mid),
17.63 + * new SortTask(array, mid, hi));
17.64 + * merge(array, lo, hi);
17.65 + * }
17.66 + * }
17.67 + * }}</pre>
17.68 + *
17.69 + * You could then sort {@code anArray} by creating {@code new
17.70 + * SortTask(anArray, 0, anArray.length-1) } and invoking it in a
17.71 + * ForkJoinPool. As a more concrete simple example, the following
17.72 + * task increments each element of an array:
17.73 + * <pre> {@code
17.74 + * class IncrementTask extends RecursiveAction {
17.75 + * final long[] array; final int lo; final int hi;
17.76 + * IncrementTask(long[] array, int lo, int hi) {
17.77 + * this.array = array; this.lo = lo; this.hi = hi;
17.78 + * }
17.79 + * protected void compute() {
17.80 + * if (hi - lo < THRESHOLD) {
17.81 + * for (int i = lo; i < hi; ++i)
17.82 + * array[i]++;
17.83 + * }
17.84 + * else {
17.85 + * int mid = (lo + hi) >>> 1;
17.86 + * invokeAll(new IncrementTask(array, lo, mid),
17.87 + * new IncrementTask(array, mid, hi));
17.88 + * }
17.89 + * }
17.90 + * }}</pre>
17.91 + *
17.92 + * <p>The following example illustrates some refinements and idioms
17.93 + * that may lead to better performance: RecursiveActions need not be
17.94 + * fully recursive, so long as they maintain the basic
17.95 + * divide-and-conquer approach. Here is a class that sums the squares
17.96 + * of each element of a double array, by subdividing out only the
17.97 + * right-hand-sides of repeated divisions by two, and keeping track of
17.98 + * them with a chain of {@code next} references. It uses a dynamic
17.99 + * threshold based on method {@code getSurplusQueuedTaskCount}, but
17.100 + * counterbalances potential excess partitioning by directly
17.101 + * performing leaf actions on unstolen tasks rather than further
17.102 + * subdividing.
17.103 + *
17.104 + * <pre> {@code
17.105 + * double sumOfSquares(ForkJoinPool pool, double[] array) {
17.106 + * int n = array.length;
17.107 + * Applyer a = new Applyer(array, 0, n, null);
17.108 + * pool.invoke(a);
17.109 + * return a.result;
17.110 + * }
17.111 + *
17.112 + * class Applyer extends RecursiveAction {
17.113 + * final double[] array;
17.114 + * final int lo, hi;
17.115 + * double result;
17.116 + * Applyer next; // keeps track of right-hand-side tasks
17.117 + * Applyer(double[] array, int lo, int hi, Applyer next) {
17.118 + * this.array = array; this.lo = lo; this.hi = hi;
17.119 + * this.next = next;
17.120 + * }
17.121 + *
17.122 + * double atLeaf(int l, int h) {
17.123 + * double sum = 0;
17.124 + * for (int i = l; i < h; ++i) // perform leftmost base step
17.125 + * sum += array[i] * array[i];
17.126 + * return sum;
17.127 + * }
17.128 + *
17.129 + * protected void compute() {
17.130 + * int l = lo;
17.131 + * int h = hi;
17.132 + * Applyer right = null;
17.133 + * while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) {
17.134 + * int mid = (l + h) >>> 1;
17.135 + * right = new Applyer(array, mid, h, right);
17.136 + * right.fork();
17.137 + * h = mid;
17.138 + * }
17.139 + * double sum = atLeaf(l, h);
17.140 + * while (right != null) {
17.141 + * if (right.tryUnfork()) // directly calculate if not stolen
17.142 + * sum += right.atLeaf(right.lo, right.hi);
17.143 + * else {
17.144 + * right.helpJoin();
17.145 + * sum += right.result;
17.146 + * }
17.147 + * right = right.next;
17.148 + * }
17.149 + * result = sum;
17.150 + * }
17.151 + * }}</pre>
17.152 + *
17.153 + * @since 1.7
17.154 + * @author Doug Lea
17.155 + */
17.156 +public abstract class RecursiveAction extends ForkJoinTask<Void> {
17.157 + private static final long serialVersionUID = 5232453952276485070L;
17.158 +
17.159 + /**
17.160 + * The main computation performed by this task.
17.161 + */
17.162 + protected abstract void compute();
17.163 +
17.164 + /**
17.165 + * Always returns null.
17.166 + */
17.167 + public final Void getRawResult() { return null; }
17.168 +
17.169 + /**
17.170 + * Requires null completion value.
17.171 + */
17.172 + protected final void setRawResult(Void mustBeNull) { }
17.173 +
17.174 + /**
17.175 + * Implements execution conventions for RecursiveActions.
17.176 + */
17.177 + protected final boolean exec() {
17.178 + compute();
17.179 + return true;
17.180 + }
17.181 +
17.182 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/src/share/classes/java/util/concurrent/RecursiveTask.java Sun Nov 08 14:49:18 2009 -0800
18.3 @@ -0,0 +1,97 @@
18.4 +/*
18.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.6 + *
18.7 + * This code is free software; you can redistribute it and/or modify it
18.8 + * under the terms of the GNU General Public License version 2 only, as
18.9 + * published by the Free Software Foundation. Sun designates this
18.10 + * particular file as subject to the "Classpath" exception as provided
18.11 + * by Sun in the LICENSE file that accompanied this code.
18.12 + *
18.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
18.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18.16 + * version 2 for more details (a copy is included in the LICENSE file that
18.17 + * accompanied this code).
18.18 + *
18.19 + * You should have received a copy of the GNU General Public License version
18.20 + * 2 along with this work; if not, write to the Free Software Foundation,
18.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18.22 + *
18.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
18.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
18.25 + * have any questions.
18.26 + */
18.27 +
18.28 +/*
18.29 + * This file is available under and governed by the GNU General Public
18.30 + * License version 2 only, as published by the Free Software Foundation.
18.31 + * However, the following notice accompanied the original version of this
18.32 + * file:
18.33 + *
18.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
18.35 + * Expert Group and released to the public domain, as explained at
18.36 + * http://creativecommons.org/licenses/publicdomain
18.37 + */
18.38 +
18.39 +package java.util.concurrent;
18.40 +
18.41 +/**
18.42 + * A recursive result-bearing {@link ForkJoinTask}.
18.43 + *
18.44 + * <p>For a classic example, here is a task computing Fibonacci numbers:
18.45 + *
18.46 + * <pre> {@code
18.47 + * class Fibonacci extends RecursiveTask<Integer> {
18.48 + * final int n;
18.49 + * Fibonacci(int n) { this.n = n; }
18.50 + * Integer compute() {
18.51 + * if (n <= 1)
18.52 + * return n;
18.53 + * Fibonacci f1 = new Fibonacci(n - 1);
18.54 + * f1.fork();
18.55 + * Fibonacci f2 = new Fibonacci(n - 2);
18.56 + * return f2.compute() + f1.join();
18.57 + * }
18.58 + * }}</pre>
18.59 + *
18.60 + * However, besides being a dumb way to compute Fibonacci functions
18.61 + * (there is a simple fast linear algorithm that you'd use in
18.62 + * practice), this is likely to perform poorly because the smallest
18.63 + * subtasks are too small to be worthwhile splitting up. Instead, as
18.64 + * is the case for nearly all fork/join applications, you'd pick some
18.65 + * minimum granularity size (for example 10 here) for which you always
18.66 + * sequentially solve rather than subdividing.
18.67 + *
18.68 + * @since 1.7
18.69 + * @author Doug Lea
18.70 + */
18.71 +public abstract class RecursiveTask<V> extends ForkJoinTask<V> {
18.72 + private static final long serialVersionUID = 5232453952276485270L;
18.73 +
18.74 + /**
18.75 + * The result of the computation.
18.76 + */
18.77 + V result;
18.78 +
18.79 + /**
18.80 + * The main computation performed by this task.
18.81 + */
18.82 + protected abstract V compute();
18.83 +
18.84 + public final V getRawResult() {
18.85 + return result;
18.86 + }
18.87 +
18.88 + protected final void setRawResult(V value) {
18.89 + result = value;
18.90 + }
18.91 +
18.92 + /**
18.93 + * Implements execution conventions for RecursiveTask.
18.94 + */
18.95 + protected final boolean exec() {
18.96 + result = compute();
18.97 + return true;
18.98 + }
18.99 +
18.100 +}
19.1 --- a/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Wed Nov 04 11:19:42 2009 -0800
19.2 +++ b/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Sun Nov 08 14:49:18 2009 -0800
19.3 @@ -61,6 +61,14 @@
19.4 * causes tasks to be immediately removed from the work queue at
19.5 * time of cancellation.
19.6 *
19.7 + * <p>Successive executions of a task scheduled via
19.8 + * <code>scheduleAtFixedRate</code> or
19.9 + * <code>scheduleWithFixedDelay</code> do not overlap. While different
19.10 + * executions may be performed by different threads, the effects of
19.11 + * prior executions <a
19.12 + * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
19.13 + * those of subsequent ones.
19.14 + *
19.15 * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
19.16 * of the inherited tuning methods are not useful for it. In
19.17 * particular, because it acts as a fixed-sized pool using
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Sun Nov 08 14:49:18 2009 -0800
20.3 @@ -0,0 +1,228 @@
20.4 +/*
20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
20.6 + *
20.7 + * This code is free software; you can redistribute it and/or modify it
20.8 + * under the terms of the GNU General Public License version 2 only, as
20.9 + * published by the Free Software Foundation. Sun designates this
20.10 + * particular file as subject to the "Classpath" exception as provided
20.11 + * by Sun in the LICENSE file that accompanied this code.
20.12 + *
20.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
20.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20.16 + * version 2 for more details (a copy is included in the LICENSE file that
20.17 + * accompanied this code).
20.18 + *
20.19 + * You should have received a copy of the GNU General Public License version
20.20 + * 2 along with this work; if not, write to the Free Software Foundation,
20.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20.22 + *
20.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
20.25 + * have any questions.
20.26 + */
20.27 +
20.28 +/*
20.29 + * This file is available under and governed by the GNU General Public
20.30 + * License version 2 only, as published by the Free Software Foundation.
20.31 + * However, the following notice accompanied the original version of this
20.32 + * file:
20.33 + *
20.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
20.35 + * Expert Group and released to the public domain, as explained at
20.36 + * http://creativecommons.org/licenses/publicdomain
20.37 + */
20.38 +
20.39 +package java.util.concurrent;
20.40 +
20.41 +import java.util.Random;
20.42 +
20.43 +/**
20.44 + * A random number generator isolated to the current thread. Like the
20.45 + * global {@link java.util.Random} generator used by the {@link
20.46 + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
20.47 + * with an internally generated seed that may not otherwise be
20.48 + * modified. When applicable, use of {@code ThreadLocalRandom} rather
20.49 + * than shared {@code Random} objects in concurrent programs will
20.50 + * typically encounter much less overhead and contention. Use of
20.51 + * {@code ThreadLocalRandom} is particularly appropriate when multiple
20.52 + * tasks (for example, each a {@link ForkJoinTask}) use random numbers
20.53 + * in parallel in thread pools.
20.54 + *
20.55 + * <p>Usages of this class should typically be of the form:
20.56 + * {@code ThreadLocalRandom.current().nextX(...)} (where
20.57 + * {@code X} is {@code Int}, {@code Long}, etc).
20.58 + * When all usages are of this form, it is never possible to
20.59 + * accidently share a {@code ThreadLocalRandom} across multiple threads.
20.60 + *
20.61 + * <p>This class also provides additional commonly used bounded random
20.62 + * generation methods.
20.63 + *
20.64 + * @since 1.7
20.65 + * @author Doug Lea
20.66 + */
20.67 +public class ThreadLocalRandom extends Random {
20.68 + // same constants as Random, but must be redeclared because private
20.69 + private final static long multiplier = 0x5DEECE66DL;
20.70 + private final static long addend = 0xBL;
20.71 + private final static long mask = (1L << 48) - 1;
20.72 +
20.73 + /**
20.74 + * The random seed. We can't use super.seed.
20.75 + */
20.76 + private long rnd;
20.77 +
20.78 + /**
20.79 + * Initialization flag to permit the first and only allowed call
20.80 + * to setSeed (inside Random constructor) to succeed. We can't
20.81 + * allow others since it would cause setting seed in one part of a
20.82 + * program to unintentionally impact other usages by the thread.
20.83 + */
20.84 + boolean initialized;
20.85 +
20.86 + // Padding to help avoid memory contention among seed updates in
20.87 + // different TLRs in the common case that they are located near
20.88 + // each other.
20.89 + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
20.90 +
20.91 + /**
20.92 + * The actual ThreadLocal
20.93 + */
20.94 + private static final ThreadLocal<ThreadLocalRandom> localRandom =
20.95 + new ThreadLocal<ThreadLocalRandom>() {
20.96 + protected ThreadLocalRandom initialValue() {
20.97 + return new ThreadLocalRandom();
20.98 + }
20.99 + };
20.100 +
20.101 +
20.102 + /**
20.103 + * Constructor called only by localRandom.initialValue.
20.104 + * We rely on the fact that the superclass no-arg constructor
20.105 + * invokes setSeed exactly once to initialize.
20.106 + */
20.107 + ThreadLocalRandom() {
20.108 + super();
20.109 + }
20.110 +
20.111 + /**
20.112 + * Returns the current thread's {@code ThreadLocalRandom}.
20.113 + *
20.114 + * @return the current thread's {@code ThreadLocalRandom}
20.115 + */
20.116 + public static ThreadLocalRandom current() {
20.117 + return localRandom.get();
20.118 + }
20.119 +
20.120 + /**
20.121 + * Throws {@code UnsupportedOperationException}. Setting seeds in
20.122 + * this generator is not supported.
20.123 + *
20.124 + * @throws UnsupportedOperationException always
20.125 + */
20.126 + public void setSeed(long seed) {
20.127 + if (initialized)
20.128 + throw new UnsupportedOperationException();
20.129 + initialized = true;
20.130 + rnd = (seed ^ multiplier) & mask;
20.131 + }
20.132 +
20.133 + protected int next(int bits) {
20.134 + rnd = (rnd * multiplier + addend) & mask;
20.135 + return (int) (rnd >>> (48-bits));
20.136 + }
20.137 +
20.138 + /**
20.139 + * Returns a pseudorandom, uniformly distributed value between the
20.140 + * given least value (inclusive) and bound (exclusive).
20.141 + *
20.142 + * @param least the least value returned
20.143 + * @param bound the upper bound (exclusive)
20.144 + * @throws IllegalArgumentException if least greater than or equal
20.145 + * to bound
20.146 + * @return the next value
20.147 + */
20.148 + public int nextInt(int least, int bound) {
20.149 + if (least >= bound)
20.150 + throw new IllegalArgumentException();
20.151 + return nextInt(bound - least) + least;
20.152 + }
20.153 +
20.154 + /**
20.155 + * Returns a pseudorandom, uniformly distributed value
20.156 + * between 0 (inclusive) and the specified value (exclusive).
20.157 + *
20.158 + * @param n the bound on the random number to be returned. Must be
20.159 + * positive.
20.160 + * @return the next value
20.161 + * @throws IllegalArgumentException if n is not positive
20.162 + */
20.163 + public long nextLong(long n) {
20.164 + if (n <= 0)
20.165 + throw new IllegalArgumentException("n must be positive");
20.166 + // Divide n by two until small enough for nextInt. On each
20.167 + // iteration (at most 31 of them but usually much less),
20.168 + // randomly choose both whether to include high bit in result
20.169 + // (offset) and whether to continue with the lower vs upper
20.170 + // half (which makes a difference only if odd).
20.171 + long offset = 0;
20.172 + while (n >= Integer.MAX_VALUE) {
20.173 + int bits = next(2);
20.174 + long half = n >>> 1;
20.175 + long nextn = ((bits & 2) == 0) ? half : n - half;
20.176 + if ((bits & 1) == 0)
20.177 + offset += n - nextn;
20.178 + n = nextn;
20.179 + }
20.180 + return offset + nextInt((int) n);
20.181 + }
20.182 +
20.183 + /**
20.184 + * Returns a pseudorandom, uniformly distributed value between the
20.185 + * given least value (inclusive) and bound (exclusive).
20.186 + *
20.187 + * @param least the least value returned
20.188 + * @param bound the upper bound (exclusive)
20.189 + * @return the next value
20.190 + * @throws IllegalArgumentException if least greater than or equal
20.191 + * to bound
20.192 + */
20.193 + public long nextLong(long least, long bound) {
20.194 + if (least >= bound)
20.195 + throw new IllegalArgumentException();
20.196 + return nextLong(bound - least) + least;
20.197 + }
20.198 +
20.199 + /**
20.200 + * Returns a pseudorandom, uniformly distributed {@code double} value
20.201 + * between 0 (inclusive) and the specified value (exclusive).
20.202 + *
20.203 + * @param n the bound on the random number to be returned. Must be
20.204 + * positive.
20.205 + * @return the next value
20.206 + * @throws IllegalArgumentException if n is not positive
20.207 + */
20.208 + public double nextDouble(double n) {
20.209 + if (n <= 0)
20.210 + throw new IllegalArgumentException("n must be positive");
20.211 + return nextDouble() * n;
20.212 + }
20.213 +
20.214 + /**
20.215 + * Returns a pseudorandom, uniformly distributed value between the
20.216 + * given least value (inclusive) and bound (exclusive).
20.217 + *
20.218 + * @param least the least value returned
20.219 + * @param bound the upper bound (exclusive)
20.220 + * @return the next value
20.221 + * @throws IllegalArgumentException if least greater than or equal
20.222 + * to bound
20.223 + */
20.224 + public double nextDouble(double least, double bound) {
20.225 + if (least >= bound)
20.226 + throw new IllegalArgumentException();
20.227 + return nextDouble() * (bound - least) + least;
20.228 + }
20.229 +
20.230 + private static final long serialVersionUID = -5851777807851030925L;
20.231 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/src/share/classes/java/util/concurrent/TransferQueue.java Sun Nov 08 14:49:18 2009 -0800
21.3 @@ -0,0 +1,161 @@
21.4 +/*
21.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.6 + *
21.7 + * This code is free software; you can redistribute it and/or modify it
21.8 + * under the terms of the GNU General Public License version 2 only, as
21.9 + * published by the Free Software Foundation. Sun designates this
21.10 + * particular file as subject to the "Classpath" exception as provided
21.11 + * by Sun in the LICENSE file that accompanied this code.
21.12 + *
21.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
21.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21.16 + * version 2 for more details (a copy is included in the LICENSE file that
21.17 + * accompanied this code).
21.18 + *
21.19 + * You should have received a copy of the GNU General Public License version
21.20 + * 2 along with this work; if not, write to the Free Software Foundation,
21.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.22 + *
21.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
21.25 + * have any questions.
21.26 + */
21.27 +
21.28 +/*
21.29 + * This file is available under and governed by the GNU General Public
21.30 + * License version 2 only, as published by the Free Software Foundation.
21.31 + * However, the following notice accompanied the original version of this
21.32 + * file:
21.33 + *
21.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
21.35 + * Expert Group and released to the public domain, as explained at
21.36 + * http://creativecommons.org/licenses/publicdomain
21.37 + */
21.38 +
21.39 +package java.util.concurrent;
21.40 +
21.41 +/**
21.42 + * A {@link BlockingQueue} in which producers may wait for consumers
21.43 + * to receive elements. A {@code TransferQueue} may be useful for
21.44 + * example in message passing applications in which producers
21.45 + * sometimes (using method {@link #transfer}) await receipt of
21.46 + * elements by consumers invoking {@code take} or {@code poll}, while
21.47 + * at other times enqueue elements (via method {@code put}) without
21.48 + * waiting for receipt.
21.49 + * {@linkplain #tryTransfer(Object) Non-blocking} and
21.50 + * {@linkplain #tryTransfer(Object,long,TimeUnit) time-out} versions of
21.51 + * {@code tryTransfer} are also available.
21.52 + * A {@code TransferQueue} may also be queried, via {@link
21.53 + * #hasWaitingConsumer}, whether there are any threads waiting for
21.54 + * items, which is a converse analogy to a {@code peek} operation.
21.55 + *
21.56 + * <p>Like other blocking queues, a {@code TransferQueue} may be
21.57 + * capacity bounded. If so, an attempted transfer operation may
21.58 + * initially block waiting for available space, and/or subsequently
21.59 + * block waiting for reception by a consumer. Note that in a queue
21.60 + * with zero capacity, such as {@link SynchronousQueue}, {@code put}
21.61 + * and {@code transfer} are effectively synonymous.
21.62 + *
21.63 + * <p>This interface is a member of the
21.64 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
21.65 + * Java Collections Framework</a>.
21.66 + *
21.67 + * @since 1.7
21.68 + * @author Doug Lea
21.69 + * @param <E> the type of elements held in this collection
21.70 + */
21.71 +public interface TransferQueue<E> extends BlockingQueue<E> {
21.72 + /**
21.73 + * Transfers the element to a waiting consumer immediately, if possible.
21.74 + *
21.75 + * <p>More precisely, transfers the specified element immediately
21.76 + * if there exists a consumer already waiting to receive it (in
21.77 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
21.78 + * otherwise returning {@code false} without enqueuing the element.
21.79 + *
21.80 + * @param e the element to transfer
21.81 + * @return {@code true} if the element was transferred, else
21.82 + * {@code false}
21.83 + * @throws ClassCastException if the class of the specified element
21.84 + * prevents it from being added to this queue
21.85 + * @throws NullPointerException if the specified element is null
21.86 + * @throws IllegalArgumentException if some property of the specified
21.87 + * element prevents it from being added to this queue
21.88 + */
21.89 + boolean tryTransfer(E e);
21.90 +
21.91 + /**
21.92 + * Transfers the element to a consumer, waiting if necessary to do so.
21.93 + *
21.94 + * <p>More precisely, transfers the specified element immediately
21.95 + * if there exists a consumer already waiting to receive it (in
21.96 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
21.97 + * else waits until the element is received by a consumer.
21.98 + *
21.99 + * @param e the element to transfer
21.100 + * @throws InterruptedException if interrupted while waiting,
21.101 + * in which case the element is not left enqueued
21.102 + * @throws ClassCastException if the class of the specified element
21.103 + * prevents it from being added to this queue
21.104 + * @throws NullPointerException if the specified element is null
21.105 + * @throws IllegalArgumentException if some property of the specified
21.106 + * element prevents it from being added to this queue
21.107 + */
21.108 + void transfer(E e) throws InterruptedException;
21.109 +
21.110 + /**
21.111 + * Transfers the element to a consumer if it is possible to do so
21.112 + * before the timeout elapses.
21.113 + *
21.114 + * <p>More precisely, transfers the specified element immediately
21.115 + * if there exists a consumer already waiting to receive it (in
21.116 + * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
21.117 + * else waits until the element is received by a consumer,
21.118 + * returning {@code false} if the specified wait time elapses
21.119 + * before the element can be transferred.
21.120 + *
21.121 + * @param e the element to transfer
21.122 + * @param timeout how long to wait before giving up, in units of
21.123 + * {@code unit}
21.124 + * @param unit a {@code TimeUnit} determining how to interpret the
21.125 + * {@code timeout} parameter
21.126 + * @return {@code true} if successful, or {@code false} if
21.127 + * the specified waiting time elapses before completion,
21.128 + * in which case the element is not left enqueued
21.129 + * @throws InterruptedException if interrupted while waiting,
21.130 + * in which case the element is not left enqueued
21.131 + * @throws ClassCastException if the class of the specified element
21.132 + * prevents it from being added to this queue
21.133 + * @throws NullPointerException if the specified element is null
21.134 + * @throws IllegalArgumentException if some property of the specified
21.135 + * element prevents it from being added to this queue
21.136 + */
21.137 + boolean tryTransfer(E e, long timeout, TimeUnit unit)
21.138 + throws InterruptedException;
21.139 +
21.140 + /**
21.141 + * Returns {@code true} if there is at least one consumer waiting
21.142 + * to receive an element via {@link #take} or
21.143 + * timed {@link #poll(long,TimeUnit) poll}.
21.144 + * The return value represents a momentary state of affairs.
21.145 + *
21.146 + * @return {@code true} if there is at least one waiting consumer
21.147 + */
21.148 + boolean hasWaitingConsumer();
21.149 +
21.150 + /**
21.151 + * Returns an estimate of the number of consumers waiting to
21.152 + * receive elements via {@link #take} or timed
21.153 + * {@link #poll(long,TimeUnit) poll}. The return value is an
21.154 + * approximation of a momentary state of affairs, that may be
21.155 + * inaccurate if consumers have completed or given up waiting.
21.156 + * The value may be useful for monitoring and heuristics, but
21.157 + * not for synchronization control. Implementations of this
21.158 + * method are likely to be noticeably slower than those for
21.159 + * {@link #hasWaitingConsumer}.
21.160 + *
21.161 + * @return the number of consumers waiting to receive elements
21.162 + */
21.163 + int getWaitingConsumerCount();
21.164 +}
22.1 --- a/src/share/classes/java/util/concurrent/locks/Condition.java Wed Nov 04 11:19:42 2009 -0800
22.2 +++ b/src/share/classes/java/util/concurrent/locks/Condition.java Sun Nov 08 14:49:18 2009 -0800
22.3 @@ -170,8 +170,8 @@
22.4 * <p>As interruption generally implies cancellation, and checks for
22.5 * interruption are often infrequent, an implementation can favor responding
22.6 * to an interrupt over normal method return. This is true even if it can be
22.7 - * shown that the interrupt occurred after another action may have unblocked
22.8 - * the thread. An implementation should document this behavior.
22.9 + * shown that the interrupt occurred after another action that may have
22.10 + * unblocked the thread. An implementation should document this behavior.
22.11 *
22.12 * @since 1.5
22.13 * @author Doug Lea
23.1 --- a/src/share/classes/java/util/concurrent/package-info.java Wed Nov 04 11:19:42 2009 -0800
23.2 +++ b/src/share/classes/java/util/concurrent/package-info.java Sun Nov 08 14:49:18 2009 -0800
23.3 @@ -92,6 +92,13 @@
23.4 * assists in coordinating the processing of groups of
23.5 * asynchronous tasks.
23.6 *
23.7 + * <p>Class {@link java.util.concurrent.ForkJoinPool} provides an
23.8 + * Executor primarily designed for processing instances of {@link
23.9 + * java.util.concurrent.ForkJoinTask} and its subclasses. These
23.10 + * classes employ a work-stealing scheduler that attains high
23.11 + * throughput for tasks conforming to restrictions that often hold in
23.12 + * computation-intensive parallel processing.
23.13 + *
23.14 * <h2>Queues</h2>
23.15 *
23.16 * The {@link java.util.concurrent.ConcurrentLinkedQueue} class
23.17 @@ -110,6 +117,12 @@
23.18 * for producer-consumer, messaging, parallel tasking, and
23.19 * related concurrent designs.
23.20 *
23.21 + * <p> Extended interface {@link java.util.concurrent.TransferQueue},
23.22 + * and implementation {@link java.util.concurrent.LinkedTransferQueue}
23.23 + * introduce a synchronous {@code transfer} method (along with related
23.24 + * features) in which a producer may optionally block awaiting its
23.25 + * consumer.
23.26 + *
23.27 * <p>The {@link java.util.concurrent.BlockingDeque} interface
23.28 * extends {@code BlockingQueue} to support both FIFO and LIFO
23.29 * (stack-based) operations.
23.30 @@ -136,15 +149,28 @@
23.31 *
23.32 * <h2>Synchronizers</h2>
23.33 *
23.34 - * Four classes aid common special-purpose synchronization idioms.
23.35 - * {@link java.util.concurrent.Semaphore} is a classic concurrency tool.
23.36 - * {@link java.util.concurrent.CountDownLatch} is a very simple yet very
23.37 - * common utility for blocking until a given number of signals, events,
23.38 - * or conditions hold. A {@link java.util.concurrent.CyclicBarrier} is a
23.39 - * resettable multiway synchronization point useful in some styles of
23.40 - * parallel programming. An {@link java.util.concurrent.Exchanger} allows
23.41 - * two threads to exchange objects at a rendezvous point, and is useful
23.42 - * in several pipeline designs.
23.43 + * Five classes aid common special-purpose synchronization idioms.
23.44 + * <ul>
23.45 + *
23.46 + * <li>{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
23.47 + *
23.48 + * <li>{@link java.util.concurrent.CountDownLatch} is a very simple yet
23.49 + * very common utility for blocking until a given number of signals,
23.50 + * events, or conditions hold.
23.51 + *
23.52 + * <li>A {@link java.util.concurrent.CyclicBarrier} is a resettable
23.53 + * multiway synchronization point useful in some styles of parallel
23.54 + * programming.
23.55 + *
23.56 + * <li>A {@link java.util.concurrent.Phaser} provides
23.57 + * a more flexible form of barrier that may be used to control phased
23.58 + * computation among multiple threads.
23.59 + *
23.60 + * <li>An {@link java.util.concurrent.Exchanger} allows two threads to
23.61 + * exchange objects at a rendezvous point, and is useful in several
23.62 + * pipeline designs.
23.63 + *
23.64 + * </ul>
23.65 *
23.66 * <h2>Concurrent Collections</h2>
23.67 *
23.68 @@ -259,7 +285,8 @@
23.69 * in each thread <i>happen-before</i> those subsequent to the
23.70 * corresponding {@code exchange()} in another thread.
23.71 *
23.72 - * <li>Actions prior to calling {@code CyclicBarrier.await}
23.73 + * <li>Actions prior to calling {@code CyclicBarrier.await} and
23.74 + * {@code Phaser.awaitAdvance} (as well as its variants)
23.75 * <i>happen-before</i> actions performed by the barrier action, and
23.76 * actions performed by the barrier action <i>happen-before</i> actions
23.77 * subsequent to a successful return from the corresponding {@code await}
24.1 --- a/test/java/util/Collection/BiggernYours.java Wed Nov 04 11:19:42 2009 -0800
24.2 +++ b/test/java/util/Collection/BiggernYours.java Sun Nov 08 14:49:18 2009 -0800
24.3 @@ -178,10 +178,10 @@
24.4 new ConcurrentLinkedQueue() {
24.5 public int size() {return randomize(super.size());}});
24.6
24.7 -// testCollections(
24.8 -// new LinkedTransferQueue(),
24.9 -// new LinkedTransferQueue() {
24.10 -// public int size() {return randomize(super.size());}});
24.11 + testCollections(
24.12 + new LinkedTransferQueue(),
24.13 + new LinkedTransferQueue() {
24.14 + public int size() {return randomize(super.size());}});
24.15
24.16 testCollections(
24.17 new LinkedBlockingQueue(),
25.1 --- a/test/java/util/Collection/IteratorAtEnd.java Wed Nov 04 11:19:42 2009 -0800
25.2 +++ b/test/java/util/Collection/IteratorAtEnd.java Sun Nov 08 14:49:18 2009 -0800
25.3 @@ -49,7 +49,7 @@
25.4 testCollection(new LinkedBlockingQueue());
25.5 testCollection(new ArrayBlockingQueue(100));
25.6 testCollection(new ConcurrentLinkedQueue());
25.7 -// testCollection(new LinkedTransferQueue());
25.8 + testCollection(new LinkedTransferQueue());
25.9
25.10 testMap(new HashMap());
25.11 testMap(new Hashtable());
26.1 --- a/test/java/util/Collection/MOAT.java Wed Nov 04 11:19:42 2009 -0800
26.2 +++ b/test/java/util/Collection/MOAT.java Sun Nov 08 14:49:18 2009 -0800
26.3 @@ -76,7 +76,7 @@
26.4 testCollection(new LinkedBlockingQueue<Integer>(20));
26.5 testCollection(new LinkedBlockingDeque<Integer>(20));
26.6 testCollection(new ConcurrentLinkedQueue<Integer>());
26.7 -// testCollection(new LinkedTransferQueue<Integer>());
26.8 + testCollection(new LinkedTransferQueue<Integer>());
26.9 testCollection(new ConcurrentSkipListSet<Integer>());
26.10 testCollection(Arrays.asList(new Integer(42)));
26.11 testCollection(Arrays.asList(1,2,3));
27.1 --- a/test/java/util/Collections/CheckedNull.java Wed Nov 04 11:19:42 2009 -0800
27.2 +++ b/test/java/util/Collections/CheckedNull.java Sun Nov 08 14:49:18 2009 -0800
27.3 @@ -52,7 +52,7 @@
27.4
27.5 testMap(Collections.checkedMap(
27.6 new HashMap<String, String>(),
27.7 - String.class, String.class));;
27.8 + String.class, String.class));
27.9 }
27.10
27.11 ClassCastException cce(F f) {
28.1 --- a/test/java/util/Collections/RacingCollections.java Wed Nov 04 11:19:42 2009 -0800
28.2 +++ b/test/java/util/Collections/RacingCollections.java Sun Nov 08 14:49:18 2009 -0800
28.3 @@ -234,7 +234,7 @@
28.4 List<Queue<Integer>> list =
28.5 new ArrayList<Queue<Integer>>(newConcurrentDeques());
28.6 list.add(new LinkedBlockingQueue<Integer>(10));
28.7 -// list.add(new LinkedTransferQueue<Integer>());
28.8 + list.add(new LinkedTransferQueue<Integer>());
28.9 return list;
28.10 }
28.11
29.1 --- a/test/java/util/PriorityQueue/RemoveContains.java Wed Nov 04 11:19:42 2009 -0800
29.2 +++ b/test/java/util/PriorityQueue/RemoveContains.java Sun Nov 08 14:49:18 2009 -0800
29.3 @@ -69,7 +69,7 @@
29.4 test(new ArrayBlockingQueue<String>(10));
29.5 test(new LinkedBlockingQueue<String>(10));
29.6 test(new LinkedBlockingDeque<String>(10));
29.7 -// test(new LinkedTransferQueue<String>());
29.8 + test(new LinkedTransferQueue<String>());
29.9 test(new ArrayDeque<String>(10));
29.10
29.11 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
30.1 --- a/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Wed Nov 04 11:19:42 2009 -0800
30.2 +++ b/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Sun Nov 08 14:49:18 2009 -0800
30.3 @@ -119,12 +119,36 @@
30.4 }
30.5 }
30.6
30.7 + static final class LTQasSQ<T> extends LinkedTransferQueue<T> {
30.8 + LTQasSQ() { super(); }
30.9 + public void put(T x) {
30.10 + try { super.transfer(x); }
30.11 + catch (InterruptedException ex) { throw new Error(); }
30.12 + }
30.13 + private final static long serialVersionUID = 42;
30.14 + }
30.15 +
30.16 + static final class HalfSyncLTQ<T> extends LinkedTransferQueue<T> {
30.17 + HalfSyncLTQ() { super(); }
30.18 + public void put(T x) {
30.19 + if (ThreadLocalRandom.current().nextBoolean())
30.20 + super.put(x);
30.21 + else {
30.22 + try { super.transfer(x); }
30.23 + catch (InterruptedException ex) { throw new Error(); }
30.24 + }
30.25 + }
30.26 + private final static long serialVersionUID = 42;
30.27 + }
30.28 +
30.29 static void oneTest(int pairs, int iters) throws Exception {
30.30
30.31 oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
30.32 oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
30.33 oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
30.34 -// oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
30.35 + oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
30.36 + oneRun(new LTQasSQ<Integer>(), pairs, iters);
30.37 + oneRun(new HalfSyncLTQ<Integer>(), pairs, iters);
30.38 oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8);
30.39
30.40 /* PriorityBlockingQueue is unbounded
31.1 --- a/test/java/util/concurrent/BlockingQueue/LastElement.java Wed Nov 04 11:19:42 2009 -0800
31.2 +++ b/test/java/util/concurrent/BlockingQueue/LastElement.java Sun Nov 08 14:49:18 2009 -0800
31.3 @@ -37,7 +37,7 @@
31.4 testQueue(new LinkedBlockingDeque<Integer>());
31.5 testQueue(new ArrayBlockingQueue<Integer>(10, true));
31.6 testQueue(new ArrayBlockingQueue<Integer>(10, false));
31.7 -// testQueue(new LinkedTransferQueue<Integer>());
31.8 + testQueue(new LinkedTransferQueue<Integer>());
31.9
31.10 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
31.11 if (failed > 0) throw new Exception("Some tests failed");
32.1 --- a/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Wed Nov 04 11:19:42 2009 -0800
32.2 +++ b/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Sun Nov 08 14:49:18 2009 -0800
32.3 @@ -87,11 +87,35 @@
32.4 throw new Error();
32.5 }
32.6
32.7 + static final class LTQasSQ<T> extends LinkedTransferQueue<T> {
32.8 + LTQasSQ() { super(); }
32.9 + public void put(T x) {
32.10 + try { super.transfer(x); }
32.11 + catch (InterruptedException ex) { throw new Error(); }
32.12 + }
32.13 + private final static long serialVersionUID = 42;
32.14 + }
32.15 +
32.16 + static final class HalfSyncLTQ<T> extends LinkedTransferQueue<T> {
32.17 + HalfSyncLTQ() { super(); }
32.18 + public void put(T x) {
32.19 + if (ThreadLocalRandom.current().nextBoolean())
32.20 + super.put(x);
32.21 + else {
32.22 + try { super.transfer(x); }
32.23 + catch (InterruptedException ex) { throw new Error(); }
32.24 + }
32.25 + }
32.26 + private final static long serialVersionUID = 42;
32.27 + }
32.28 +
32.29 static void oneTest(int producers, int iters) throws Exception {
32.30 oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), producers, iters);
32.31 oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), producers, iters);
32.32 oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), producers, iters);
32.33 -// oneRun(new LinkedTransferQueue<Integer>(), producers, iters);
32.34 + oneRun(new LinkedTransferQueue<Integer>(), producers, iters);
32.35 + oneRun(new LTQasSQ<Integer>(), producers, iters);
32.36 + oneRun(new HalfSyncLTQ<Integer>(), producers, iters);
32.37
32.38 // Don't run PBQ since can legitimately run out of memory
32.39 // if (print)
33.1 --- a/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Wed Nov 04 11:19:42 2009 -0800
33.2 +++ b/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Sun Nov 08 14:49:18 2009 -0800
33.3 @@ -63,12 +63,11 @@
33.4 test(new LinkedBlockingDeque());
33.5 test(new LinkedBlockingDeque(2000));
33.6 test(new ArrayBlockingQueue(2000));
33.7 -// test(new LinkedTransferQueue());
33.8 + test(new LinkedTransferQueue());
33.9 }
33.10
33.11 Random getRandom() {
33.12 - return new Random();
33.13 - // return ThreadLocalRandom.current();
33.14 + return ThreadLocalRandom.current();
33.15 }
33.16
33.17 void test(final BlockingQueue q) throws Throwable {
34.1 --- a/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Wed Nov 04 11:19:42 2009 -0800
34.2 +++ b/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Sun Nov 08 14:49:18 2009 -0800
34.3 @@ -46,7 +46,7 @@
34.4 public static void main(String[] args) throws InterruptedException {
34.5 final BlockingQueue[] qs = {
34.6 new LinkedBlockingQueue(10),
34.7 -// new LinkedTransferQueue(),
34.8 + new LinkedTransferQueue(),
34.9 new ArrayBlockingQueue(10),
34.10 new SynchronousQueue(),
34.11 new SynchronousQueue(true),
35.1 --- a/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Wed Nov 04 11:19:42 2009 -0800
35.2 +++ b/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Sun Nov 08 14:49:18 2009 -0800
35.3 @@ -87,11 +87,35 @@
35.4 throw new Error();
35.5 }
35.6
35.7 + static final class LTQasSQ<T> extends LinkedTransferQueue<T> {
35.8 + LTQasSQ() { super(); }
35.9 + public void put(T x) {
35.10 + try { super.transfer(x); }
35.11 + catch (InterruptedException ex) { throw new Error(); }
35.12 + }
35.13 + private final static long serialVersionUID = 42;
35.14 + }
35.15 +
35.16 + static final class HalfSyncLTQ<T> extends LinkedTransferQueue<T> {
35.17 + HalfSyncLTQ() { super(); }
35.18 + public void put(T x) {
35.19 + if (ThreadLocalRandom.current().nextBoolean())
35.20 + super.put(x);
35.21 + else {
35.22 + try { super.transfer(x); }
35.23 + catch (InterruptedException ex) { throw new Error(); }
35.24 + }
35.25 + }
35.26 + private final static long serialVersionUID = 42;
35.27 + }
35.28 +
35.29 static void oneTest(int pairs, int iters) throws Exception {
35.30 oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
35.31 oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
35.32 oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
35.33 -// oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
35.34 + oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
35.35 + oneRun(new LTQasSQ<Integer>(), pairs, iters);
35.36 + oneRun(new HalfSyncLTQ<Integer>(), pairs, iters);
35.37 oneRun(new PriorityBlockingQueue<Integer>(), pairs, iters);
35.38 oneRun(new SynchronousQueue<Integer>(), pairs, iters);
35.39
36.1 --- a/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Wed Nov 04 11:19:42 2009 -0800
36.2 +++ b/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Sun Nov 08 14:49:18 2009 -0800
36.3 @@ -73,11 +73,35 @@
36.4 throw new Error();
36.5 }
36.6
36.7 + static final class LTQasSQ<T> extends LinkedTransferQueue<T> {
36.8 + LTQasSQ() { super(); }
36.9 + public void put(T x) {
36.10 + try { super.transfer(x); }
36.11 + catch (InterruptedException ex) { throw new Error(); }
36.12 + }
36.13 + private final static long serialVersionUID = 42;
36.14 + }
36.15 +
36.16 + static final class HalfSyncLTQ<T> extends LinkedTransferQueue<T> {
36.17 + HalfSyncLTQ() { super(); }
36.18 + public void put(T x) {
36.19 + if (ThreadLocalRandom.current().nextBoolean())
36.20 + super.put(x);
36.21 + else {
36.22 + try { super.transfer(x); }
36.23 + catch (InterruptedException ex) { throw new Error(); }
36.24 + }
36.25 + }
36.26 + private final static long serialVersionUID = 42;
36.27 + }
36.28 +
36.29 static void oneTest(int consumers, int iters) throws Exception {
36.30 oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), consumers, iters);
36.31 oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), consumers, iters);
36.32 oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), consumers, iters);
36.33 -// oneRun(new LinkedTransferQueue<Integer>(), consumers, iters);
36.34 + oneRun(new LinkedTransferQueue<Integer>(), consumers, iters);
36.35 + oneRun(new LTQasSQ<Integer>(), consumers, iters);
36.36 + oneRun(new HalfSyncLTQ<Integer>(), consumers, iters);
36.37 oneRun(new PriorityBlockingQueue<Integer>(), consumers, iters);
36.38 oneRun(new SynchronousQueue<Integer>(), consumers, iters);
36.39 if (print)
37.1 --- a/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Wed Nov 04 11:19:42 2009 -0800
37.2 +++ b/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Sun Nov 08 14:49:18 2009 -0800
37.3 @@ -60,7 +60,7 @@
37.4 //queues.add(new ArrayBlockingQueue<Integer>(count, true));
37.5 queues.add(new LinkedBlockingQueue<Integer>());
37.6 queues.add(new LinkedBlockingDeque<Integer>());
37.7 -// queues.add(new LinkedTransferQueue<Integer>());
37.8 + queues.add(new LinkedTransferQueue<Integer>());
37.9
37.10 // Following additional implementations are available from:
37.11 // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html
38.1 --- a/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Wed Nov 04 11:19:42 2009 -0800
38.2 +++ b/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Sun Nov 08 14:49:18 2009 -0800
38.3 @@ -43,7 +43,7 @@
38.4 import java.util.concurrent.ConcurrentLinkedQueue;
38.5 import java.util.concurrent.LinkedBlockingDeque;
38.6 import java.util.concurrent.LinkedBlockingQueue;
38.7 -// import java.util.concurrent.LinkedTransferQueue;
38.8 +import java.util.concurrent.LinkedTransferQueue;
38.9 import java.util.concurrent.PriorityBlockingQueue;
38.10 import java.util.LinkedList;
38.11 import java.util.PriorityQueue;
38.12 @@ -70,7 +70,7 @@
38.13 queues.add(new PriorityBlockingQueue<Boolean>());
38.14 queues.add(new PriorityQueue<Boolean>());
38.15 queues.add(new LinkedList<Boolean>());
38.16 -// queues.add(new LinkedTransferQueue<Boolean>());
38.17 + queues.add(new LinkedTransferQueue<Boolean>());
38.18
38.19 // Following additional implementations are available from:
38.20 // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html
39.1 --- a/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Wed Nov 04 11:19:42 2009 -0800
39.2 +++ b/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Sun Nov 08 14:49:18 2009 -0800
39.3 @@ -49,7 +49,7 @@
39.4 test(new LinkedBlockingDeque());
39.5 test(new LinkedBlockingDeque(20));
39.6 test(new ConcurrentLinkedQueue());
39.7 -// test(new LinkedTransferQueue());
39.8 + test(new LinkedTransferQueue());
39.9 // Other concurrent queues (e.g. ArrayBlockingQueue) do not
39.10 // currently have weakly consistent iterators.
39.11 // test(new ArrayBlockingQueue(20));
40.1 --- a/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Wed Nov 04 11:19:42 2009 -0800
40.2 +++ b/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Sun Nov 08 14:49:18 2009 -0800
40.3 @@ -56,12 +56,11 @@
40.4 testQueue(new ArrayBlockingQueue(10));
40.5 testQueue(new PriorityBlockingQueue(10));
40.6 testQueue(new ConcurrentLinkedQueue());
40.7 -// testQueue(new LinkedTransferQueue());
40.8 + testQueue(new LinkedTransferQueue());
40.9 }
40.10
40.11 Random getRandom() {
40.12 - return new Random();
40.13 - // return ThreadLocalRandom.current();
40.14 + return ThreadLocalRandom.current();
40.15 }
40.16
40.17 void testQueue(final Queue q) throws Throwable {
41.1 --- a/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Wed Nov 04 11:19:42 2009 -0800
41.2 +++ b/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Sun Nov 08 14:49:18 2009 -0800
41.3 @@ -45,7 +45,7 @@
41.4 import java.util.concurrent.CountDownLatch;
41.5 import java.util.concurrent.LinkedBlockingDeque;
41.6 import java.util.concurrent.LinkedBlockingQueue;
41.7 -// import java.util.concurrent.LinkedTransferQueue;
41.8 +import java.util.concurrent.LinkedTransferQueue;
41.9 import java.util.concurrent.atomic.AtomicLong;
41.10 import java.util.ArrayList;
41.11 import java.util.Collection;
41.12 @@ -67,7 +67,7 @@
41.13 queues.add(new ArrayBlockingQueue<Boolean>(count, true));
41.14 queues.add(new LinkedBlockingQueue<Boolean>());
41.15 queues.add(new LinkedBlockingDeque<Boolean>());
41.16 -// queues.add(new LinkedTransferQueue<Boolean>());
41.17 + queues.add(new LinkedTransferQueue<Boolean>());
41.18
41.19 // Following additional implementations are available from:
41.20 // http://gee.cs.oswego.edu/dl/concurrency-interest/index.html
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/test/java/util/concurrent/Phaser/Arrive.java Sun Nov 08 14:49:18 2009 -0800
42.3 @@ -0,0 +1,94 @@
42.4 +/*
42.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
42.6 + *
42.7 + * This code is free software; you can redistribute it and/or modify it
42.8 + * under the terms of the GNU General Public License version 2 only, as
42.9 + * published by the Free Software Foundation.
42.10 + *
42.11 + * This code is distributed in the hope that it will be useful, but WITHOUT
42.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
42.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42.14 + * version 2 for more details (a copy is included in the LICENSE file that
42.15 + * accompanied this code).
42.16 + *
42.17 + * You should have received a copy of the GNU General Public License version
42.18 + * 2 along with this work; if not, write to the Free Software Foundation,
42.19 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
42.20 + *
42.21 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
42.22 + * CA 95054 USA or visit www.sun.com if you need additional information or
42.23 + * have any questions.
42.24 + */
42.25 +
42.26 +/*
42.27 + * This file is available under and governed by the GNU General Public
42.28 + * License version 2 only, as published by the Free Software Foundation.
42.29 + * However, the following notice accompanied the original version of this
42.30 + * file:
42.31 + *
42.32 + * Written by Doug Lea with assistance from members of JCP JSR-166
42.33 + * Expert Group and released to the public domain, as explained at
42.34 + * http://creativecommons.org/licenses/publicdomain
42.35 + */
42.36 +
42.37 +/*
42.38 + * @test
42.39 + * @bug 6445158
42.40 + * @summary tests for Phaser.arrive()
42.41 + */
42.42 +
42.43 +import java.util.ArrayList;
42.44 +import java.util.List;
42.45 +import java.util.concurrent.Phaser;
42.46 +import java.util.concurrent.ThreadLocalRandom;
42.47 +import java.util.concurrent.atomic.AtomicInteger;
42.48 +
42.49 +public class Arrive {
42.50 + void test(String[] args) throws Throwable {
42.51 + final int n = ThreadLocalRandom.current().nextInt(1, 10);
42.52 + final int nthreads = n*3/2;
42.53 + final Phaser startingGate = new Phaser(nthreads);
42.54 + final Phaser phaser = new Phaser(n);
42.55 + final List<Thread> threads = new ArrayList<Thread>();
42.56 + final AtomicInteger count0 = new AtomicInteger(0);
42.57 + final AtomicInteger count1 = new AtomicInteger(0);
42.58 + final Runnable task = new Runnable() { public void run() {
42.59 + equal(startingGate.getPhase(), 0);
42.60 + startingGate.arriveAndAwaitAdvance();
42.61 + equal(startingGate.getPhase(), 1);
42.62 + int phase = phaser.arrive();
42.63 + if (phase == 0)
42.64 + count0.getAndIncrement();
42.65 + else if (phase == 1)
42.66 + count1.getAndIncrement();
42.67 + else
42.68 + fail();
42.69 + }};
42.70 + for (int i = 0; i < nthreads; i++)
42.71 + threads.add(new Thread(task));
42.72 + for (Thread thread : threads)
42.73 + thread.start();
42.74 + for (Thread thread : threads)
42.75 + thread.join();
42.76 + equal(count0.get(), n);
42.77 + equal(count1.get(), nthreads-n);
42.78 + equal(phaser.getPhase(), 1);
42.79 + }
42.80 +
42.81 + //--------------------- Infrastructure ---------------------------
42.82 + volatile int passed = 0, failed = 0;
42.83 + void pass() {passed++;}
42.84 + void fail() {failed++; Thread.dumpStack();}
42.85 + void fail(String msg) {System.err.println(msg); fail();}
42.86 + void unexpected(Throwable t) {failed++; t.printStackTrace();}
42.87 + void check(boolean cond) {if (cond) pass(); else fail();}
42.88 + void equal(Object x, Object y) {
42.89 + if (x == null ? y == null : x.equals(y)) pass();
42.90 + else fail(x + " not equal to " + y);}
42.91 + public static void main(String[] args) throws Throwable {
42.92 + new Arrive().instanceMain(args);}
42.93 + public void instanceMain(String[] args) throws Throwable {
42.94 + try {test(args);} catch (Throwable t) {unexpected(t);}
42.95 + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
42.96 + if (failed > 0) throw new AssertionError("Some tests failed");}
42.97 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/test/java/util/concurrent/Phaser/Basic.java Sun Nov 08 14:49:18 2009 -0800
43.3 @@ -0,0 +1,407 @@
43.4 +/*
43.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
43.6 + *
43.7 + * This code is free software; you can redistribute it and/or modify it
43.8 + * under the terms of the GNU General Public License version 2 only, as
43.9 + * published by the Free Software Foundation.
43.10 + *
43.11 + * This code is distributed in the hope that it will be useful, but WITHOUT
43.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
43.14 + * version 2 for more details (a copy is included in the LICENSE file that
43.15 + * accompanied this code).
43.16 + *
43.17 + * You should have received a copy of the GNU General Public License version
43.18 + * 2 along with this work; if not, write to the Free Software Foundation,
43.19 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
43.20 + *
43.21 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
43.22 + * CA 95054 USA or visit www.sun.com if you need additional information or
43.23 + * have any questions.
43.24 + */
43.25 +
43.26 +/*
43.27 + * This file is available under and governed by the GNU General Public
43.28 + * License version 2 only, as published by the Free Software Foundation.
43.29 + * However, the following notice accompanied the original version of this
43.30 + * file:
43.31 + *
43.32 + * Written by Doug Lea with assistance from members of JCP JSR-166
43.33 + * Expert Group and released to the public domain, as explained at
43.34 + * http://creativecommons.org/licenses/publicdomain
43.35 + */
43.36 +
43.37 +/*
43.38 + * @test
43.39 + * @bug 6445158
43.40 + * @summary Basic tests for Phaser
43.41 + * @author Chris Hegarty
43.42 + */
43.43 +
43.44 +import java.util.Iterator;
43.45 +import java.util.LinkedList;
43.46 +import java.util.concurrent.Phaser;
43.47 +import java.util.concurrent.TimeUnit;
43.48 +import java.util.concurrent.TimeoutException;
43.49 +import java.util.concurrent.atomic.AtomicInteger;
43.50 +import static java.util.concurrent.TimeUnit.*;
43.51 +
43.52 +public class Basic {
43.53 +
43.54 + private static void checkTerminated(final Phaser phaser) {
43.55 + check(phaser.isTerminated());
43.56 + int unarriverParties = phaser.getUnarrivedParties();
43.57 + int registeredParties = phaser.getRegisteredParties();
43.58 + equal(phaser.arrive(), -1);
43.59 + equal(phaser.arriveAndDeregister(), -1);
43.60 + equal(phaser.arriveAndAwaitAdvance(), -1);
43.61 + equal(phaser.bulkRegister(10), -1);
43.62 + equal(phaser.getPhase(), -1);
43.63 + equal(phaser.register(), -1);
43.64 + try {
43.65 + equal(phaser.awaitAdvanceInterruptibly(0), -1);
43.66 + equal(phaser.awaitAdvanceInterruptibly(0, 10, SECONDS), -1);
43.67 + } catch (Exception ie) {
43.68 + unexpected(ie);
43.69 + }
43.70 + equal(phaser.getUnarrivedParties(), unarriverParties);
43.71 + equal(phaser.getRegisteredParties(), registeredParties);
43.72 + }
43.73 +
43.74 + private static void checkResult(Arriver a, Class<? extends Throwable> c) {
43.75 + Throwable t = a.result();
43.76 + if (! ((t == null && c == null) || (c != null && c.isInstance(t)))) {
43.77 + // t.printStackTrace();
43.78 + fail("Mismatch in thread " +
43.79 + a.getName() + ": " +
43.80 + t + ", " +
43.81 + (c == null ? "<null>" : c.getName()));
43.82 + } else {
43.83 + pass();
43.84 + }
43.85 + }
43.86 +
43.87 + //----------------------------------------------------------------
43.88 + // Mechanism to get all test threads into "running" mode.
43.89 + //----------------------------------------------------------------
43.90 + private static Phaser atTheStartingGate = new Phaser(3);
43.91 +
43.92 + private static void toTheStartingGate() {
43.93 + try {
43.94 + boolean expectNextPhase = false;
43.95 + if (atTheStartingGate.getUnarrivedParties() == 1) {
43.96 + expectNextPhase = true;
43.97 + }
43.98 + int phase = atTheStartingGate.getPhase();
43.99 + equal(phase, atTheStartingGate.arrive());
43.100 + int AwaitPhase = atTheStartingGate.awaitAdvanceInterruptibly(phase,
43.101 + 10,
43.102 + SECONDS);
43.103 + if (expectNextPhase) check(AwaitPhase == (phase + 1));
43.104 +
43.105 + pass();
43.106 + } catch (Throwable t) {
43.107 + unexpected(t);
43.108 + // reset(atTheStartingGate);
43.109 + throw new Error(t);
43.110 + }
43.111 + }
43.112 +
43.113 + //----------------------------------------------------------------
43.114 + // Convenience methods for creating threads that call arrive,
43.115 + // awaitAdvance, arriveAndAwaitAdvance, awaitAdvanceInterruptibly
43.116 + //----------------------------------------------------------------
43.117 + private static abstract class Arriver extends Thread {
43.118 + static AtomicInteger count = new AtomicInteger(1);
43.119 +
43.120 + Arriver() {
43.121 + this("Arriver");
43.122 + }
43.123 +
43.124 + Arriver(String name) {
43.125 + this.setName(name + ":" + count.getAndIncrement());
43.126 + this.setDaemon(true);
43.127 + }
43.128 +
43.129 + private volatile Throwable result;
43.130 + private volatile int phase;
43.131 + protected void result(Throwable result) { this.result = result; }
43.132 + public Throwable result() { return this.result; }
43.133 + protected void phase(int phase) { this.phase = phase; }
43.134 + public int phase() { return this.phase; }
43.135 + }
43.136 +
43.137 + private static abstract class Awaiter extends Arriver {
43.138 + Awaiter() { super("Awaiter"); }
43.139 + Awaiter(String name) { super(name); }
43.140 + }
43.141 +
43.142 + private static Arriver arriver(final Phaser phaser) {
43.143 + return new Arriver() { public void run() {
43.144 + toTheStartingGate();
43.145 +
43.146 + try { phase(phaser.arrive()); }
43.147 + catch (Throwable result) { result(result); }}};
43.148 + }
43.149 +
43.150 + private static AtomicInteger cycleArriveAwaitAdvance = new AtomicInteger(1);
43.151 +
43.152 + private static Awaiter awaiter(final Phaser phaser) {
43.153 + return new Awaiter() { public void run() {
43.154 + toTheStartingGate();
43.155 +
43.156 + try {
43.157 + if (cycleArriveAwaitAdvance.getAndIncrement() % 2 == 0)
43.158 + phase(phaser.awaitAdvance(phaser.arrive()));
43.159 + else
43.160 + phase(phaser.arriveAndAwaitAdvance());
43.161 + } catch (Throwable result) { result(result); }}};
43.162 + }
43.163 +
43.164 + private static Awaiter awaiter(final Phaser phaser,
43.165 + final long timeout,
43.166 + final TimeUnit unit) {
43.167 + return new Awaiter("InterruptibleWaiter") { public void run() {
43.168 + toTheStartingGate();
43.169 +
43.170 + try {
43.171 + if (timeout < 0)
43.172 + phase(phaser.awaitAdvanceInterruptibly(phaser.arrive()));
43.173 + else
43.174 + phase(phaser.awaitAdvanceInterruptibly(phaser.arrive(),
43.175 + timeout,
43.176 + unit));
43.177 + } catch (Throwable result) { result(result); }}};
43.178 + }
43.179 +
43.180 + // Returns an infinite lazy list of all possible arriver/awaiter combinations.
43.181 + private static Iterator<Arriver> arriverIterator(final Phaser phaser) {
43.182 + return new Iterator<Arriver>() {
43.183 + int i = 0;
43.184 + public boolean hasNext() { return true; }
43.185 + public Arriver next() {
43.186 + switch ((i++)&7) {
43.187 + case 0: case 4:
43.188 + return arriver(phaser);
43.189 + case 1: case 5:
43.190 + return awaiter(phaser);
43.191 + case 2: case 6: case 7:
43.192 + return awaiter(phaser, -1, SECONDS);
43.193 + default:
43.194 + return awaiter(phaser, 10, SECONDS); }}
43.195 + public void remove() {throw new UnsupportedOperationException();}};
43.196 + }
43.197 +
43.198 + // Returns an infinite lazy list of all possible awaiter only combinations.
43.199 + private static Iterator<Awaiter> awaiterIterator(final Phaser phaser) {
43.200 + return new Iterator<Awaiter>() {
43.201 + int i = 0;
43.202 + public boolean hasNext() { return true; }
43.203 + public Awaiter next() {
43.204 + switch ((i++)&7) {
43.205 + case 1: case 4: case 7:
43.206 + return awaiter(phaser);
43.207 + case 2: case 5:
43.208 + return awaiter(phaser, -1, SECONDS);
43.209 + default:
43.210 + return awaiter(phaser, 10, SECONDS); }}
43.211 + public void remove() {throw new UnsupportedOperationException();}};
43.212 + }
43.213 +
43.214 + private static void realMain(String[] args) throws Throwable {
43.215 +
43.216 + Thread.currentThread().setName("mainThread");
43.217 +
43.218 + //----------------------------------------------------------------
43.219 + // Normal use
43.220 + //----------------------------------------------------------------
43.221 + try {
43.222 + Phaser phaser = new Phaser(3);
43.223 + equal(phaser.getRegisteredParties(), 3);
43.224 + equal(phaser.getArrivedParties(), 0);
43.225 + equal(phaser.getPhase(), 0);
43.226 + check(phaser.getRoot().equals(phaser));
43.227 + equal(phaser.getParent(), null);
43.228 + check(!phaser.isTerminated());
43.229 +
43.230 + Iterator<Arriver> arrivers = arriverIterator(phaser);
43.231 + int phase = 0;
43.232 + for (int i = 0; i < 10; i++) {
43.233 + equal(phaser.getPhase(), phase++);
43.234 + Arriver a1 = arrivers.next(); a1.start();
43.235 + Arriver a2 = arrivers.next(); a2.start();
43.236 + toTheStartingGate();
43.237 + phaser.arriveAndAwaitAdvance();
43.238 + a1.join();
43.239 + a2.join();
43.240 + checkResult(a1, null);
43.241 + checkResult(a2, null);
43.242 + check(!phaser.isTerminated());
43.243 + equal(phaser.getRegisteredParties(), 3);
43.244 + equal(phaser.getArrivedParties(), 0);
43.245 + }
43.246 + } catch (Throwable t) { unexpected(t); }
43.247 +
43.248 + //----------------------------------------------------------------
43.249 + // One thread interrupted
43.250 + //----------------------------------------------------------------
43.251 + try {
43.252 + Phaser phaser = new Phaser(3);
43.253 + Iterator<Arriver> arrivers = arriverIterator(phaser);
43.254 + int phase = phaser.getPhase();
43.255 + for (int i = 0; i < 4; i++) {
43.256 + check(phaser.getPhase() == phase);
43.257 + Awaiter a1 = awaiter(phaser, 10, SECONDS); a1.start();
43.258 + Arriver a2 = arrivers.next(); a2.start();
43.259 + toTheStartingGate();
43.260 + a1.interrupt();
43.261 + a1.join();
43.262 + phaser.arriveAndAwaitAdvance();
43.263 + a2.join();
43.264 + checkResult(a1, InterruptedException.class);
43.265 + checkResult(a2, null);
43.266 + check(!phaser.isTerminated());
43.267 + equal(phaser.getRegisteredParties(), 3);
43.268 + equal(phaser.getArrivedParties(), 0);
43.269 + phase++;
43.270 + }
43.271 + } catch (Throwable t) { unexpected(t); }
43.272 +
43.273 + //----------------------------------------------------------------
43.274 + // Phaser is terminated while threads are waiting
43.275 + //----------------------------------------------------------------
43.276 + try {
43.277 + Phaser phaser = new Phaser(3);
43.278 + Iterator<Awaiter> awaiters = awaiterIterator(phaser);
43.279 + for (int i = 0; i < 4; i++) {
43.280 + Arriver a1 = awaiters.next(); a1.start();
43.281 + Arriver a2 = awaiters.next(); a2.start();
43.282 + toTheStartingGate();
43.283 + while (phaser.getArrivedParties() < 2) Thread.yield();
43.284 + phaser.forceTermination();
43.285 + a1.join();
43.286 + a2.join();
43.287 + check(a1.phase == -1);
43.288 + check(a2.phase == -1);
43.289 + int arrivedParties = phaser.getArrivedParties();
43.290 + checkTerminated(phaser);
43.291 + equal(phaser.getArrivedParties(), arrivedParties);
43.292 + }
43.293 + } catch (Throwable t) { unexpected(t); }
43.294 +
43.295 + //----------------------------------------------------------------
43.296 + // Adds new unarrived parties to this phaser
43.297 + //----------------------------------------------------------------
43.298 + try {
43.299 + Phaser phaser = new Phaser(1);
43.300 + Iterator<Arriver> arrivers = arriverIterator(phaser);
43.301 + LinkedList<Arriver> arriverList = new LinkedList<Arriver>();
43.302 + int phase = phaser.getPhase();
43.303 + for (int i = 1; i < 5; i++) {
43.304 + atTheStartingGate = new Phaser(1+(3*i));
43.305 + check(phaser.getPhase() == phase);
43.306 + // register 3 more
43.307 + phaser.register(); phaser.register(); phaser.register();
43.308 + for (int z=0; z<(3*i); z++) {
43.309 + arriverList.add(arrivers.next());
43.310 + }
43.311 + for (Arriver arriver : arriverList)
43.312 + arriver.start();
43.313 +
43.314 + toTheStartingGate();
43.315 + phaser.arriveAndAwaitAdvance();
43.316 +
43.317 + for (Arriver arriver : arriverList) {
43.318 + arriver.join();
43.319 + checkResult(arriver, null);
43.320 + }
43.321 + equal(phaser.getRegisteredParties(), 1 + (3*i));
43.322 + equal(phaser.getArrivedParties(), 0);
43.323 + arriverList.clear();
43.324 + phase++;
43.325 + }
43.326 + atTheStartingGate = new Phaser(3);
43.327 + } catch (Throwable t) { unexpected(t); }
43.328 +
43.329 + //----------------------------------------------------------------
43.330 + // One thread timed out
43.331 + //----------------------------------------------------------------
43.332 + try {
43.333 + Phaser phaser = new Phaser(3);
43.334 + Iterator<Arriver> arrivers = arriverIterator(phaser);
43.335 + for (long timeout : new long[] { 0L, 5L }) {
43.336 + for (int i = 0; i < 2; i++) {
43.337 + Awaiter a1 = awaiter(phaser, timeout, SECONDS); a1.start();
43.338 + Arriver a2 = arrivers.next(); a2.start();
43.339 + toTheStartingGate();
43.340 + a1.join();
43.341 + checkResult(a1, TimeoutException.class);
43.342 + phaser.arrive();
43.343 + a2.join();
43.344 + checkResult(a2, null);
43.345 + check(!phaser.isTerminated());
43.346 + }
43.347 + }
43.348 + } catch (Throwable t) { unexpected(t); }
43.349 +
43.350 + //----------------------------------------------------------------
43.351 + // Barrier action completed normally
43.352 + //----------------------------------------------------------------
43.353 + try {
43.354 + final AtomicInteger count = new AtomicInteger(0);
43.355 + final Phaser[] kludge = new Phaser[1];
43.356 + Phaser phaser = new Phaser(3) {
43.357 + @Override
43.358 + protected boolean onAdvance(int phase, int registeredParties) {
43.359 + int countPhase = count.getAndIncrement();
43.360 + equal(countPhase, phase);
43.361 + equal(kludge[0].getPhase(), phase);
43.362 + equal(kludge[0].getRegisteredParties(), registeredParties);
43.363 + if (phase >= 3)
43.364 + return true; // terminate
43.365 +
43.366 + return false;
43.367 + }
43.368 + };
43.369 + kludge[0] = phaser;
43.370 + equal(phaser.getRegisteredParties(), 3);
43.371 + Iterator<Awaiter> awaiters = awaiterIterator(phaser);
43.372 + for (int i = 0; i < 4; i++) {
43.373 + Awaiter a1 = awaiters.next(); a1.start();
43.374 + Awaiter a2 = awaiters.next(); a2.start();
43.375 + toTheStartingGate();
43.376 + while (phaser.getArrivedParties() < 2) Thread.yield();
43.377 + phaser.arrive();
43.378 + a1.join();
43.379 + a2.join();
43.380 + checkResult(a1, null);
43.381 + checkResult(a2, null);
43.382 + equal(count.get(), i+1);
43.383 + if (i < 3) {
43.384 + check(!phaser.isTerminated());
43.385 + equal(phaser.getRegisteredParties(), 3);
43.386 + equal(phaser.getArrivedParties(), 0);
43.387 + equal(phaser.getUnarrivedParties(), 3);
43.388 + equal(phaser.getPhase(), count.get());
43.389 + } else
43.390 + checkTerminated(phaser);
43.391 + }
43.392 + } catch (Throwable t) { unexpected(t); }
43.393 +
43.394 + }
43.395 +
43.396 + //--------------------- Infrastructure ---------------------------
43.397 + static volatile int passed = 0, failed = 0;
43.398 + static void pass() {passed++;}
43.399 + static void fail() {failed++; Thread.dumpStack();}
43.400 + static void fail(String msg) {System.out.println(msg); fail();}
43.401 + static void unexpected(Throwable t) {failed++; t.printStackTrace();}
43.402 + static void check(boolean cond) {if (cond) pass(); else fail();}
43.403 + static void equal(Object x, Object y) {
43.404 + if (x == null ? y == null : x.equals(y)) pass();
43.405 + else fail(x + " not equal to " + y);}
43.406 + public static void main(String[] args) throws Throwable {
43.407 + try {realMain(args);} catch (Throwable t) {unexpected(t);}
43.408 + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
43.409 + if (failed > 0) throw new AssertionError("Some tests failed");}
43.410 +}
44.1 --- a/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Wed Nov 04 11:19:42 2009 -0800
44.2 +++ b/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Sun Nov 08 14:49:18 2009 -0800
44.3 @@ -21,6 +21,17 @@
44.4 */
44.5
44.6 /*
44.7 + * This file is available under and governed by the GNU General Public
44.8 + * License version 2 only, as published by the Free Software Foundation.
44.9 + * However, the following notice accompanied the original version of this
44.10 + * file:
44.11 + *
44.12 + * Written by Doug Lea with assistance from members of JCP JSR-166
44.13 + * Expert Group and released to the public domain, as explained at
44.14 + * http://creativecommons.org/licenses/publicdomain
44.15 + */
44.16 +
44.17 +/*
44.18 * @test
44.19 * @bug 6725789
44.20 * @summary Check for long overflow in task time comparison.
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/test/java/util/concurrent/forkjoin/Integrate.java Sun Nov 08 14:49:18 2009 -0800
45.3 @@ -0,0 +1,265 @@
45.4 +/*
45.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45.6 + *
45.7 + * This code is free software; you can redistribute it and/or modify it
45.8 + * under the terms of the GNU General Public License version 2 only, as
45.9 + * published by the Free Software Foundation.
45.10 + *
45.11 + * This code is distributed in the hope that it will be useful, but WITHOUT
45.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
45.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45.14 + * version 2 for more details (a copy is included in the LICENSE file that
45.15 + * accompanied this code).
45.16 + *
45.17 + * You should have received a copy of the GNU General Public License version
45.18 + * 2 along with this work; if not, write to the Free Software Foundation,
45.19 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
45.20 + *
45.21 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
45.22 + * CA 95054 USA or visit www.sun.com if you need additional information or
45.23 + * have any questions.
45.24 + */
45.25 +
45.26 +/*
45.27 + * This file is available under and governed by the GNU General Public
45.28 + * License version 2 only, as published by the Free Software Foundation.
45.29 + * However, the following notice accompanied the original version of this
45.30 + * file:
45.31 + *
45.32 + * Written by Doug Lea with assistance from members of JCP JSR-166
45.33 + * Expert Group and released to the public domain, as explained at
45.34 + * http://creativecommons.org/licenses/publicdomain
45.35 + */
45.36 +
45.37 +/*
45.38 + * @test
45.39 + * @bug 6865571
45.40 + * @summary Numerical Integration using fork/join
45.41 + * @run main Integrate reps=1 forkPolicy=dynamic
45.42 + * @run main Integrate reps=1 forkPolicy=serial
45.43 + * @run main Integrate reps=1 forkPolicy=fork
45.44 + */
45.45 +
45.46 +import java.util.concurrent.ForkJoinPool;
45.47 +import java.util.concurrent.RecursiveAction;
45.48 +
45.49 +/**
45.50 + * Sample program using Gaussian Quadrature for numerical integration.
45.51 + * This version uses a simplified hardwired function. Inspired by a
45.52 + * <A href="http://www.cs.uga.edu/~dkl/filaments/dist.html">
45.53 + * Filaments</A> demo program.
45.54 + */
45.55 +public final class Integrate {
45.56 +
45.57 + static final double errorTolerance = 1.0e-11;
45.58 + /** for time conversion */
45.59 + static final long NPS = (1000L * 1000 * 1000);
45.60 +
45.61 + static final int SERIAL = -1;
45.62 + static final int DYNAMIC = 0;
45.63 + static final int FORK = 1;
45.64 +
45.65 + // the function to integrate
45.66 + static double computeFunction(double x) {
45.67 + return (x * x + 1.0) * x;
45.68 + }
45.69 +
45.70 + static final double start = 0.0;
45.71 + static final double end = 1536.0;
45.72 + /*
45.73 + * The number of recursive calls for
45.74 + * integrate from start to end.
45.75 + * (Empirically determined)
45.76 + */
45.77 + static final int calls = 263479047;
45.78 +
45.79 + static String keywordValue(String[] args, String keyword) {
45.80 + for (String arg : args)
45.81 + if (arg.startsWith(keyword))
45.82 + return arg.substring(keyword.length() + 1);
45.83 + return null;
45.84 + }
45.85 +
45.86 + static int intArg(String[] args, String keyword, int defaultValue) {
45.87 + String val = keywordValue(args, keyword);
45.88 + return (val == null) ? defaultValue : Integer.parseInt(val);
45.89 + }
45.90 +
45.91 + static int policyArg(String[] args, String keyword, int defaultPolicy) {
45.92 + String val = keywordValue(args, keyword);
45.93 + if (val == null) return defaultPolicy;
45.94 + if (val.equals("dynamic")) return DYNAMIC;
45.95 + if (val.equals("serial")) return SERIAL;
45.96 + if (val.equals("fork")) return FORK;
45.97 + throw new Error();
45.98 + }
45.99 +
45.100 + /**
45.101 + * Usage: Integrate [procs=N] [reps=N] forkPolicy=serial|dynamic|fork
45.102 + */
45.103 + public static void main(String[] args) throws Exception {
45.104 + final int procs = intArg(args, "procs",
45.105 + Runtime.getRuntime().availableProcessors());
45.106 + final int forkPolicy = policyArg(args, "forkPolicy", DYNAMIC);
45.107 +
45.108 + ForkJoinPool g = new ForkJoinPool(procs);
45.109 + System.out.println("Integrating from " + start + " to " + end +
45.110 + " forkPolicy = " + forkPolicy);
45.111 + long lastTime = System.nanoTime();
45.112 +
45.113 + for (int reps = intArg(args, "reps", 10); reps > 0; reps--) {
45.114 + double a;
45.115 + if (forkPolicy == SERIAL)
45.116 + a = SQuad.computeArea(g, start, end);
45.117 + else if (forkPolicy == FORK)
45.118 + a = FQuad.computeArea(g, start, end);
45.119 + else
45.120 + a = DQuad.computeArea(g, start, end);
45.121 + long now = System.nanoTime();
45.122 + double s = (double) (now - lastTime) / NPS;
45.123 + lastTime = now;
45.124 + System.out.printf("Calls/sec: %12d", (long) (calls / s));
45.125 + System.out.printf(" Time: %7.3f", s);
45.126 + System.out.printf(" Area: %12.1f", a);
45.127 + System.out.println();
45.128 + }
45.129 + System.out.println(g);
45.130 + g.shutdown();
45.131 + }
45.132 +
45.133 +
45.134 + // Sequential version
45.135 + static final class SQuad extends RecursiveAction {
45.136 + static double computeArea(ForkJoinPool pool, double l, double r) {
45.137 + SQuad q = new SQuad(l, r, 0);
45.138 + pool.invoke(q);
45.139 + return q.area;
45.140 + }
45.141 +
45.142 + final double left; // lower bound
45.143 + final double right; // upper bound
45.144 + double area;
45.145 +
45.146 + SQuad(double l, double r, double a) {
45.147 + this.left = l; this.right = r; this.area = a;
45.148 + }
45.149 +
45.150 + public final void compute() {
45.151 + double l = left;
45.152 + double r = right;
45.153 + area = recEval(l, r, (l * l + 1.0) * l, (r * r + 1.0) * r, area);
45.154 + }
45.155 +
45.156 + static final double recEval(double l, double r, double fl,
45.157 + double fr, double a) {
45.158 + double h = (r - l) * 0.5;
45.159 + double c = l + h;
45.160 + double fc = (c * c + 1.0) * c;
45.161 + double hh = h * 0.5;
45.162 + double al = (fl + fc) * hh;
45.163 + double ar = (fr + fc) * hh;
45.164 + double alr = al + ar;
45.165 + if (Math.abs(alr - a) <= errorTolerance)
45.166 + return alr;
45.167 + else
45.168 + return recEval(c, r, fc, fr, ar) + recEval(l, c, fl, fc, al);
45.169 + }
45.170 +
45.171 + }
45.172 +
45.173 + //....................................
45.174 +
45.175 + // ForkJoin version
45.176 + static final class FQuad extends RecursiveAction {
45.177 + static double computeArea(ForkJoinPool pool, double l, double r) {
45.178 + FQuad q = new FQuad(l, r, 0);
45.179 + pool.invoke(q);
45.180 + return q.area;
45.181 + }
45.182 +
45.183 + final double left; // lower bound
45.184 + final double right; // upper bound
45.185 + double area;
45.186 +
45.187 + FQuad(double l, double r, double a) {
45.188 + this.left = l; this.right = r; this.area = a;
45.189 + }
45.190 +
45.191 + public final void compute() {
45.192 + double l = left;
45.193 + double r = right;
45.194 + area = recEval(l, r, (l * l + 1.0) * l, (r * r + 1.0) * r, area);
45.195 + }
45.196 +
45.197 + static final double recEval(double l, double r, double fl,
45.198 + double fr, double a) {
45.199 + double h = (r - l) * 0.5;
45.200 + double c = l + h;
45.201 + double fc = (c * c + 1.0) * c;
45.202 + double hh = h * 0.5;
45.203 + double al = (fl + fc) * hh;
45.204 + double ar = (fr + fc) * hh;
45.205 + double alr = al + ar;
45.206 + if (Math.abs(alr - a) <= errorTolerance)
45.207 + return alr;
45.208 + FQuad q = new FQuad(l, c, al);
45.209 + q.fork();
45.210 + ar = recEval(c, r, fc, fr, ar);
45.211 + if (!q.tryUnfork()) {
45.212 + q.quietlyHelpJoin();
45.213 + return ar + q.area;
45.214 + }
45.215 + return ar + recEval(l, c, fl, fc, al);
45.216 + }
45.217 +
45.218 + }
45.219 +
45.220 + // ...........................
45.221 +
45.222 + // Version using on-demand Fork
45.223 + static final class DQuad extends RecursiveAction {
45.224 + static double computeArea(ForkJoinPool pool, double l, double r) {
45.225 + DQuad q = new DQuad(l, r, 0);
45.226 + pool.invoke(q);
45.227 + return q.area;
45.228 + }
45.229 +
45.230 + final double left; // lower bound
45.231 + final double right; // upper bound
45.232 + double area;
45.233 +
45.234 + DQuad(double l, double r, double a) {
45.235 + this.left = l; this.right = r; this.area = a;
45.236 + }
45.237 +
45.238 + public final void compute() {
45.239 + double l = left;
45.240 + double r = right;
45.241 + area = recEval(l, r, (l * l + 1.0) * l, (r * r + 1.0) * r, area);
45.242 + }
45.243 +
45.244 + static final double recEval(double l, double r, double fl,
45.245 + double fr, double a) {
45.246 + double h = (r - l) * 0.5;
45.247 + double c = l + h;
45.248 + double fc = (c * c + 1.0) * c;
45.249 + double hh = h * 0.5;
45.250 + double al = (fl + fc) * hh;
45.251 + double ar = (fr + fc) * hh;
45.252 + double alr = al + ar;
45.253 + if (Math.abs(alr - a) <= errorTolerance)
45.254 + return alr;
45.255 + DQuad q = null;
45.256 + if (getSurplusQueuedTaskCount() <= 3)
45.257 + (q = new DQuad(l, c, al)).fork();
45.258 + ar = recEval(c, r, fc, fr, ar);
45.259 + if (q != null && !q.tryUnfork()) {
45.260 + q.quietlyHelpJoin();
45.261 + return ar + q.area;
45.262 + }
45.263 + return ar + recEval(l, c, fl, fc, al);
45.264 + }
45.265 +
45.266 + }
45.267 +
45.268 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/test/java/util/concurrent/forkjoin/NQueensCS.java Sun Nov 08 14:49:18 2009 -0800
46.3 @@ -0,0 +1,174 @@
46.4 +/*
46.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
46.6 + *
46.7 + * This code is free software; you can redistribute it and/or modify it
46.8 + * under the terms of the GNU General Public License version 2 only, as
46.9 + * published by the Free Software Foundation.
46.10 + *
46.11 + * This code is distributed in the hope that it will be useful, but WITHOUT
46.12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
46.13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46.14 + * version 2 for more details (a copy is included in the LICENSE file that
46.15 + * accompanied this code).
46.16 + *
46.17 + * You should have received a copy of the GNU General Public License version
46.18 + * 2 along with this work; if not, write to the Free Software Foundation,
46.19 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
46.20 + *
46.21 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
46.22 + * CA 95054 USA or visit www.sun.com if you need additional information or
46.23 + * have any questions.
46.24 + */
46.25 +
46.26 +/*
46.27 + * This file is available under and governed by the GNU General Public
46.28 + * License version 2 only, as published by the Free Software Foundation.
46.29 + * However, the following notice accompanied the original version of this
46.30 + * file:
46.31 + *
46.32 + * Written by Doug Lea with assistance from members of JCP JSR-166
46.33 + * Expert Group and released to the public domain, as explained at
46.34 + * http://creativecommons.org/licenses/publicdomain
46.35 + */
46.36 +
46.37 +/*
46.38 + * @test
46.39 + * @bug 6865571
46.40 + * @summary Solve NQueens using fork/join
46.41 + * @run main NQueensCS maxBoardSize=11 reps=1
46.42 + * @run main NQueensCS maxBoardSize=11 reps=1 procs=8
46.43 + */
46.44 +
46.45 +import java.util.Arrays;
46.46 +import java.util.concurrent.ForkJoinPool;
46.47 +import java.util.concurrent.RecursiveAction;
46.48 +
46.49 +public class NQueensCS extends RecursiveAction {
46.50 +
46.51 + static long lastStealCount;
46.52 + static int boardSize;
46.53 +
46.54 + static final int[] expectedSolutions = new int[] {
46.55 + 0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200,
46.56 + 73712, 365596, 2279184, 14772512, 95815104, 666090624
46.57 + }; // see http://www.durangobill.com/N_Queens.html
46.58 +
46.59 + static String keywordValue(String[] args, String keyword) {
46.60 + for (String arg : args)
46.61 + if (arg.startsWith(keyword))
46.62 + return arg.substring(keyword.length() + 1);
46.63 + return null;
46.64 + }
46.65 +
46.66 + static int intArg(String[] args, String keyword, int defaultValue) {
46.67 + String val = keywordValue(args, keyword);
46.68 + return (val == null) ? defaultValue : Integer.parseInt(val);
46.69 + }
46.70 +
46.71 + /** for time conversion */
46.72 + static final long NPS = (1000L * 1000L * 1000L);
46.73 +
46.74 + /**
46.75 + * Usage: NQueensCS [minBoardSize=N] [maxBoardSize=N] [procs=N] [reps=N]
46.76 + */
46.77 + public static void main(String[] args) throws Exception {
46.78 + // Board sizes too small: hard to measure well.
46.79 + // Board sizes too large: take too long to run.
46.80 + final int minBoardSize = intArg(args, "minBoardSize", 8);
46.81 + final int maxBoardSize = intArg(args, "maxBoardSize", 15);
46.82 +
46.83 + final int procs = intArg(args, "procs", 0);
46.84 +
46.85 + for (int reps = intArg(args, "reps", 10); reps > 0; reps--) {
46.86 + ForkJoinPool g = (procs == 0) ?
46.87 + new ForkJoinPool() :
46.88 + new ForkJoinPool(procs);
46.89 + lastStealCount = g.getStealCount();
46.90 + for (int i = minBoardSize; i <= maxBoardSize; i++)
46.91 + test(g, i);
46.92 + System.out.println(g);
46.93 + g.shutdown();
46.94 + }
46.95 + }
46.96 +
46.97 + static void test(ForkJoinPool g, int i) throws Exception {
46.98 + boardSize = i;
46.99 + int ps = g.getParallelism();
46.100 + long start = System.nanoTime();
46.101 + NQueensCS task = new NQueensCS(new int[0]);
46.102 + g.invoke(task);
46.103 + int solutions = task.solutions;
46.104 + long time = System.nanoTime() - start;
46.105 + double secs = (double) time / NPS;
46.106 + if (solutions != expectedSolutions[i])
46.107 + throw new Error();
46.108 + System.out.printf("NQueensCS %3d", i);
46.109 + System.out.printf(" Time: %7.3f", secs);
46.110 + long sc = g.getStealCount();
46.111 + long ns = sc - lastStealCount;
46.112 + lastStealCount = sc;
46.113 + System.out.printf(" Steals/t: %5d", ns/ps);
46.114 + System.out.println();
46.115 + }
46.116 +
46.117 + // Boards are represented as arrays where each cell
46.118 + // holds the column number of the queen in that row
46.119 +
46.120 + final int[] sofar;
46.121 + NQueensCS nextSubtask; // to link subtasks
46.122 + int solutions;
46.123 + NQueensCS(int[] a) {
46.124 + this.sofar = a;
46.125 + }
46.126 +
46.127 + public final void compute() {
46.128 + NQueensCS subtasks;
46.129 + int bs = boardSize;
46.130 + if (sofar.length >= bs)
46.131 + solutions = 1;
46.132 + else if ((subtasks = explore(sofar, bs)) != null)
46.133 + solutions = processSubtasks(subtasks);
46.134 + }
46.135 +
46.136 + private static NQueensCS explore(int[] array, int bs) {
46.137 + int row = array.length;
46.138 + NQueensCS s = null; // subtask list
46.139 + outer:
46.140 + for (int q = 0; q < bs; ++q) {
46.141 + for (int i = 0; i < row; i++) {
46.142 + int p = array[i];
46.143 + if (q == p || q == p - (row - i) || q == p + (row - i))
46.144 + continue outer; // attacked
46.145 + }
46.146 + NQueensCS first = s; // lag forks to ensure 1 kept
46.147 + if (first != null)
46.148 + first.fork();
46.149 + int[] next = Arrays.copyOf(array, row+1);
46.150 + next[row] = q;
46.151 + NQueensCS subtask = new NQueensCS(next);
46.152 + subtask.nextSubtask = first;
46.153 + s = subtask;
46.154 + }
46.155 + return s;
46.156 + }
46.157 +
46.158 + private static int processSubtasks(NQueensCS s) {
46.159 + // Always run first the task held instead of forked
46.160 + s.compute();
46.161 + int ns = s.solutions;
46.162 + s = s.nextSubtask;
46.163 + // Then the unstolen ones
46.164 + while (s != null && s.tryUnfork()) {
46.165 + s.compute();
46.166 + ns += s.solutions;
46.167 + s = s.nextSubtask;
46.168 + }
46.169 + // Then wait for the stolen ones
46.170 + while (s != null) {
46.171 + s.join();
46.172 + ns += s.solutions;
46.173 + s = s.nextSubtask;
46.174 + }
46.175 + return ns;
46.176 + }
46.177 +}
47.1 --- a/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Wed Nov 04 11:19:42 2009 -0800
47.2 +++ b/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Sun Nov 08 14:49:18 2009 -0800
47.3 @@ -115,7 +115,7 @@
47.4 finally {
47.5 lock.unlock();
47.6 }
47.7 - if (completed != 2)
47.8 + if (c != 2)
47.9 throw new Error("Completed != 2");
47.10 int r = result;
47.11 if (r == 0) // avoid overoptimization
48.1 --- a/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Wed Nov 04 11:19:42 2009 -0800
48.2 +++ b/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Sun Nov 08 14:49:18 2009 -0800
48.3 @@ -30,6 +30,7 @@
48.4 * Expert Group and released to the public domain, as explained at
48.5 * http://creativecommons.org/licenses/publicdomain
48.6 */
48.7 +
48.8 import java.util.*;
48.9 import java.util.concurrent.*;
48.10 import java.util.concurrent.locks.*;