This test case (ShortCancelledProducerConsumerLoops.java) is an abbreviated version of j2se/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java with fewer iterations. It passes OK using C2 version "20061012073853.nips.bug6480445" but hangs when using C2 version "20061012181105.jrose.dolphin-cleanups" Passes OK when run with '-client' /* * @test 1.4 06/04/21 * @bug 4486658 * @compile -source 1.5 ShortCancelledProducerConsumerLoops.java * @run main/othervm ShortCancelledProducerConsumerLoops * @summary Checks for responsiveness of blocking queues to cancellation. * Runs under the assumption that ITERS computations require more than * TIMEOUT msecs to complete. */ /* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain. Use, modify, and * redistribute this code in any way without acknowledgement. */ import java.util.concurrent.*; public class ShortCancelledProducerConsumerLoops { static final int CAPACITY = 100; static final long TIMEOUT = 100; static final ExecutorService pool = Executors.newCachedThreadPool(); static boolean print = false; public static void main(String[] args) throws Exception { int maxPairs = 8; int iters = 550000; if (args.length > 0) maxPairs = Integer.parseInt(args[0]); print = true; for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) { System.out.println("Pairs:" + i); try { oneTest(i, iters); } catch (BrokenBarrierException bb) { // OK, ignore } Thread.sleep(100); } pool.shutdown(); } static void oneRun(BlockingQueue<Integer> q, int npairs, int iters) throws Exception { LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer); Future[] prods = new Future[npairs]; Future[] cons = new Future[npairs]; for (int i = 0; i < npairs; ++i) { prods[i] = pool.submit(new Producer(q, barrier, iters)); cons[i] = pool.submit(new Consumer(q, barrier, iters)); } barrier.await(); Thread.sleep(TIMEOUT); boolean tooLate = false; for (int i = 1; i < npairs; ++i) { if (!prods[i].cancel(true)) tooLate = true; if (!cons[i].cancel(true)) tooLate = true; } Object p0 = prods[0].get(); Object c0 = cons[0].get(); if (!tooLate) { for (int i = 1; i < npairs; ++i) { if (!prods[i].isDone() || !prods[i].isCancelled()) throw new Error("Only one producer thread should complete"); if (!cons[i].isDone() || !cons[i].isCancelled()) throw new Error("Only one consumer thread should complete"); } } else System.out.print("(cancelled too late) "); long endTime = System.nanoTime(); long time = endTime - timer.startTime; if (print) { double secs = (double)(time) / 1000000000.0; System.out.println("\t " + secs + "s run time"); } } static void oneTest(int pairs, int iters) throws Exception { if (print) System.out.print("ArrayBlockingQueue "); oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters); if (print) System.out.print("LinkedBlockingQueue "); oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters); if (print) System.out.print("SynchronousQueue "); oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8); /* PriorityBlockingQueue is unbounded if (print) System.out.print("PriorityBlockingQueue "); oneRun(new PriorityBlockingQueue<Integer>(iters / 2 * pairs), pairs, iters / 4); */ } static abstract class Stage implements Callable<Integer> { final BlockingQueue<Integer> queue; final CyclicBarrier barrier; final int iters; Stage (BlockingQueue<Integer> q, CyclicBarrier b, int iters) { queue = q; barrier = b; this.iters = iters; } } static class Producer extends Stage { Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) { super(q, b, iters); } public Integer call() throws Exception { barrier.await(); int s = 0; int l = 4321; for (int i = 0; i < iters; ++i) { l = LoopHelpers.compute1(l); s += LoopHelpers.compute2(l); if (!queue.offer(new Integer(l), 1, TimeUnit.SECONDS)) break; } return new Integer(s); } } static class Consumer extends Stage { Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) { super(q, b, iters); } public Integer call() throws Exception { barrier.await(); int l = 0; int s = 0; for (int i = 0; i < iters; ++i) { Integer x = queue.poll(1, TimeUnit.SECONDS); if (x == null) break; l = LoopHelpers.compute1(x.intValue()); s += l; } return new Integer(s); } } } Runtime output is as follows: % /usr/bin/time java -server -showversion -XX:+PrintCompilation -Xbatch ShortCancelledProducerConsumerLoops java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b03) Java HotSpot(TM) Server VM (build 20061012181105.jrose.dolphin-cleanups, mixed mode) Pairs:1 ArrayBlockingQueue --- n java.lang.Thread::currentThread (static) --- n java.lang.Thread::currentThread (static) 1 b LoopHelpers::compute2 (28 bytes) 2 b java.util.concurrent.locks.ReentrantLock$Sync::nonfairTryAcquire (67 bytes) 3 b java.util.concurrent.locks.ReentrantLock$NonfairSync::tryAcquire (6 bytes) 4 b java.util.concurrent.locks.AbstractOwnableSynchronizer::setExclusiveOwnerThread (6 bytes) 5 b java.lang.Object::<init> (1 bytes) --- n java.lang.Thread::isInterrupted 6 b java.lang.Thread::interrupted (8 bytes) 7 b java.util.concurrent.locks.AbstractQueuedSynchronizer::release (33 bytes) 8 b java.util.concurrent.locks.ReentrantLock$Sync::tryRelease (45 bytes) 9 b java.util.concurrent.locks.AbstractQueuedSynchronizer::setState (6 bytes) 10 b java.util.concurrent.locks.AbstractQueuedSynchronizer$Node::predecessor (19 bytes) 11 b java.util.concurrent.locks.ReentrantLock::unlock (10 bytes) 12 b java.util.concurrent.TimeUnit$4::toNanos (11 bytes) 13 b java.util.concurrent.TimeUnit::x (27 bytes) 14 b java.util.concurrent.locks.ReentrantLock$Sync::isHeldExclusively (16 bytes) 15 b java.util.concurrent.locks.AbstractQueuedSynchronizer::acquireInterruptibly (28 bytes) 16 b LoopHelpers::compute1 (72 bytes) 17 b java.util.concurrent.ArrayBlockingQueue::inc (18 bytes) 18 b java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject::signal (33 bytes) 19 b java.util.concurrent.locks.ReentrantLock::lockInterruptibly (9 bytes) 15 made not entrant java.util.concurrent.locks.AbstractQueuedSynchronizer::acquireInterruptibly (28 bytes) --- n sun.misc.Unsafe::compareAndSwapInt --- n sun.misc.Unsafe::compareAndSwapObject 20 b java.util.concurrent.locks.AbstractQueuedSynchronizer::setHead (16 bytes) 21 b java.util.concurrent.locks.AbstractQueuedSynchronizer::compareAndSetTail (13 bytes) 22 b java.util.concurrent.locks.AbstractQueuedSynchronizer::addWaiter (50 bytes) 23 b java.util.concurrent.locks.AbstractQueuedSynchronizer$Node::<init> (15 bytes) 24 !b java.util.concurrent.ArrayBlockingQueue::poll (101 bytes) 25 !b java.util.concurrent.ArrayBlockingQueue::offer (117 bytes) 26 b java.lang.Number::<init> (5 bytes) 27 b java.lang.Integer::<init> (10 bytes) 1% b ShortCancelledProducerConsumerLoops$Producer::call @ 16 (78 bytes) 2% b ShortCancelledProducerConsumerLoops$Consumer::call @ 14 (76 bytes) --- n sun.misc.Unsafe::unpark --- n sun.misc.Unsafe::park 28 b java.util.concurrent.locks.AbstractQueuedSynchronizer::compareAndSetWaitStatus (13 bytes) --- n java.lang.System::nanoTime (static) --- n sun.misc.Unsafe::putObject 29 b java.util.concurrent.locks.LockSupport::setBlocker (12 bytes) 30 b java.util.concurrent.locks.AbstractQueuedSynchronizer::isOnSyncQueue (33 bytes) 31 b java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject::awaitNanos (160 bytes) 32 b java.util.concurrent.locks.AbstractQueuedSynchronizer::enq (69 bytes) 33 b java.util.concurrent.locks.AbstractQueuedSynchronizer::transferForSignal (45 bytes) 34 b java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject::doSignal (43 bytes) 31 made not entrant java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject::awaitNanos (160 bytes) xxxxxxx - hangs here xxxxxxxx
|