1 /*
2 * Copyright (c) 2021, 2024, 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 id=default
26 * @summary Test SuspendThread/ResumeThread, SuspendThreadList/ResumeThreadList
27 * for virtual threads.
28 * @library /test/lib
29 * @compile SuspendResume1.java
30 * @run driver jdk.test.lib.FileInstaller . .
31 * @run main/othervm/native/timeout=600
32 * -Djdk.virtualThreadScheduler.maxPoolSize=1
33 * -agentlib:SuspendResume1
34 * SuspendResume1
35 */
36
37 /*
38 * @test id=no-vmcontinuations
39 * @requires vm.continuations
40 * @library /test/lib
41 * @compile SuspendResume1.java
42 * @run driver jdk.test.lib.FileInstaller . .
43 * @run main/othervm/native/timeout=600
44 * -agentlib:SuspendResume1
45 * -XX:+UnlockExperimentalVMOptions
46 * -XX:-VMContinuations
47 * SuspendResume1
48 */
49
50 import java.io.PrintStream;
51 import java.util.concurrent.*;
52 import jdk.test.lib.jvmti.DebugeeClass;
53
54 public class SuspendResume1 extends DebugeeClass {
55
56 // load native library if required
57 static {
58 System.loadLibrary("SuspendResume1");
59 }
60
61 native static void TestSuspendResume();
62 native static int GetStatus();
63
64 static public void sleep(long millis) {
65 try {
66 Thread.sleep(millis);
67 } catch (InterruptedException e) {
68 throw new RuntimeException("Interruption in TestedThread.sleep: \n\t" + e);
69 }
70 }
71
72 // run test from command line
73 public static void main(String argv[]) {
74 int status = run(argv, System.out);
75 if (status != DebugeeClass.TEST_PASSED) {
76 throw new RuntimeException("FAILED: unexpected status: " + status);
77 }
78 }
79
80 public static int run(String argv[], PrintStream out) {
81 return new SuspendResume1().runIt(argv, out);
82 }
83
84 private static final int VTHREADS_CNT = 20;
85 int status = DebugeeClass.TEST_PASSED;
86
87 // run debuggee
88 public int runIt(String argv[], PrintStream out) {
89 System.out.println("\n## Java: runIt: Starting threads");
90 status = test_vthreads();
91 if (status != DebugeeClass.TEST_PASSED) {
92 System.out.println("\n## Java: runIt FAILED: status from native Agent: " + status);
93 }
94 return status;
95 }
96
97 private int test_vthreads() {
98 TestedThread[] threads = new TestedThread[VTHREADS_CNT];
99 Thread vts[] = new Thread[VTHREADS_CNT];
100
101 for (int i = 0; i < VTHREADS_CNT; i++) {
102 String name = "TestedThread" + i;
103 TestedThread thread = new TestedThread(name);
104 threads[i] = thread;
105 vts[i] = start_thread(name, thread);
106 }
107 /*
108 status = checkStatus(status);
109 if (status != DebugeeClass.TEST_PASSED) {
110 return status;
111 }
112 */
113 System.out.println("\n## Java: runIt: testing Suspend/Resume");
114 TestSuspendResume();
115
116 System.out.println("\n## Java: runIt: Finishing vthreads");
117 try {
118 for (int i = 0; i < VTHREADS_CNT; i++) {
119 // let thread to finish
120 TestedThread thread = threads[i];
121 thread.letFinish();
122 vts[i].join();
123 }
124 } catch (InterruptedException e) {
125 throw new RuntimeException(e);
126 }
127 return GetStatus();
128 }
129
130 Thread start_thread(String name, TestedThread thread) {
131 Thread vthread = Thread.ofVirtual().name(name).start(thread);
132 thread.ensureReady(); // testing sync
133 System.out.println("## Java: started thread: " + name);
134 return vthread;
135 }
136 }
137
138 // class for tested threads
139 class TestedThread extends Thread {
140 private volatile boolean threadReady = false;
141 private volatile boolean shouldFinish = false;
142
143 // make thread with specific name
144 public TestedThread(String name) {
145 super(name);
146 }
147
148 // run thread continuously
149 public void run() {
150 // run in a loop
151 threadReady = true;
152 int i = 0;
153 int n = 1000;
154 while (!shouldFinish) {
155 if (n <= 0) {
156 n = 1000;
157 SuspendResume1.sleep(10);
158 }
159 if (i > n) {
160 i = 0;
161 n = n - 1;
162 }
163 i = i + 1;
164 }
165 }
166
167 // ensure thread is ready
168 public void ensureReady() {
169 try {
170 while (!threadReady) {
171 sleep(1000);
172 }
173 } catch (InterruptedException e) {
174 throw new RuntimeException("Interruption while preparing tested thread: \n\t" + e);
175 }
176 }
177
178 // let thread to finish
179 public void letFinish() {
180 shouldFinish = true;
181 }
182 }
--- EOF ---