Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/strace/strace006.java
41155 views
1
/*
2
* Copyright (c) 2003, 2020, 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/strace/strace006.
29
* VM testbase keywords: [stress, strace]
30
* VM testbase readme:
31
* DESCRIPTION
32
* The test checks up java.lang.Thread.getAllStackTraces() method for many
33
* threads, that recursively invoke pure java and native methods by turns
34
* in running mode ("alive" stack).
35
* The test fails if:
36
* - amount of stack trace elements is more than depth of recursion plus
37
* four elements corresponding to invocations of Thread.run(), Thread.wait(),
38
* Thread.exit(), Thread.yield() and ThreadGroup.remove() methods;
39
* - there is at least one element corresponding to invocation of unexpected
40
* method.
41
* This test is almost the same as nsk.stress.strace.strace005 except for
42
* checking is performed for java.lang.Thread.getAllStackTraces() method.
43
* COMMENTS
44
* Similar assertion is thrown (see strace005.README).
45
*
46
* @library /vmTestbase
47
* /test/lib
48
* @run main/othervm/native nsk.stress.strace.strace006
49
*/
50
51
package nsk.stress.strace;
52
53
import nsk.share.ArgumentParser;
54
import nsk.share.Failure;
55
import nsk.share.Log;
56
57
import java.io.PrintStream;
58
import java.util.Map;
59
60
/**
61
* The test check up <code>java.lang.Thread.getStackTrace()</code> method for the pure
62
* java recursion.
63
* <p>The test creates <code>THRD_COUNT</code> instances of <code>strace006Thread</code>
64
* class, tries to get their stack traces and checks up that returned array contains
65
* correct stack frames. Each stack frame must be corresponded to one of the following
66
* methods defined by the <code>expectedMethod</code> array.</p>
67
* <p>These checking are performed <code>REPEAT_COUNT</code> times.</p>
68
*/
69
public class strace006 {
70
71
static final int DEPTH = 500;
72
static final int THRD_COUNT = 100;
73
static final int REPEAT_COUNT = 10;
74
static final String[] EXPECTED_METHODS = {
75
"java.lang.System.arraycopy",
76
"java.lang.Object.wait",
77
"java.lang.Thread.exit",
78
"java.lang.Thread.yield",
79
"java.lang.ThreadGroup.remove",
80
"java.lang.ThreadGroup.threadTerminated",
81
"nsk.stress.strace.strace006Thread.run",
82
"nsk.stress.strace.strace006Thread.recursiveMethod1",
83
"nsk.stress.strace.strace006Thread.recursiveMethod2"
84
};
85
86
87
static volatile boolean isLocked = false;
88
static PrintStream out;
89
static long waitTime = 2;
90
91
static Object waitStart = new Object();
92
93
static strace006Thread[] threads;
94
static StackTraceElement[][] snapshots = new StackTraceElement[THRD_COUNT][];
95
static Log log;
96
97
volatile int achivedCount = 0;
98
99
public static void main(String[] args) {
100
out = System.out;
101
int exitCode = run(args);
102
System.exit(exitCode + 95);
103
}
104
105
public static int run(String[] args) {
106
ArgumentParser argHandler = new ArgumentParser(args);
107
log = new Log(out, argHandler);
108
waitTime = argHandler.getWaitTime() * 60000;
109
110
strace006 test = new strace006();
111
boolean res = true;
112
113
for (int j = 0; j < REPEAT_COUNT; j++) {
114
test.startThreads();
115
116
if (!test.makeSnapshot(j + 1)) res = false;
117
118
display("waiting for threads finished\n");
119
test.finishThreads();
120
}
121
122
if (!res) {
123
complain("***>>>Test failed<<<***");
124
return 2;
125
}
126
127
return 0;
128
}
129
130
void startThreads() {
131
threads = new strace006Thread[THRD_COUNT];
132
achivedCount = 0;
133
134
String tmp_name;
135
for (int i = 0; i < THRD_COUNT; i++) {
136
tmp_name = "strace006Thread" + Integer.toString(i);
137
threads[i] = new strace006Thread(this, tmp_name);
138
// threads[i].setPriority(Thread.MIN_PRIORITY);
139
}
140
141
for (int i = 0; i < THRD_COUNT; i++) {
142
threads[i].start();
143
}
144
145
waitFor("all threads started ...");
146
synchronized (waitStart) {
147
isLocked = true;
148
waitStart.notifyAll();
149
}
150
try {
151
Thread.yield();
152
Thread.sleep(1);
153
} catch (InterruptedException e) {
154
complain("" + e);
155
}
156
}
157
158
void waitFor(String msg) {
159
if (msg.length() > 0)
160
display("waiting for " + msg);
161
162
while (achivedCount < THRD_COUNT) {
163
try {
164
Thread.sleep(1);
165
} catch (InterruptedException e) {
166
complain("" + e);
167
}
168
}
169
achivedCount = 0;
170
}
171
172
boolean makeSnapshot(int repeat_number) {
173
174
// wait for native resolution completed (all threads have finished recursiveMethod2)
175
boolean isNativeResolved = false;
176
while (!isNativeResolved) {
177
try {
178
isNativeResolved = true;
179
for (int i = 0; i < threads.length; ++i)
180
if (!threads[i].isNativeResolved)
181
isNativeResolved = false;
182
Thread.sleep(20);
183
} catch (InterruptedException e) {
184
throw new Error(e);
185
}
186
}
187
188
Map traces = Thread.getAllStackTraces();
189
for (int i = 0; i < threads.length; i++) {
190
snapshots[i] = (StackTraceElement[]) traces.get(threads[i]);
191
}
192
193
return checkTraces(repeat_number);
194
}
195
196
boolean checkTraces(int repeat_number) {
197
StackTraceElement[] elements;
198
199
boolean res = true;
200
display(">>> snapshot " + repeat_number);
201
int expectedCount = DEPTH + 1;
202
203
for (int i = 0; i < threads.length; i++) {
204
elements = snapshots[i];
205
206
if (elements == null || elements.length == 0)
207
continue;
208
209
if (elements.length > 0) {
210
display("\tchecking " + threads[i].getName()
211
+ "(trace elements: " + elements.length + ")");
212
}
213
214
if (elements.length > expectedCount) {
215
complain(threads[i].getName() + ">Contains more then "
216
+ expectedCount + " elements");
217
}
218
219
for (int j = 0; j < elements.length; j++) {
220
if (!checkElement(elements[j])) {
221
complain(threads[i].getName() + ">Unexpected method name: "
222
+ elements[j].getMethodName());
223
complain("\tat " + j + " position");
224
if (elements[j].isNativeMethod()) {
225
complain("\tline number: (native method)");
226
complain("\tclass name: " + elements[j].getClassName());
227
} else {
228
complain("\tline number: " + elements[j].getLineNumber());
229
complain("\tclass name: " + elements[j].getClassName());
230
complain("\tfile name: " + elements[j].getFileName());
231
}
232
res = false;
233
}
234
}
235
}
236
return res;
237
}
238
239
boolean checkElement(StackTraceElement element) {
240
if (element.getClassName().equals("java.lang.ClassLoader"))
241
return true;
242
String name = element.getClassName() + "." + element.getMethodName();
243
for (int i = 0; i < EXPECTED_METHODS.length; i++) {
244
if (EXPECTED_METHODS[i].compareTo(name) == 0)
245
return true;
246
}
247
return false;
248
}
249
250
void finishThreads() {
251
try {
252
for (int i = 0; i < threads.length; i++) {
253
if (threads[i].isAlive())
254
threads[i].join(waitTime / THRD_COUNT);
255
}
256
} catch (InterruptedException e) {
257
complain("" + e);
258
}
259
isLocked = false;
260
}
261
262
static void display(String message) {
263
log.display(message);
264
}
265
266
static void complain(String message) {
267
log.complain(message);
268
}
269
270
}
271
272
/**
273
* The test creates many instances of <code>strace006Thread</code> class and tries
274
* to get their stack traces.
275
*/
276
class strace006Thread extends Thread {
277
278
private int currentDepth = 0;
279
public boolean isNativeResolved = false;
280
281
strace006 test;
282
283
static {
284
try {
285
System.loadLibrary("strace006");
286
} catch (UnsatisfiedLinkError e) {
287
System.err.println("Could not load strace006 library");
288
System.err.println("java.library.path:"
289
+ System.getProperty("java.library.path"));
290
throw e;
291
}
292
}
293
294
strace006Thread(strace006 test, String name) {
295
this.test = test;
296
setName(name);
297
}
298
299
public void run() {
300
301
recursiveMethod1();
302
303
}
304
305
void recursiveMethod1() {
306
307
currentDepth++;
308
309
if (currentDepth == 1) {
310
synchronized (test) {
311
test.achivedCount++;
312
}
313
314
int alltime = 0;
315
while (!strace006.isLocked) {
316
synchronized (test) {
317
try {
318
test.wait(1);
319
alltime++;
320
} catch (InterruptedException e) {
321
strace006.complain("" + e);
322
}
323
if (alltime > strace006.waitTime) {
324
throw new Failure("out of wait time");
325
}
326
}
327
}
328
} else if (currentDepth > 1 && !isNativeResolved)
329
isNativeResolved = true;
330
331
if (strace006.DEPTH - currentDepth > 0) {
332
try {
333
Thread.yield();
334
recursiveMethod2();
335
} catch (StackOverflowError e) {
336
// ignore this exception
337
}
338
}
339
340
currentDepth--;
341
}
342
343
native void recursiveMethod2();
344
}
345
346