Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2176721 | 7 | John Rose | P3 | Closed | Fixed | b05 |
JDK-2171888 | 6u4 | John Rose | P3 | Resolved | Fixed | b03 |
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
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
- backported by
-
JDK-2171888 VM hangs after 'made not entrant java.util.concurrent.........'
- Resolved
-
JDK-2176721 VM hangs after 'made not entrant java.util.concurrent.........'
- Closed