From 247c08f85dce53fa7663b1d5308a8be9fca83abf Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Wed, 25 Nov 2015 18:35:27 -0800 Subject: [PATCH] 8140468: java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java failed with java.lang.Error: Completed == 4; expected 2 8040928: java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java: java.lang.Error: Completed != 2 Reviewed-by: martin, psandoz, chegar, shade, plevart --- .../ReentrantLock/CancelledLockLoops.java | 78 ++++++++++--------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java index 48aeebd5a73..dbbc2fbb638 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java @@ -33,51 +33,45 @@ /* * @test - * @bug 4486658 - * @run main/timeout=2800 CancelledLockLoops + * @bug 4486658 8040928 8140468 * @summary tests ReentrantLock.lockInterruptibly. - * Checks for responsiveness of locks to interrupts. Runs under the - * assumption that ITERS computations require more than TIMEOUT msecs - * to complete. + * Checks for responsiveness of locks to interrupts. */ -import java.util.concurrent.*; -import java.util.concurrent.locks.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +import java.util.SplittableRandom; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.locks.ReentrantLock; public final class CancelledLockLoops { - static final Random rng = new Random(); - static boolean print = false; - static final int ITERS = 1000000; - static final long TIMEOUT = 100; + static final SplittableRandom rnd = new SplittableRandom(); public static void main(String[] args) throws Exception { - int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5; + final int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5; + final int reps = 1; // increase for stress testing - print = true; - - for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) { - System.out.print("Threads: " + i); - try { - new ReentrantLockLoop(i).test(); + for (int j = 0; j < reps; j++) { + for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) { + new Loops(i).test(); } - catch (BrokenBarrierException bb) { - // OK, ignore - } - Thread.sleep(TIMEOUT); } } - static final class ReentrantLockLoop implements Runnable { - private int v = rng.nextInt(); - private int completed; + static final class Loops implements Runnable { + private final boolean print = false; + private volatile boolean done = false; + private int v = rnd.nextInt(); + private int completed = 0; private volatile int result = 17; private final ReentrantLock lock = new ReentrantLock(); private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); private final CyclicBarrier barrier; private final int nthreads; - ReentrantLockLoop(int nthreads) { + private volatile Throwable fail = null; + Loops(int nthreads) { this.nthreads = nthreads; + if (print) System.out.print("Threads: " + nthreads); barrier = new CyclicBarrier(nthreads+1, timer); } @@ -88,15 +82,15 @@ public final class CancelledLockLoops { for (int i = 0; i < threads.length; ++i) threads[i].start(); Thread[] cancels = threads.clone(); - Collections.shuffle(Arrays.asList(cancels), rng); barrier.await(); - Thread.sleep(TIMEOUT); + Thread.sleep(rnd.nextInt(5)); for (int i = 0; i < cancels.length-2; ++i) { cancels[i].interrupt(); // make sure all OK even when cancellations spaced out if ( (i & 3) == 0) - Thread.sleep(1 + rng.nextInt(10)); + Thread.sleep(1 + rnd.nextInt(5)); } + done = true; barrier.await(); if (print) { long time = timer.getTime(); @@ -117,20 +111,25 @@ public final class CancelledLockLoops { int r = result; if (r == 0) // avoid overoptimization System.out.println("useless result: " + r); + if (fail != null) throw new RuntimeException(fail); } public final void run() { try { barrier.await(); + boolean interrupted = false; + long startTime = System.nanoTime(); int sum = v; int x = 0; - int n = ITERS; - boolean done = false; - do { + while (!done || Thread.currentThread().isInterrupted()) { try { lock.lockInterruptibly(); } catch (InterruptedException ie) { + interrupted = true; + if (print) + System.out.printf("interrupted after %d millis%n", + NANOSECONDS.toMillis(System.nanoTime() - startTime)); break; } try { @@ -140,8 +139,11 @@ public final class CancelledLockLoops { lock.unlock(); } sum += LoopHelpers.compute2(x); - } while (n-- > 0); - if (n <= 0) { + } + if (!interrupted) { + if (print) + System.out.printf("completed after %d millis%n", + NANOSECONDS.toMillis(System.nanoTime() - startTime)); lock.lock(); try { ++completed; @@ -153,9 +155,9 @@ public final class CancelledLockLoops { barrier.await(); result += sum; } - catch (Exception ex) { - ex.printStackTrace(); - return; + catch (Throwable ex) { + fail = ex; + throw new RuntimeException(ex); } } }