7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.management.internal;
26
27 import java.util.concurrent.Executor;
28 import java.util.concurrent.ForkJoinPool;
29 import javax.management.ObjectName;
30 import jdk.management.VirtualThreadSchedulerMXBean;
31 import jdk.internal.access.JavaLangAccess;
32 import jdk.internal.access.SharedSecrets;
33 import jdk.internal.vm.ContinuationSupport;
34 import sun.management.Util;
35
36 /**
37 * Provides the implementation of the management interface for the JDK's default virtual
38 * thread scheduler.
39 */
40 public class VirtualThreadSchedulerImpls {
41 private VirtualThreadSchedulerImpls() {
42 }
43
44 public static VirtualThreadSchedulerMXBean create() {
45 if (ContinuationSupport.isSupported()) {
46 return new VirtualThreadSchedulerImpl();
73
74 private void append(StringBuilder sb, String name, long value) {
75 sb.append(", ").append(name).append('=');
76 if (value >= 0) {
77 sb.append(value);
78 } else {
79 sb.append("<unavailable>");
80 }
81 }
82 }
83
84 /**
85 * Implementation of VirtualThreadSchedulerMXBean when virtual threads are
86 * implemented with continuations + scheduler.
87 */
88 private static final class VirtualThreadSchedulerImpl extends BaseVirtualThreadSchedulerImpl {
89 /**
90 * Holder class for scheduler.
91 */
92 private static class Scheduler {
93 private static final Executor scheduler =
94 SharedSecrets.getJavaLangAccess().virtualThreadDefaultScheduler();
95 static Executor instance() {
96 return scheduler;
97 }
98 }
99
100 @Override
101 public int getParallelism() {
102 if (Scheduler.instance() instanceof ForkJoinPool pool) {
103 return pool.getParallelism();
104 }
105 throw new InternalError(); // should not get here
106 }
107
108 @Override
109 public void setParallelism(int size) {
110 if (Scheduler.instance() instanceof ForkJoinPool pool) {
111 pool.setParallelism(size);
112 if (pool.getPoolSize() < size) {
113 // FJ worker thread creation is on-demand
114 Thread.startVirtualThread(() -> { });
115 }
116
117 return;
118 }
119 throw new UnsupportedOperationException(); // should not get here
120 }
121
122 @Override
123 public int getPoolSize() {
124 if (Scheduler.instance() instanceof ForkJoinPool pool) {
125 return pool.getPoolSize();
126 }
127 return -1; // should not get here
128 }
129
130 @Override
131 public int getMountedVirtualThreadCount() {
132 if (Scheduler.instance() instanceof ForkJoinPool pool) {
133 return pool.getActiveThreadCount();
134 }
135 return -1; // should not get here
136 }
137
138 @Override
139 public long getQueuedVirtualThreadCount() {
140 if (Scheduler.instance() instanceof ForkJoinPool pool) {
141 return pool.getQueuedTaskCount() + pool.getQueuedSubmissionCount();
142 }
143 return -1L; // should not get here
144 }
145 }
146
147 /**
148 * Implementation of VirtualThreadSchedulerMXBean when virtual threads are backed
149 * by platform threads.
150 */
151 private static final class BoundVirtualThreadSchedulerImpl extends BaseVirtualThreadSchedulerImpl {
152 @Override
153 public int getParallelism() {
154 return Integer.MAX_VALUE;
155 }
156
157 @Override
158 public void setParallelism(int size) {
159 throw new UnsupportedOperationException();
160 }
161
162 @Override
163 public int getPoolSize() {
|
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.sun.management.internal;
26
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.util.concurrent.Executor;
30 import java.util.concurrent.ForkJoinPool;
31 import javax.management.ObjectName;
32 import jdk.management.VirtualThreadSchedulerMXBean;
33 import jdk.internal.access.JavaLangAccess;
34 import jdk.internal.access.SharedSecrets;
35 import jdk.internal.vm.ContinuationSupport;
36 import sun.management.Util;
37
38 /**
39 * Provides the implementation of the management interface for the JDK's default virtual
40 * thread scheduler.
41 */
42 public class VirtualThreadSchedulerImpls {
43 private VirtualThreadSchedulerImpls() {
44 }
45
46 public static VirtualThreadSchedulerMXBean create() {
47 if (ContinuationSupport.isSupported()) {
48 return new VirtualThreadSchedulerImpl();
75
76 private void append(StringBuilder sb, String name, long value) {
77 sb.append(", ").append(name).append('=');
78 if (value >= 0) {
79 sb.append(value);
80 } else {
81 sb.append("<unavailable>");
82 }
83 }
84 }
85
86 /**
87 * Implementation of VirtualThreadSchedulerMXBean when virtual threads are
88 * implemented with continuations + scheduler.
89 */
90 private static final class VirtualThreadSchedulerImpl extends BaseVirtualThreadSchedulerImpl {
91 /**
92 * Holder class for scheduler.
93 */
94 private static class Scheduler {
95 private static final Executor SCHEDULER =
96 SharedSecrets.getJavaLangAccess().virtualThreadDefaultScheduler();
97 static Executor instance() {
98 return SCHEDULER;
99 }
100 }
101
102 /**
103 * Reflective access for custom schedulers.
104 */
105 private static class SchedulerMethods {
106 private final static Method GET_PARALLELISM = findMethod("getParallelism");
107 private final static Method SET_PARALLELISM = findMethod("setParallelism", int.class);
108 private final static Method GET_POOL_SIZE = findMethod("getPoolSize");
109 private final static Method GET_MOUNTED_VTHREAD_COUNT = findMethod("getMountedVirtualThreadCount");
110 private final static Method GET_QUEUED_VTHREAD_COUNT = findMethod("getQueuedVirtualThreadCount");
111
112 static Method findMethod(String method, Class<?>... params) {
113 try {
114 return Scheduler.instance().getClass().getMethod(method, params);
115 } catch (Exception e) {
116 return null;
117 }
118 }
119 }
120
121 @Override
122 public int getParallelism() {
123 Executor scheduler = Scheduler.instance();
124 if (scheduler instanceof ForkJoinPool pool) {
125 return pool.getParallelism();
126 }
127
128 // custom scheduler
129 if (SchedulerMethods.GET_PARALLELISM instanceof Method m) {
130 return (int) invokeSchedulerMethod(m);
131 }
132
133 return -1; // unknown
134 }
135
136 @Override
137 public void setParallelism(int size) {Executor scheduler = Scheduler.instance();
138 if (scheduler instanceof ForkJoinPool pool) {
139 pool.setParallelism(size);
140 if (pool.getPoolSize() < size) {
141 // FJ worker thread creation is on-demand
142 Thread.startVirtualThread(() -> { });
143 }
144 return;
145 }
146
147 // custom scheduler
148 if (SchedulerMethods.SET_PARALLELISM instanceof Method m) {
149 invokeSchedulerMethod(m, size);
150 }
151
152 throw new UnsupportedOperationException();
153 }
154
155 @Override
156 public int getPoolSize() {
157 Executor scheduler = Scheduler.instance();
158 if (scheduler instanceof ForkJoinPool pool) {
159 return pool.getPoolSize();
160 }
161
162 // custom scheduler
163 if (SchedulerMethods.GET_POOL_SIZE instanceof Method m) {
164 return (int) invokeSchedulerMethod(m);
165 }
166
167 return -1; // unknown
168 }
169
170 @Override
171 public int getMountedVirtualThreadCount() {
172 Executor scheduler = Scheduler.instance();
173 if (scheduler instanceof ForkJoinPool pool) {
174 return pool.getActiveThreadCount();
175 }
176
177 // custom scheduler
178 if (SchedulerMethods.GET_MOUNTED_VTHREAD_COUNT instanceof Method m) {
179 return (int) invokeSchedulerMethod(m);
180 }
181
182 return -1; // unknown
183 }
184
185 @Override
186 public long getQueuedVirtualThreadCount() {
187 Executor scheduler = Scheduler.instance();
188 if (scheduler instanceof ForkJoinPool pool) {
189 return pool.getQueuedTaskCount() + pool.getQueuedSubmissionCount();
190 }
191
192 // custom scheduler
193 if (SchedulerMethods.GET_QUEUED_VTHREAD_COUNT instanceof Method m) {
194 return (long) invokeSchedulerMethod(m);
195 }
196
197 return -1L; // unknown
198 }
199
200 private static Object invokeSchedulerMethod(Method m, Object... args) {
201 try {
202 return m.invoke(Scheduler.instance(), args);
203 } catch (InvocationTargetException e) {
204 throw new RuntimeException(e.getCause());
205 } catch (IllegalAccessException e) {
206 throw new RuntimeException(e);
207 }
208 }
209 }
210
211 /**
212 * Implementation of VirtualThreadSchedulerMXBean when virtual threads are backed
213 * by platform threads.
214 */
215 private static final class BoundVirtualThreadSchedulerImpl extends BaseVirtualThreadSchedulerImpl {
216 @Override
217 public int getParallelism() {
218 return Integer.MAX_VALUE;
219 }
220
221 @Override
222 public void setParallelism(int size) {
223 throw new UnsupportedOperationException();
224 }
225
226 @Override
227 public int getPoolSize() {
|