1 /* 2 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @key stress 27 * 28 * @summary converted from VM testbase nsk/stress/thread/thread006. 29 * VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick] 30 * VM testbase readme: 31 * DESCRIPTION 32 * Try many threads of lower priority 33 * starting simultaneously. 34 * 35 * @run main/othervm nsk.stress.thread.thread006 500 2m 5s 36 */ 37 38 package nsk.stress.thread; 39 40 41 import java.io.PrintStream; 42 43 /** 44 * Try many threads of lower priority starting simultaneously. 45 */ 46 public class thread006 extends Thread { 47 /** 48 * Enable/disable printing of debugging info. 49 */ 50 private static boolean DEBUG_MODE = false; 51 52 /** 53 * The minimal number of threads that the tested JVM must support. 54 * (This number should be specified by the command-line parameter. 55 */ 56 private static int THREADS_EXPECTED = 1000; 57 58 /** 59 * Timeout (in milliseconds) after which all threads must halt. 60 */ 61 private static long TIMEOUT = 300000; // 5 minutes 62 63 /** 64 * Wait few seconds to allow child threads actually start. 65 */ 66 private static long YIELD_TIME = 5000; // 5 seconds 67 68 /** 69 * Once <code>arg</code> is ``XXXs'', or ``XXXm'', or ``XXXms'', 70 * return the given number of seconds, minutes, or milliseconds 71 * correspondingly. 72 */ 73 private static long parseTime(String arg) { 74 for (int i = arg.lastIndexOf("ms"); i > -1; ) 75 return Long.parseLong(arg.substring(0, i)); 76 for (int i = arg.lastIndexOf("s"); i > -1; ) 77 return Long.parseLong(arg.substring(0, i)) * 1000; 78 for (int i = arg.lastIndexOf("m"); i > -1; ) 79 return Long.parseLong(arg.substring(0, i)) * 60000; 80 throw new IllegalArgumentException( 81 "cannot recognize time scale: " + arg); 82 } 83 84 /** 85 * Re-invoke to <code>run(args,out)</code> in a JCK style. 86 */ 87 public static void main(String args[]) { 88 int exitCode = run(args, System.out); 89 System.exit(exitCode + 95); 90 } 91 92 /** 93 * JavaTest-like entry: <code>args[]</code> may reset 94 * <code>THREADS_EXPECTED</code>, <code>TIMEOUT</code> 95 * and <code>YIELD_TIME</code> values. 96 */ 97 public static int run(String args[], PrintStream out) { 98 if (args.length > 0) 99 THREADS_EXPECTED = Integer.parseInt(args[0]); 100 if (args.length > 1) 101 TIMEOUT = parseTime(args[1]); 102 if (args.length > 2) 103 YIELD_TIME = parseTime(args[2]); 104 if (args.length > 3) 105 DEBUG_MODE = args[3].toLowerCase().startsWith("-v"); 106 if (args.length > 4) { 107 out.println("#"); 108 out.println("# Too namy command-line arguments!"); 109 out.println("#"); 110 return 2; 111 } 112 113 if (DEBUG_MODE) { 114 out.println("Start " + THREADS_EXPECTED + " threads of lower priority,"); 115 out.println("wait " + YIELD_TIME + " milliseconds to let them go,"); 116 out.println("and halt after " + TIMEOUT + " milliseconds:"); 117 } 118 119 Thread thread[] = new Thread[THREADS_EXPECTED]; 120 for (int i = 0; i < THREADS_EXPECTED; i++) 121 try { 122 thread[i] = new thread006(); 123 thread[i].setPriority(Thread.MIN_PRIORITY); 124 if (thread[i].getPriority() == currentThread().getPriority()) { 125 out.println("*"); 126 out.println("* Sorry! -- The test cannot execute because"); 127 out.println("* it cannot create threads with lower priority"); 128 out.println("* than that executing run(args[],out) method."); 129 out.println("*"); 130 out.println("* However, since no JVM mistakes were found,"); 131 out.println("* the test finishes as PASSED."); 132 out.println("*"); 133 return 0; 134 } 135 thread[i].start(); 136 if (DEBUG_MODE) 137 out.println("Threads started: " + (i + 1)); 138 } catch (OutOfMemoryError oome) { 139 oome.printStackTrace(out); 140 out.println("#"); 141 out.println("# The test have FAILED:"); 142 out.println("# Only " + i + " threads could start,"); 143 out.println("# while at least " + THREADS_EXPECTED + 144 " were expected."); 145 out.println("#"); 146 return 2; 147 } 148 149 // Actually start: 150 GO = true; 151 // ...and let them go: 152 try { 153 doSleep(YIELD_TIME); 154 } catch (InterruptedException ie) { 155 ie.printStackTrace(out); 156 out.println("#"); 157 out.println("# OOPS! Could not let threads actually start!"); 158 out.println("#"); 159 return 2; 160 } 161 STOP = true; 162 163 if (DEBUG_MODE) 164 out.println("The test have PASSED."); 165 return 0; 166 } 167 168 private static boolean GO = false; 169 private static boolean STOP = false; 170 171 172 /** 173 * The thread activity: do nothing special, but do not 174 * free CPU time so that the thread's memory could not 175 * be moved to swap file. 176 */ 177 public void run() { 178 while (!GO && !timeout()) 179 yield(); 180 while (!STOP && !timeout()) 181 ; 182 } 183 184 private static long startTime = System.currentTimeMillis(); 185 186 /** 187 * Check if timeout for this test is exceeded. 188 */ 189 private boolean timeout() { 190 long elapsedTime = System.currentTimeMillis() - startTime; 191 return elapsedTime > TIMEOUT; 192 } 193 194 /** 195 * Yield to other threads for the given amount of 196 * <code>time</code> (milliseconds). 197 */ 198 private static void doSleep(long time) throws InterruptedException { 199 // 200 // Since Java 2, the method Thread.sleep() doesn't guarantee 201 // to yield to other threads. So, call Object.wait() to yield: 202 // 203 Object lock = new Object(); // local scope, nobody can notify it 204 synchronized (lock) { 205 lock.wait(time); 206 } 207 } 208 }