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 * @compile -source 1.5 TimeoutLockLoops.java 38 * @run main TimeoutLockLoops 39 * @summary Checks for responsiveness of locks to timeouts. 40 * Runs under the assumption that ITERS computations require more than 41 * TIMEOUT msecs to complete, which seems to be a safe assumption for 42 * another decade. 43 */ 44 45 import java.util.concurrent.*; 46 import java.util.concurrent.locks.*; 47 import java.util.*; 48 49 public final class TimeoutLockLoops { 50 static final ExecutorService pool = Executors.newCachedThreadPool(); 51 static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom(); 52 static boolean print = false; 53 static final int ITERS = Integer.MAX_VALUE; 54 static final long TIMEOUT = 100; 55 56 public static void main(String[] args) throws Exception { 57 int maxThreads = 100; 58 if (args.length > 0) 59 maxThreads = Integer.parseInt(args[0]); 60 61 62 print = true; 63 64 for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) { 65 System.out.print("Threads: " + i); 66 new ReentrantLockLoop(i).test(); 67 Thread.sleep(10); 68 } 69 pool.shutdown(); 70 if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) 71 throw new Error(); 72 } 73 74 static final class ReentrantLockLoop implements Runnable { 75 private int v = rng.next(); 76 private volatile boolean completed; 77 private volatile int result = 17; 78 private final ReentrantLock lock = new ReentrantLock(); 79 private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer(); 80 private final CyclicBarrier barrier; 81 private final int nthreads; 82 ReentrantLockLoop(int nthreads) { 83 this.nthreads = nthreads; 84 barrier = new CyclicBarrier(nthreads+1, timer); 85 } 86 87 final void test() throws Exception { 88 for (int i = 0; i < nthreads; ++i) { 89 lock.lock(); 90 pool.execute(this); 91 lock.unlock(); 92 } 93 barrier.await(); 94 Thread.sleep(TIMEOUT); 95 while (!lock.tryLock()); // Jam lock 96 // lock.lock(); 97 barrier.await(); 98 if (print) { 99 long time = timer.getTime(); 100 double secs = (double)(time) / 1000000000.0; 101 System.out.println("\t " + secs + "s run time"); 102 } 103 104 if (completed) 105 throw new Error("Some thread completed instead of timing out"); 106 int r = result; 107 if (r == 0) // avoid overoptimization 108 System.out.println("useless result: " + r); 109 } 110 111 public final void run() { 112 try { 113 barrier.await(); 114 int sum = v; 115 int x = 17; 116 int n = ITERS; 117 final ReentrantLock lock = this.lock; 118 for (;;) { 119 if (x != 0) { 120 if (n-- <= 0) 121 break; 122 } 123 if (!lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) 124 break; 125 try { 126 v = x = LoopHelpers.compute1(v); 127 } 128 finally { 129 lock.unlock(); 130 } 131 sum += LoopHelpers.compute2(x); 132 } 133 if (n <= 0) 134 completed = true; 135 barrier.await(); 136 result += sum; 137 } 138 catch (Exception ex) { 139 ex.printStackTrace(); 140 return; 141 } 142 } 143 } 144 145 146 }