Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6500685

VM hangs after 'made not entrant java.util.concurrent.........'

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P2
    • hs10
    • 7
    • hotspot
    • b03
    • 7
    • b05
    • x86
    • solaris

    Backports

      Description

        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

        Attachments

          Issue Links

            Activity

              People

                jrose John Rose
                tbell Tim Bell
                Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: