1 /* 2 * Copyright (c) 2003, 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 package nsk.jvmti.scenarios.sampling.SP02; 25 26 import java.io.PrintStream; 27 28 import nsk.share.*; 29 import nsk.share.jvmti.*; 30 31 public class sp02t002 extends DebugeeClass { 32 33 // load native library if required 34 static { 35 System.loadLibrary("sp02t002"); 36 } 37 38 // run test from command line main(String argv[])39 public static void main(String argv[]) { 40 argv = nsk.share.jvmti.JVMTITest.commonInit(argv); 41 42 // JCK-compatible exit 43 System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); 44 } 45 46 // run test from JCK-compatible environment run(String argv[], PrintStream out)47 public static int run(String argv[], PrintStream out) { 48 return new sp02t002().runIt(argv, out); 49 } 50 51 /* =================================================================== */ 52 53 // scaffold objects 54 static public Log log = null; 55 56 ArgumentHandler argHandler = null; 57 long timeout = 0; 58 int status = Consts.TEST_PASSED; 59 60 // monitors for threads synchronization 61 static Object endingMonitor = new Object(); 62 63 // tested threads list 64 sp02t002Thread threads[] = null; 65 66 // run debuggee runIt(String argv[], PrintStream out)67 public int runIt(String argv[], PrintStream out) { 68 argHandler = new ArgumentHandler(argv); 69 log = new Log(out, argHandler); 70 timeout = argHandler.getWaitTime() * 60 * 1000; // milliseconds 71 72 // create threads list 73 threads = new sp02t002Thread[] { 74 new sp02t002ThreadRunning("threadRunning"), 75 new sp02t002ThreadEntering("threadEntering"), 76 new sp02t002ThreadWaiting("threadWaiting"), 77 new sp02t002ThreadSleeping("threadSleeping"), 78 new sp02t002ThreadRunningInterrupted("threadRunningInterrupted"), 79 new sp02t002ThreadRunningNative("threadRunningNative") 80 }; 81 82 // run threads 83 log.display("Starting tested threads"); 84 try { 85 synchronized (endingMonitor) { 86 // start threads (except first one) 87 for (int i = 0; i < threads.length; i++) { 88 synchronized (threads[i].startingMonitor) { 89 threads[i].start(); 90 threads[i].startingMonitor.wait(); 91 } 92 if (!threads[i].checkReady()) { 93 throw new Failure("Unable to prepare thread #" + i + ": " + threads[i]); 94 } 95 } 96 97 // testing sync 98 log.display("Testing sync: threads ready"); 99 status = checkStatus(status); 100 } 101 } catch (InterruptedException e) { 102 throw new Failure(e); 103 } finally { 104 // let all threads to finish 105 for (int i = 0; i < threads.length; i++) { 106 threads[i].letFinish(); 107 } 108 } 109 110 // wait for all threads to finish 111 log.display("Finishing tested threads"); 112 try { 113 for (int i = 0; i < threads.length; i++) { 114 threads[i].join(); 115 } 116 } catch (InterruptedException e) { 117 throw new Failure(e); 118 } 119 120 return status; 121 } 122 } 123 124 /* =================================================================== */ 125 126 // basic class for tested threads 127 abstract class sp02t002Thread extends Thread { 128 public Object startingMonitor = new Object(); 129 130 // make thread with specific name sp02t002Thread(String name)131 public sp02t002Thread(String name) { 132 super(name); 133 } 134 135 // tested method testedMethod()136 public abstract void testedMethod(); 137 138 // run thread and call tested method run()139 public void run() { 140 // call tested mathod 141 sp02t002.log.display(getName() + ": run(): before call to testedMethod"); 142 testedMethod(); 143 sp02t002.log.display(getName() + ": run(): after call to testedMethod"); 144 } 145 146 // check if thread is ready for testing checkReady()147 public boolean checkReady() { 148 // return true by default 149 return true; 150 } 151 152 // let thread to finish letFinish()153 public void letFinish() { 154 // do nothing by default 155 } 156 } 157 158 /* =================================================================== */ 159 160 class sp02t002ThreadRunning extends sp02t002Thread { 161 private volatile boolean shouldFinish = false; 162 sp02t002ThreadRunning(String name)163 public sp02t002ThreadRunning(String name) { 164 super(name); 165 } 166 testedMethod()167 public void testedMethod() { 168 sp02t002.log.display(getName() + ": testedMethod()"); 169 170 // notify about starting 171 synchronized (startingMonitor) { 172 startingMonitor.notifyAll(); 173 } 174 175 // run in a loop 176 int i = 0; 177 int n = 1000; 178 while (!shouldFinish) { 179 if (n <= 0) { 180 n = 1000; 181 } 182 if (i > n) { 183 i = 0; 184 n = n - 1; 185 } 186 i = i + 1; 187 } 188 } 189 letFinish()190 public void letFinish() { 191 shouldFinish = true; 192 } 193 } 194 195 class sp02t002ThreadEntering extends sp02t002Thread { sp02t002ThreadEntering(String name)196 public sp02t002ThreadEntering(String name) { 197 super(name); 198 } 199 testedMethod()200 public void testedMethod() { 201 sp02t002.log.display(getName() + ": testedMethod()"); 202 203 // notify about starting 204 synchronized (startingMonitor) { 205 startingMonitor.notifyAll(); 206 } 207 208 // wait for endingMonitor to become released 209 synchronized (sp02t002.endingMonitor) { 210 // do nothing 211 } 212 } 213 } 214 215 class sp02t002ThreadWaiting extends sp02t002Thread { 216 private Object waitingMonitor = new Object(); 217 sp02t002ThreadWaiting(String name)218 public sp02t002ThreadWaiting(String name) { 219 super(name); 220 } 221 testedMethod()222 public void testedMethod() { 223 sp02t002.log.display(getName() + ": testedMethod()"); 224 225 synchronized (waitingMonitor) { 226 227 // notify about starting 228 synchronized (startingMonitor) { 229 startingMonitor.notifyAll(); 230 } 231 232 // wait on monitor 233 try { 234 waitingMonitor.wait(); 235 } catch (InterruptedException ignore) { 236 // just finish 237 } 238 } 239 } 240 checkReady()241 public boolean checkReady() { 242 // wait until waitingMonitor released on wait() 243 synchronized (waitingMonitor) { 244 } 245 return true; 246 } 247 letFinish()248 public void letFinish() { 249 synchronized (waitingMonitor) { 250 waitingMonitor.notifyAll(); 251 } 252 } 253 } 254 255 class sp02t002ThreadSleeping extends sp02t002Thread { sp02t002ThreadSleeping(String name)256 public sp02t002ThreadSleeping(String name) { 257 super(name); 258 } 259 testedMethod()260 public void testedMethod() { 261 sp02t002.log.display(getName() + ": testedMethod()"); 262 263 // sleep for a loooong time 264 long timeout = 7 * 24 * 60 * 60 * 1000; // one week in milliseconds 265 266 // notify about starting 267 synchronized (startingMonitor) { 268 startingMonitor.notifyAll(); 269 } 270 271 try { 272 sleep(timeout); 273 } catch (InterruptedException ignore) { 274 // just finish 275 } 276 } 277 letFinish()278 public void letFinish() { 279 interrupt(); 280 } 281 } 282 283 class sp02t002ThreadRunningInterrupted extends sp02t002Thread { 284 private Object waitingMonitor = new Object(); 285 private volatile boolean shouldFinish = false; 286 sp02t002ThreadRunningInterrupted(String name)287 public sp02t002ThreadRunningInterrupted(String name) { 288 super(name); 289 } 290 testedMethod()291 public void testedMethod() { 292 sp02t002.log.display(getName() + ": testedMethod()"); 293 294 synchronized (waitingMonitor) { 295 296 // notify about starting 297 synchronized (startingMonitor) { 298 startingMonitor.notifyAll(); 299 } 300 301 // wait on watingMonitor until interrupted 302 try { 303 waitingMonitor.wait(); 304 } catch (InterruptedException ignore) { 305 // just continue 306 } 307 } 308 309 // run in a loop 310 int i = 0; 311 int n = 1000; 312 while (!shouldFinish) { 313 if (n <= 0) { 314 n = 1000; 315 } 316 if (i > n) { 317 i = 0; 318 n = n - 1; 319 } 320 i = i + 1; 321 } 322 } 323 checkReady()324 public boolean checkReady() { 325 // interrupt thread on wait() 326 synchronized (waitingMonitor) { 327 interrupt(); 328 } 329 330 return true; 331 } 332 letFinish()333 public void letFinish() { 334 shouldFinish = true; 335 } 336 } 337 338 class sp02t002ThreadRunningNative extends sp02t002Thread { sp02t002ThreadRunningNative(String name)339 public sp02t002ThreadRunningNative(String name) { 340 super(name); 341 } 342 run()343 public void run() { 344 // notify about starting 345 synchronized (startingMonitor) { 346 startingMonitor.notifyAll(); 347 } 348 349 // call tested mathod 350 sp02t002.log.display(getName() + ": run(): before call to testedMethod"); 351 testedMethod(); 352 sp02t002.log.display(getName() + ": run(): after call to testedMethod"); 353 } 354 testedMethod()355 public native void testedMethod(); 356 checkReady()357 public native boolean checkReady(); letFinish()358 public native void letFinish(); 359 } 360