1 /*
2  * Copyright (c) 2004, 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.GetThreadState;
25 
26 import nsk.share.Wicket;
27 import java.io.PrintStream;
28 
29 public class thrstat002 {
30 
31     public static final int STATUS_RUNNING = 0;
32     public static final int STATUS_MONITOR = 1;
33     public static final int STATUS_WAIT    = 2;
34 
init(int waitTime)35     native static void init(int waitTime);
checkStatus(int statInd, boolean susp)36     native static void checkStatus(int statInd, boolean susp);
getRes()37     native static int getRes();
38 
main(String[] args)39     public static void main(String[] args) {
40         args = nsk.share.jvmti.JVMTITest.commonInit(args);
41 
42         System.exit(run(args, System.out) + 95/*STATUS_TEMP*/);
43     }
44 
run(String args[], PrintStream out)45     public static int run(String args[], PrintStream out) {
46         int waitTime = 2;
47         if (args.length > 0) {
48             try {
49                 int i  = Integer.parseInt(args[0]);
50                 waitTime = i;
51             } catch (NumberFormatException ex) {
52                 out.println("# Wrong argument \"" + args[0]
53                     + "\", the default value is used");
54             }
55         }
56         out.println("# Waiting time = " + waitTime + " mins");
57         init(waitTime);
58         new thrstat002().meth();
59         return getRes();
60     }
61 
62     public static Wicket startingBarrier;
63     public static Wicket runningBarrier;
64     public static Object blockingMonitor = new Object();
65     public static Lock endingMonitor = new Lock();
66 
67     static volatile boolean targetAboutToLock = false;
68 
meth()69     void meth() {
70         thrstat002a thr = new thrstat002a("thr1");
71         startingBarrier = new Wicket();
72         runningBarrier = new Wicket();
73 
74         synchronized (blockingMonitor) {
75             thr.start();
76             System.out.println("thrstat002.meth after thr.start()");
77 
78             startingBarrier.waitFor();
79             System.out.println("thrstat002.meth after thr.startingBarrier.waitFor()");
80 
81             waitForThreadBlocked(thr);
82 
83             checkStatus(STATUS_MONITOR, false);
84             System.out.println("thrstat002.meth after checkStatus(STATUS_MONITOR,false)");
85 
86             thr.suspend();
87             System.out.println("thrstat002.meth after thr.suspend()");
88             checkStatus(STATUS_MONITOR, true);
89             System.out.println("thrstat002.meth after checkStatus(STATUS_MONITOR,true)");
90 
91             thr.resume();
92             System.out.println("thrstat002.meth after thr.resume()");
93             checkStatus(STATUS_MONITOR, false);
94             System.out.println("thrstat002.meth after checkStatus(STATUS_MONITOR,false)");
95         }
96 
97         runningBarrier.waitFor();
98         checkStatus(STATUS_RUNNING, false);
99         thr.suspend();
100         checkStatus(STATUS_RUNNING, true);
101         thr.resume();
102         checkStatus(STATUS_RUNNING, false);
103         thr.letItGo();
104 
105         synchronized (endingMonitor) {
106             checkStatus(STATUS_WAIT, false);
107             thr.suspend();
108             checkStatus(STATUS_WAIT, true);
109             thr.resume();
110             checkStatus(STATUS_WAIT, false);
111             endingMonitor.val++;
112             endingMonitor.notifyAll();
113         }
114 
115         try {
116             thr.join();
117         } catch (InterruptedException e) {
118             throw new Error("Unexpected: " + e);
119         }
120     }
121 
waitForThreadBlocked(Thread t)122     private static void waitForThreadBlocked(Thread t) {
123         // Ensure that the thread is blocked on the right monitor
124         while (!targetAboutToLock || t.getState() != Thread.State.BLOCKED) {
125             try {
126                 Thread.sleep(100);
127             } catch (InterruptedException ex) {
128                 System.out.println("thrstat002.waitForThreadBlocked was interrupted: " + ex.getMessage());
129             }
130         }
131     }
132 
133     static class Lock {
134         public int val = 0;
135     }
136 }
137 
138 class thrstat002a extends Thread {
139     private volatile boolean flag = true;
140 
thrstat002a(String name)141     public thrstat002a(String name) {
142         super(name);
143     }
144 
run()145     public void run() {
146         synchronized (thrstat002.endingMonitor) {
147             System.out.println("thrstat002a.run before startingBarrier.unlock");
148             thrstat002.startingBarrier.unlock();
149 
150             System.out.println("thrstat002a.run after  startingBarrier.unlock");
151 
152             System.out.println("thrstat002a.run before blockingMonitor lock");
153 
154             thrstat002.targetAboutToLock = true;
155 
156             synchronized (thrstat002.blockingMonitor) {
157                System.out.println("thrstat002a.run blockingMonitor locked");
158             }
159             System.out.println("thrstat002a.run after blockingMonitor lock");
160 
161             thrstat002.runningBarrier.unlock();
162             System.out.println("thrstat002a.run after runningBarrier unlock");
163             int i = 0;
164             int n = 1000;
165             while (flag) {
166                 if (n <= 0) {
167                     n = 1000;
168                 }
169                 if (i > n) {
170                     i = 0;
171                     n--;
172                 }
173                 i++;
174             }
175 
176             thrstat002.endingMonitor.val = 0;
177             while (thrstat002.endingMonitor.val == 0) {
178                 try {
179                     thrstat002.endingMonitor.wait();
180                 } catch (InterruptedException e) {
181                     throw new Error("Unexpected: " + e);
182                 }
183             }
184             System.out.println("thrstat002a.run before endingMonitor unlock");
185        }
186     }
187 
letItGo()188     public void letItGo() {
189         flag = false;
190     }
191 }
192