1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 */ 33 34 /* 35 * @test 36 * @bug 4486658 5031862 37 * @run main TimeoutLockLoops 38 * @summary Checks for responsiveness of locks to timeouts. 39 * Runs under the assumption that ITERS computations require more than 40 * TIMEOUT msecs to complete, which seems to be a safe assumption for 41 * another decade. 42 */ 43 44 import java.util.concurrent.*; 45 import java.util.concurrent.locks.*; 46 import java.util.*; 47 48 public final class TimeoutLockLoops { 49 static final ExecutorService pool = Executors.newCachedThreadPool(); 50 static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); 51 static boolean print = false; 52 static final int ITERS = Integer.MAX_VALUE; 53 static final long TIMEOUT = 100; 54 55 public static void main(String[] args) throws Exception { 56 int maxThreads = 100; 57 if (args.length > 0) 58 maxThreads = Integer.parseInt(args[0]); 59 60 61 print = true; 62 63 for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) { 64 System.out.print("Threads: " + i); 65 new ReentrantLockLoop(i).test(); 66 Thread.sleep(10); 67 } 68 pool.shutdown(); 69 if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) 70 throw new Error(); 71 } 72 73 static final class ReentrantLockLoop implements Runnable { 74 private int v = rng.next(); 75 private volatile boolean completed; 76 private volatile int result = 17; 77 private final ReentrantLock lock = new ReentrantLock(); 78 private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); 79 private final CyclicBarrier barrier; 80 private final int nthreads; 81 ReentrantLockLoop(int nthreads) { 82 this.nthreads = nthreads; 83 barrier = new CyclicBarrier(nthreads+1, timer); 84 } 85 86 final void test() throws Exception { 87 for (int i = 0; i < nthreads; ++i) { 88 lock.lock(); 89 pool.execute(this); 90 lock.unlock(); 91 } 92 barrier.await(); 93 Thread.sleep(TIMEOUT); 94 while (!lock.tryLock()); // Jam lock 95 // lock.lock(); 96 barrier.await(); 97 if (print) { 98 long time = timer.getTime(); 99 double secs = (double)(time) / 1000000000.0; 100 System.out.println("\t " + secs + "s run time"); 101 } 102 103 if (completed) 104 throw new Error("Some thread completed instead of timing out"); 105 int r = result; 106 if (r == 0) // avoid overoptimization 107 System.out.println("useless result: " + r); 108 } 109 110 public final void run() { 111 try { 112 barrier.await(); 113 int sum = v; 114 int x = 17; 115 int n = ITERS; 116 final ReentrantLock lock = this.lock; 117 for (;;) { 118 if (x != 0) { 119 if (n-- <= 0) 120 break; 121 } 122 if (!lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) 123 break; 124 try { 125 v = x = LoopHelpers.compute1(v); 126 } 127 finally { 128 lock.unlock(); 129 } 130 sum += LoopHelpers.compute2(x); 131 } 132 if (n <= 0) 133 completed = true; 134 barrier.await(); 135 result += sum; 136 } 137 catch (Exception ex) { 138 ex.printStackTrace(); 139 return; 140 } 141 } 142 } 143 144 145 }