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 * @summary stress test for register/arriveAndDeregister 37 * @run main FickleRegister 300 38 */ 39 40 import java.util.ArrayList; 41 import java.util.concurrent.Phaser; 42 import java.util.concurrent.atomic.AtomicLong; 43 44 public class FickleRegister { 45 final AtomicLong count = new AtomicLong(0); 46 final long testDurationMillisDefault = 10_000L; 47 final long testDurationMillis; 48 final long quittingTimeNanos; 49 final int chunkSize = 1000; 50 51 FickleRegister(String[] args) { 52 testDurationMillis = (args.length > 0) ? 53 Long.valueOf(args[0]) : testDurationMillisDefault; 54 quittingTimeNanos = System.nanoTime() + 55 testDurationMillis * 1000L * 1000L; 56 } 57 58 class Runner extends CheckedRunnable { 59 final Phaser p; 60 Runner(Phaser phaser) { p = phaser; } 61 public void realRun() { 62 int prevPhase = -1; 63 for (int k = 1;; k++) { 64 for (int i = 0; i < chunkSize; i++) { 65 int phase = p.register(); 66 if (phase < 0) break; 67 check(phase > prevPhase); 68 prevPhase = phase; 69 equal(phase, p.arriveAndDeregister()); 70 check(phase < p.awaitAdvance(phase)); 71 } 72 if (System.nanoTime() - quittingTimeNanos > 0) { 73 count.getAndAdd(k * chunkSize); 74 break; 75 } 76 } 77 } 78 } 79 80 void test(String[] args) throws Throwable { 81 final Phaser parent = new Phaser() { 82 protected boolean onAdvance(int phase, int parties) { 83 return false; 84 } 85 }; 86 87 final Phaser child1 = new Phaser(parent); 88 final Phaser child2 = new Phaser(parent); 89 final Phaser subchild1 = new Phaser(child1); 90 final Phaser subchild2 = new Phaser(child2); 91 final Phaser[] phasers = { 92 parent, child1, child2, subchild1, subchild2 93 }; 94 95 int reps = 4; 96 ArrayList<Thread> threads = new ArrayList<>(); 97 for (int j = 0; j < reps; ++j) { 98 threads.add(new Thread(new Runner(subchild1))); 99 threads.add(new Thread(new Runner(child1))); 100 threads.add(new Thread(new Runner(parent))); 101 threads.add(new Thread(new Runner(child2))); 102 threads.add(new Thread(new Runner(subchild2))); 103 } 104 105 for (Thread thread : threads) 106 thread.start(); 107 108 for (Thread thread : threads) 109 thread.join(); 110 111 System.out.println("Parent: " + parent); 112 System.out.println("Child1: " + child1); 113 System.out.println("Child2: " + child2); 114 System.out.println("Subchild1: " + subchild1); 115 System.out.println("Subchild2: " + subchild2); 116 System.out.println("Iterations:" + count.get()); 117 118 for (Phaser phaser : phasers) { 119 check(phaser.getPhase() > 0); 120 equal(0, phaser.getRegisteredParties()); 121 equal(0, phaser.getUnarrivedParties()); 122 equal(parent.getPhase(), phaser.getPhase()); 123 } 124 } 125 126 //--------------------- Infrastructure --------------------------- 127 volatile int passed = 0, failed = 0; 128 void pass() {passed++;} 129 void fail() {failed++; Thread.dumpStack();} 130 void fail(String msg) {System.err.println(msg); fail();} 131 void unexpected(Throwable t) {failed++; t.printStackTrace();} 132 void check(boolean cond) {if (cond) pass(); else fail();} 133 void equal(Object x, Object y) { 134 if (x == null ? y == null : x.equals(y)) pass(); 135 else fail(x + " not equal to " + y);} 136 public static void main(String[] args) throws Throwable { 137 new FickleRegister(args).instanceMain(args);} 138 public void instanceMain(String[] args) throws Throwable { 139 try {test(args);} catch (Throwable t) {unexpected(t);} 140 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 141 if (failed > 0) throw new AssertionError("Some tests failed");} 142 143 abstract class CheckedRunnable implements Runnable { 144 protected abstract void realRun() throws Throwable; 145 146 public final void run() { 147 try {realRun();} catch (Throwable t) {unexpected(t);} 148 } 149 } 150 }