Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/SuspendWithCurrentThread/SuspendWithCurrentThread.java
41155 views
1
/*
2
* Copyright (c) 2019, 2021, 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
* @bug 8231595
27
* @summary [TEST] develop a test case for SuspendThreadList including current thread
28
* @requires vm.jvmti
29
* @library /test/lib
30
* @compile SuspendWithCurrentThread.java
31
* @run main/othervm/native -agentlib:SuspendWithCurrentThread SuspendWithCurrentThread SuspenderIndex=first
32
* @run main/othervm/native -agentlib:SuspendWithCurrentThread SuspendWithCurrentThread SuspenderIndex=last
33
*/
34
35
import java.io.PrintStream;
36
37
public class SuspendWithCurrentThread {
38
private static final String AGENT_LIB = "SuspendWithCurrentThread";
39
private static final String SUSPENDER_OPT = "SuspenderIndex=";
40
private static final int THREADS_COUNT = 10;
41
42
private static void log(String msg) { System.out.println(msg); }
43
44
private static native void registerTestedThreads(Thread[] threads);
45
private static native boolean checkTestedThreadsSuspended();
46
private static native void resumeTestedThreads();
47
private static native void releaseTestedThreadsInfo();
48
49
// The suspender thread index defines the thread which has to suspend
50
// the tested threads including itself with the JVMTI SuspendThreadList
51
private static int suspenderIndex;
52
53
public static void main(String args[]) throws Exception {
54
try {
55
System.loadLibrary(AGENT_LIB);
56
log("Loaded library: " + AGENT_LIB);
57
} catch (UnsatisfiedLinkError ule) {
58
log("Failed to load library: " + AGENT_LIB);
59
log("java.library.path: " + System.getProperty("java.library.path"));
60
throw ule;
61
}
62
if (args.length != 1) {
63
throw new RuntimeException("Main: wrong arguments count: " + args.length + ", expected: 1");
64
}
65
String arg = args[0];
66
if (arg.equals(SUSPENDER_OPT + "first")) {
67
suspenderIndex = 0;
68
} else if (arg.equals(SUSPENDER_OPT + "last")) {
69
suspenderIndex = THREADS_COUNT - 1;
70
} else {
71
throw new RuntimeException("Main: wrong argument: " + arg + ", expected: SuspenderIndex={first|last}");
72
}
73
log("Main: suspenderIndex: " + suspenderIndex);
74
75
SuspendWithCurrentThread test = new SuspendWithCurrentThread();
76
test.run();
77
}
78
79
private ThreadToSuspend[] startTestedThreads(int threadsCount) throws RuntimeException {
80
ThreadToSuspend[]threads = new ThreadToSuspend[threadsCount];
81
82
// create tested threads
83
for (int i = 0; i < threads.length; i++) {
84
threads[i] = new ThreadToSuspend("ThreadToSuspend#" + i,
85
i == suspenderIndex // isSuspender
86
);
87
}
88
log("Main: starting tested threads");
89
for (int i = 0; i < threads.length; i++) {
90
threads[i].start();
91
if (!threads[i].checkReady()) {
92
throw new RuntimeException("Main: unable to prepare tested thread: " + threads[i]);
93
}
94
}
95
log("Main: tested threads started");
96
97
registerTestedThreads(threads);
98
return threads;
99
}
100
101
private boolean checkSuspendedStatus() throws RuntimeException {
102
log("Main: checking all tested threads have been suspended");
103
return checkTestedThreadsSuspended();
104
}
105
106
/* The test does the following steps:
107
* - main thread starts several (THREADS_COUNT) ThreadToSuspend tested threads
108
* - main thread waits for threads to be ready with the thread.checkReady()
109
* - main thread registers tested threads within the native agent library
110
* with the native method registerTestedThreads()
111
* - main thread triggers the suspender tested thread with the
112
* ThreadToSuspend.setAllThreadsReady() to suspend tested threads
113
* - suspender thread suspends tested threads including itself with the native
114
* method suspendTestedThreads() (uses the JVMTI SuspendThreadList function)
115
* - main thread checks tested threads suspended status with the native method
116
* checkSuspendedStatus(); the tested threads are expected to have suspended status
117
* - main thread resumes tested threads with the native method resumeTestedThreads()
118
* - main thread releases tested threads with the native method releaseTestedThreads()
119
* - main thread triggers the tested threads to finish with the thread.letFinish()
120
*/
121
private void run() throws Exception {
122
ThreadToSuspend[] threads = null; // tested threads
123
124
log("Main: started");
125
try {
126
threads = startTestedThreads(THREADS_COUNT);
127
128
log("Main: trigger " + threads[suspenderIndex].getName() +
129
" to suspend all tested threads including itself");
130
ThreadToSuspend.setAllThreadsReady();
131
132
while (!checkSuspendedStatus()) {
133
Thread.sleep(10);
134
}
135
136
log("Main: resuming all tested threads");
137
resumeTestedThreads();
138
} finally {
139
// let threads to finish
140
for (int i = 0; i < threads.length; i++) {
141
threads[i].letFinish();
142
}
143
log("Main: tested threads finished");
144
}
145
146
// wait for threads to finish
147
log("Main: joining tested threads");
148
try {
149
for (int i = 0; i < threads.length; i++) {
150
threads[i].join();
151
}
152
log("Main: tested thread joined");
153
} catch (InterruptedException e) {
154
throw new RuntimeException(e);
155
}
156
log("Main: releasing tested threads native info");
157
releaseTestedThreadsInfo();
158
159
log("Main: finished");
160
}
161
}
162
163
/* =================================================================== */
164
165
// tested threads
166
class ThreadToSuspend extends Thread {
167
private static void log(String msg) { System.out.println(msg); }
168
169
private static native void suspendTestedThreads();
170
private static volatile boolean allThreadsReady = false;
171
172
public static void setAllThreadsReady() {
173
allThreadsReady = true;
174
}
175
176
private volatile boolean threadReady = false;
177
private volatile boolean shouldFinish = false;
178
private boolean isSuspender = false;
179
180
// make thread with specific name
181
public ThreadToSuspend(String name, boolean isSuspender) {
182
super(name);
183
this.isSuspender = isSuspender;
184
}
185
186
// run thread continuously
187
public void run() {
188
boolean needSuspend = true;
189
threadReady = true;
190
191
// run in a loop
192
while (!shouldFinish) {
193
if (isSuspender && needSuspend && allThreadsReady) {
194
log(getName() + ": before suspending all tested threads including myself");
195
needSuspend = false;
196
suspendTestedThreads();
197
log(getName() + ": after suspending all tested threads including myself");
198
}
199
}
200
}
201
202
// check if thread is ready
203
public boolean checkReady() {
204
try {
205
while (!threadReady) {
206
sleep(1);
207
}
208
} catch (InterruptedException e) {
209
throw new RuntimeException("checkReady: sleep was interrupted\n\t" + e);
210
}
211
return threadReady;
212
}
213
214
// let thread to finish
215
public void letFinish() {
216
shouldFinish = true;
217
}
218
}
219
220