Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/serviceability/tmtools/jstack/TraveledLockTest.java
41153 views
1
/*
2
* Copyright (c) 2015, 2017, 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
* @summary Create a thread which stops in methods a(), a()->b(), a()->b()->c(),
27
* synchronizing on one monitor inside of each method.
28
* After checking that lock info is correct free the lock and
29
* invoke another method. Repeat this action.
30
* @modules java.base/jdk.internal.misc
31
* @library /test/lib
32
* @library ../share
33
* @run main/othervm -XX:+UsePerfData TraveledLockTest
34
*/
35
import common.ToolResults;
36
import java.util.Iterator;
37
import utils.*;
38
39
class TraveledLockDebuggee extends Thread {
40
41
static final String THREAD_NAME = "MyThread";
42
43
TraveledLockDebuggee() {
44
setName(THREAD_NAME);
45
}
46
47
Object monitor = new Object();
48
49
public void c() {
50
synchronized (monitor) {
51
Utils.sleep();
52
}
53
}
54
55
public void b() {
56
try {
57
synchronized (monitor) {
58
while (true) {
59
Thread.sleep(Long.MAX_VALUE);
60
}
61
}
62
} catch (InterruptedException e) {
63
c();
64
}
65
}
66
67
public void a() {
68
try {
69
synchronized (monitor) {
70
while (true) {
71
Thread.sleep(Long.MAX_VALUE);
72
}
73
}
74
} catch (InterruptedException e) {
75
b();
76
}
77
}
78
79
public void run() {
80
a();
81
}
82
83
}
84
85
public class TraveledLockTest {
86
87
public static void main(String[] args) throws Exception {
88
new TraveledLockTest().doTest();
89
}
90
91
private void doTest() throws Exception {
92
TraveledLockDebuggee debuggee = new TraveledLockDebuggee();
93
94
// Start in method a()
95
debuggee.start();
96
97
// Collect output from the jstack tool
98
JstackTool jstackTool = new JstackTool(ProcessHandle.current().pid());
99
ToolResults results1 = jstackTool.measure();
100
101
// Go to method b()
102
debuggee.interrupt();
103
104
// Collect output from the jstack tool
105
ToolResults results2 = jstackTool.measure();
106
107
// Go to method c()
108
debuggee.interrupt();
109
110
// Collect output from the jstack tool
111
ToolResults results3 = jstackTool.measure();
112
113
analyse(results1.getStdoutString(), results2.getStdoutString(), results3.getStdoutString());
114
}
115
116
// Analyzsing the outputs from the 3 jstack runs
117
public void analyse(String results1, String results2, String results3) {
118
119
String jstackStr1 = results1;
120
String jstackStr2 = results2;
121
String jstackStr3 = results3;
122
123
if (jstackStr1 == null) {
124
throw new RuntimeException("First jstack output is empty");
125
}
126
if (jstackStr2 == null) {
127
throw new RuntimeException("Second jstack output is empty");
128
}
129
if (jstackStr3 == null) {
130
throw new RuntimeException("Third jstack output is empty");
131
}
132
133
Format format = new DefaultFormat();
134
JStack jstack1 = format.parse(jstackStr1);
135
JStack jstack2 = format.parse(jstackStr2);
136
JStack jstack3 = format.parse(jstackStr3);
137
138
ThreadStack ts1 = jstack1.getThreadStack(TraveledLockDebuggee.THREAD_NAME);
139
ThreadStack ts2 = jstack2.getThreadStack(TraveledLockDebuggee.THREAD_NAME);
140
ThreadStack ts3 = jstack3.getThreadStack(TraveledLockDebuggee.THREAD_NAME);
141
142
if (ts1 == null || ts2 == null || ts3 == null) {
143
throw new RuntimeException(
144
"One of thread stack trace is null in the first jstack output : "
145
+ ts1 + ", " + ts2 + ", " + ts3);
146
}
147
148
MonitorInfo monitorInfo1 = null;
149
MonitorInfo monitorInfo2 = null;
150
MonitorInfo monitorInfo3 = null;
151
152
Iterator<MethodInfo> it = ts1.getStack().iterator();
153
while (it.hasNext()) {
154
MethodInfo mi = it.next();
155
if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".a")) {
156
monitorInfo1 = haveToHaveOneLock(mi);
157
}
158
}
159
160
it = ts2.getStack().iterator();
161
while (it.hasNext()) {
162
MethodInfo mi = it.next();
163
if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".a")) {
164
haveToBeEmpty(mi);
165
} else if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".b")) {
166
monitorInfo2 = haveToHaveOneLock(mi);
167
}
168
}
169
170
it = ts3.getStack().iterator();
171
while (it.hasNext()) {
172
MethodInfo mi = it.next();
173
if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".a")
174
|| mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".b")) {
175
haveToBeEmpty(mi);
176
} else if (mi.getName().startsWith(TraveledLockDebuggee.class.getName() + ".c")) {
177
monitorInfo3 = haveToHaveOneLock(mi);
178
}
179
}
180
181
System.out.println("All monitors found - passed");
182
}
183
184
private MonitorInfo haveToHaveOneLock(MethodInfo mi) {
185
if (mi.getLocks().size() == 1) {
186
System.out.println("Method \"" + mi.getName()
187
+ "\" contain 1 lock - correct");
188
return mi.getLocks().getFirst();
189
} else {
190
throw new RuntimeException("Lock count ("
191
+ mi.getLocks().size() + ") is incorrect in method \""
192
+ mi.getName() + "\"");
193
}
194
}
195
196
private void haveToBeEmpty(MethodInfo mi) {
197
if (mi.getLocks().size() == 0) {
198
System.out.println("Method \"" + mi.getName()
199
+ "\" does not lock anything - correct");
200
} else {
201
throw new RuntimeException(
202
"Unexpected lock found in method \"" + mi.getName() + "\"");
203
}
204
}
205
206
}
207
208