Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/management/ThreadImpl.java
38827 views
1
/*
2
* Copyright (c) 2003, 2019, 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. 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
26
package sun.management;
27
28
import java.lang.management.ManagementFactory;
29
30
import java.lang.management.ThreadInfo;
31
32
import javax.management.ObjectName;
33
import java.util.Objects;
34
35
/**
36
* Implementation class for the thread subsystem.
37
* Standard and committed hotspot-specific metrics if any.
38
*
39
* ManagementFactory.getThreadMXBean() returns an instance
40
* of this class.
41
*/
42
class ThreadImpl implements com.sun.management.ThreadMXBean {
43
44
private final VMManagement jvm;
45
46
// default for thread contention monitoring is disabled.
47
private boolean contentionMonitoringEnabled = false;
48
private boolean cpuTimeEnabled;
49
private boolean allocatedMemoryEnabled;
50
51
/**
52
* Constructor of ThreadImpl class.
53
*/
54
ThreadImpl(VMManagement vm) {
55
this.jvm = vm;
56
this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();
57
this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled();
58
}
59
60
public int getThreadCount() {
61
return jvm.getLiveThreadCount();
62
}
63
64
public int getPeakThreadCount() {
65
return jvm.getPeakThreadCount();
66
}
67
68
public long getTotalStartedThreadCount() {
69
return jvm.getTotalThreadCount();
70
}
71
72
public int getDaemonThreadCount() {
73
return jvm.getDaemonThreadCount();
74
}
75
76
public boolean isThreadContentionMonitoringSupported() {
77
return jvm.isThreadContentionMonitoringSupported();
78
}
79
80
public synchronized boolean isThreadContentionMonitoringEnabled() {
81
if (!isThreadContentionMonitoringSupported()) {
82
throw new UnsupportedOperationException(
83
"Thread contention monitoring is not supported.");
84
}
85
return contentionMonitoringEnabled;
86
}
87
88
public boolean isThreadCpuTimeSupported() {
89
return jvm.isOtherThreadCpuTimeSupported();
90
}
91
92
public boolean isCurrentThreadCpuTimeSupported() {
93
return jvm.isCurrentThreadCpuTimeSupported();
94
}
95
96
public boolean isThreadAllocatedMemorySupported() {
97
return jvm.isThreadAllocatedMemorySupported();
98
}
99
100
public boolean isThreadCpuTimeEnabled() {
101
if (!isThreadCpuTimeSupported() &&
102
!isCurrentThreadCpuTimeSupported()) {
103
throw new UnsupportedOperationException(
104
"Thread CPU time measurement is not supported");
105
}
106
return cpuTimeEnabled;
107
}
108
109
private void ensureThreadAllocatedMemorySupported() {
110
if (!isThreadAllocatedMemorySupported()) {
111
throw new UnsupportedOperationException(
112
"Thread allocated memory measurement is not supported.");
113
}
114
}
115
116
public boolean isThreadAllocatedMemoryEnabled() {
117
ensureThreadAllocatedMemorySupported();
118
return allocatedMemoryEnabled;
119
}
120
121
public long[] getAllThreadIds() {
122
Util.checkMonitorAccess();
123
124
Thread[] threads = getThreads();
125
int length = threads.length;
126
long[] ids = new long[length];
127
for (int i = 0; i < length; i++) {
128
Thread t = threads[i];
129
ids[i] = t.getId();
130
}
131
return ids;
132
}
133
134
public ThreadInfo getThreadInfo(long id) {
135
long[] ids = new long[1];
136
ids[0] = id;
137
final ThreadInfo[] infos = getThreadInfo(ids, 0);
138
return infos[0];
139
}
140
141
public ThreadInfo getThreadInfo(long id, int maxDepth) {
142
long[] ids = new long[1];
143
ids[0] = id;
144
final ThreadInfo[] infos = getThreadInfo(ids, maxDepth);
145
return infos[0];
146
}
147
148
public ThreadInfo[] getThreadInfo(long[] ids) {
149
return getThreadInfo(ids, 0);
150
}
151
152
private void verifyThreadId(long id) {
153
if (id <= 0) {
154
throw new IllegalArgumentException(
155
"Invalid thread ID parameter: " + id);
156
}
157
}
158
159
private void verifyThreadIds(long[] ids) {
160
Objects.requireNonNull(ids);
161
162
for (int i = 0; i < ids.length; i++) {
163
verifyThreadId(ids[i]);
164
}
165
}
166
167
public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
168
verifyThreadIds(ids);
169
170
if (maxDepth < 0) {
171
throw new IllegalArgumentException(
172
"Invalid maxDepth parameter: " + maxDepth);
173
}
174
175
// ids has been verified to be non-null
176
// an empty array of ids should return an empty array of ThreadInfos
177
if (ids.length == 0) return new ThreadInfo[0];
178
179
Util.checkMonitorAccess();
180
181
ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls
182
if (maxDepth == Integer.MAX_VALUE) {
183
getThreadInfo1(ids, -1, infos);
184
} else {
185
getThreadInfo1(ids, maxDepth, infos);
186
}
187
return infos;
188
}
189
190
public void setThreadContentionMonitoringEnabled(boolean enable) {
191
if (!isThreadContentionMonitoringSupported()) {
192
throw new UnsupportedOperationException(
193
"Thread contention monitoring is not supported");
194
}
195
196
Util.checkControlAccess();
197
198
synchronized (this) {
199
if (contentionMonitoringEnabled != enable) {
200
if (enable) {
201
// if reeabled, reset contention time statistics
202
// for all threads
203
resetContentionTimes0(0);
204
}
205
206
// update the VM of the state change
207
setThreadContentionMonitoringEnabled0(enable);
208
209
contentionMonitoringEnabled = enable;
210
}
211
}
212
}
213
214
private boolean verifyCurrentThreadCpuTime() {
215
// check if Thread CPU time measurement is supported.
216
if (!isCurrentThreadCpuTimeSupported()) {
217
throw new UnsupportedOperationException(
218
"Current thread CPU time measurement is not supported.");
219
}
220
return isThreadCpuTimeEnabled();
221
}
222
223
public long getCurrentThreadCpuTime() {
224
if (verifyCurrentThreadCpuTime()) {
225
return getThreadTotalCpuTime0(0);
226
}
227
return -1;
228
}
229
230
public long getThreadCpuTime(long id) {
231
long[] ids = new long[1];
232
ids[0] = id;
233
final long[] times = getThreadCpuTime(ids);
234
return times[0];
235
}
236
237
private boolean verifyThreadCpuTime(long[] ids) {
238
verifyThreadIds(ids);
239
240
// check if Thread CPU time measurement is supported.
241
if (!isThreadCpuTimeSupported() &&
242
!isCurrentThreadCpuTimeSupported()) {
243
throw new UnsupportedOperationException(
244
"Thread CPU time measurement is not supported.");
245
}
246
247
if (!isThreadCpuTimeSupported()) {
248
// support current thread only
249
for (int i = 0; i < ids.length; i++) {
250
if (ids[i] != Thread.currentThread().getId()) {
251
throw new UnsupportedOperationException(
252
"Thread CPU time measurement is only supported" +
253
" for the current thread.");
254
}
255
}
256
}
257
258
return isThreadCpuTimeEnabled();
259
}
260
261
public long[] getThreadCpuTime(long[] ids) {
262
boolean verified = verifyThreadCpuTime(ids);
263
264
int length = ids.length;
265
long[] times = new long[length];
266
java.util.Arrays.fill(times, -1);
267
268
if (verified) {
269
if (length == 1) {
270
long id = ids[0];
271
if (id == Thread.currentThread().getId()) {
272
id = 0;
273
}
274
times[0] = getThreadTotalCpuTime0(id);
275
} else {
276
getThreadTotalCpuTime1(ids, times);
277
}
278
}
279
return times;
280
}
281
282
public long getCurrentThreadUserTime() {
283
if (verifyCurrentThreadCpuTime()) {
284
return getThreadUserCpuTime0(0);
285
}
286
return -1;
287
}
288
289
public long getThreadUserTime(long id) {
290
long[] ids = new long[1];
291
ids[0] = id;
292
final long[] times = getThreadUserTime(ids);
293
return times[0];
294
}
295
296
public long[] getThreadUserTime(long[] ids) {
297
boolean verified = verifyThreadCpuTime(ids);
298
299
int length = ids.length;
300
long[] times = new long[length];
301
java.util.Arrays.fill(times, -1);
302
303
if (verified) {
304
if (length == 1) {
305
long id = ids[0];
306
if (id == Thread.currentThread().getId()) {
307
id = 0;
308
}
309
times[0] = getThreadUserCpuTime0(id);
310
} else {
311
getThreadUserCpuTime1(ids, times);
312
}
313
}
314
return times;
315
}
316
317
public void setThreadCpuTimeEnabled(boolean enable) {
318
if (!isThreadCpuTimeSupported() &&
319
!isCurrentThreadCpuTimeSupported()) {
320
throw new UnsupportedOperationException(
321
"Thread CPU time measurement is not supported");
322
}
323
324
Util.checkControlAccess();
325
synchronized (this) {
326
if (cpuTimeEnabled != enable) {
327
// notify VM of the state change
328
setThreadCpuTimeEnabled0(enable);
329
cpuTimeEnabled = enable;
330
}
331
}
332
}
333
334
public long getCurrentThreadAllocatedBytes() {
335
if (isThreadAllocatedMemoryEnabled()) {
336
return getThreadAllocatedMemory0(0);
337
}
338
return -1;
339
}
340
341
private boolean verifyThreadAllocatedMemory(long id) {
342
verifyThreadId(id);
343
return isThreadAllocatedMemoryEnabled();
344
}
345
346
public long getThreadAllocatedBytes(long id) {
347
boolean verified = verifyThreadAllocatedMemory(id);
348
349
if (verified) {
350
return getThreadAllocatedMemory0(
351
Thread.currentThread().getId() == id ? 0 : id);
352
}
353
return -1;
354
}
355
356
private boolean verifyThreadAllocatedMemory(long[] ids) {
357
verifyThreadIds(ids);
358
return isThreadAllocatedMemoryEnabled();
359
}
360
361
public long[] getThreadAllocatedBytes(long[] ids) {
362
Objects.requireNonNull(ids);
363
364
if (ids.length == 1) {
365
long size = getThreadAllocatedBytes(ids[0]);
366
return new long[] { size };
367
}
368
369
boolean verified = verifyThreadAllocatedMemory(ids);
370
371
long[] sizes = new long[ids.length];
372
java.util.Arrays.fill(sizes, -1);
373
374
if (verified) {
375
getThreadAllocatedMemory1(ids, sizes);
376
}
377
return sizes;
378
}
379
380
public void setThreadAllocatedMemoryEnabled(boolean enable) {
381
ensureThreadAllocatedMemorySupported();
382
383
Util.checkControlAccess();
384
synchronized (this) {
385
if (allocatedMemoryEnabled != enable) {
386
// notify VM of the state change
387
setThreadAllocatedMemoryEnabled0(enable);
388
allocatedMemoryEnabled = enable;
389
}
390
}
391
}
392
393
public long[] findMonitorDeadlockedThreads() {
394
Util.checkMonitorAccess();
395
396
Thread[] threads = findMonitorDeadlockedThreads0();
397
if (threads == null) {
398
return null;
399
}
400
401
long[] ids = new long[threads.length];
402
for (int i = 0; i < threads.length; i++) {
403
Thread t = threads[i];
404
ids[i] = t.getId();
405
}
406
return ids;
407
}
408
409
public long[] findDeadlockedThreads() {
410
if (!isSynchronizerUsageSupported()) {
411
throw new UnsupportedOperationException(
412
"Monitoring of Synchronizer Usage is not supported.");
413
}
414
415
Util.checkMonitorAccess();
416
417
Thread[] threads = findDeadlockedThreads0();
418
if (threads == null) {
419
return null;
420
}
421
422
long[] ids = new long[threads.length];
423
for (int i = 0; i < threads.length; i++) {
424
Thread t = threads[i];
425
ids[i] = t.getId();
426
}
427
return ids;
428
}
429
430
public void resetPeakThreadCount() {
431
Util.checkControlAccess();
432
resetPeakThreadCount0();
433
}
434
435
public boolean isObjectMonitorUsageSupported() {
436
return jvm.isObjectMonitorUsageSupported();
437
}
438
439
public boolean isSynchronizerUsageSupported() {
440
return jvm.isSynchronizerUsageSupported();
441
}
442
443
private void verifyDumpThreads(boolean lockedMonitors,
444
boolean lockedSynchronizers) {
445
if (lockedMonitors && !isObjectMonitorUsageSupported()) {
446
throw new UnsupportedOperationException(
447
"Monitoring of Object Monitor Usage is not supported.");
448
}
449
450
if (lockedSynchronizers && !isSynchronizerUsageSupported()) {
451
throw new UnsupportedOperationException(
452
"Monitoring of Synchronizer Usage is not supported.");
453
}
454
455
Util.checkMonitorAccess();
456
}
457
458
public ThreadInfo[] getThreadInfo(long[] ids,
459
boolean lockedMonitors,
460
boolean lockedSynchronizers) {
461
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers,
462
Integer.MAX_VALUE);
463
}
464
465
public ThreadInfo[] getThreadInfo(long[] ids,
466
boolean lockedMonitors,
467
boolean lockedSynchronizers,
468
int maxDepth) {
469
if (maxDepth < 0) {
470
throw new IllegalArgumentException(
471
"Invalid maxDepth parameter: " + maxDepth);
472
}
473
verifyThreadIds(ids);
474
// ids has been verified to be non-null
475
// an empty array of ids should return an empty array of ThreadInfos
476
if (ids.length == 0) return new ThreadInfo[0];
477
478
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
479
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers, maxDepth);
480
}
481
482
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
483
boolean lockedSynchronizers) {
484
return dumpAllThreads(lockedMonitors, lockedSynchronizers,
485
Integer.MAX_VALUE);
486
}
487
488
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
489
boolean lockedSynchronizers,
490
int maxDepth) {
491
if (maxDepth < 0) {
492
throw new IllegalArgumentException(
493
"Invalid maxDepth parameter: " + maxDepth);
494
}
495
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
496
return dumpThreads0(null, lockedMonitors, lockedSynchronizers, maxDepth);
497
}
498
499
// VM support where maxDepth == -1 to request entire stack dump
500
private static native Thread[] getThreads();
501
private static native void getThreadInfo1(long[] ids,
502
int maxDepth,
503
ThreadInfo[] result);
504
private static native long getThreadTotalCpuTime0(long id);
505
private static native void getThreadTotalCpuTime1(long[] ids, long[] result);
506
private static native long getThreadUserCpuTime0(long id);
507
private static native void getThreadUserCpuTime1(long[] ids, long[] result);
508
private static native long getThreadAllocatedMemory0(long id);
509
private static native void getThreadAllocatedMemory1(long[] ids, long[] result);
510
private static native void setThreadCpuTimeEnabled0(boolean enable);
511
private static native void setThreadAllocatedMemoryEnabled0(boolean enable);
512
private static native void setThreadContentionMonitoringEnabled0(boolean enable);
513
private static native Thread[] findMonitorDeadlockedThreads0();
514
private static native Thread[] findDeadlockedThreads0();
515
private static native void resetPeakThreadCount0();
516
private static native ThreadInfo[] dumpThreads0(long[] ids,
517
boolean lockedMonitors,
518
boolean lockedSynchronizers,
519
int maxDepth);
520
521
// tid == 0 to reset contention times for all threads
522
private static native void resetContentionTimes0(long tid);
523
524
public ObjectName getObjectName() {
525
return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME);
526
}
527
528
}
529
530