blob: 70df681710c885ce1e1cff01c25edc124914b680 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2004 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package sun.management.snmp.jvminstr;
26
27// java imports
28//
29import java.io.Serializable;
30import java.lang.management.ThreadInfo;
31import java.lang.management.ManagementFactory;
32import java.lang.management.ThreadMXBean;
33
34// jmx imports
35//
36import com.sun.jmx.snmp.SnmpStatusException;
37
38// jdmk imports
39//
40import com.sun.jmx.snmp.agent.SnmpMib;
41import com.sun.jmx.snmp.SnmpOid;
42import com.sun.jmx.snmp.SnmpDefinitions;
43import com.sun.jmx.snmp.SnmpOidTable;
44import com.sun.jmx.snmp.SnmpOidRecord;
45
46import sun.management.snmp.jvmmib.JvmThreadInstanceEntryMBean;
47import sun.management.snmp.jvmmib.JVM_MANAGEMENT_MIBOidTable;
48import sun.management.snmp.util.MibLogger;
49
50/**
51 * The class is used for implementing the "JvmThreadInstanceEntry" group.
52 */
53public class JvmThreadInstanceEntryImpl
54 implements JvmThreadInstanceEntryMBean, Serializable {
55
56 public final static class ThreadStateMap {
57 public final static class Byte0 {
58 public final static byte inNative = (byte)0x80; // bit 1
59 public final static byte suspended = (byte)0x40; // bit 2
60 public final static byte newThread = (byte)0x20; // bit 3
61 public final static byte runnable = (byte)0x10; // bit 4
62 public final static byte blocked = (byte)0x08; // bit 5
63 public final static byte terminated = (byte)0x04; // bit 6
64 public final static byte waiting = (byte)0x02; // bit 7
65 public final static byte timedWaiting = (byte)0x01; // bit 8
66 }
67 public final static class Byte1 {
68 public final static byte other = (byte)0x80; // bit 9
69 public final static byte reserved10 = (byte)0x40; // bit 10
70 public final static byte reserved11 = (byte)0x20; // bit 11
71 public final static byte reserved12 = (byte)0x10; // bit 12
72 public final static byte reserved13 = (byte)0x08; // bit 13
73 public final static byte reserved14 = (byte)0x04; // bit 14
74 public final static byte reserved15 = (byte)0x02; // bit 15
75 public final static byte reserved16 = (byte)0x01; // bit 16
76 }
77
78 public final static byte mask0 = (byte)0x3F;
79 public final static byte mask1 = (byte)0x80;
80
81 private static void setBit(byte[] bitmap, int index, byte state) {
82 bitmap[index] = (byte) (bitmap[index] | state);
83 }
84 public static void setNative(byte[] bitmap) {
85 setBit(bitmap,0,Byte0.inNative);
86 }
87 public static void setSuspended(byte[] bitmap) {
88 setBit(bitmap,0,Byte0.suspended);
89 }
90 public static void setState(byte[] bitmap, Thread.State state) {
91 switch(state) {
92 case BLOCKED:
93 setBit(bitmap,0,Byte0.blocked);
94 return;
95 case NEW:
96 setBit(bitmap,0,Byte0.newThread);
97 return;
98 case RUNNABLE:
99 setBit(bitmap,0,Byte0.runnable);
100 return;
101 case TERMINATED:
102 setBit(bitmap,0,Byte0.terminated);
103 return;
104 case TIMED_WAITING:
105 setBit(bitmap,0,Byte0.timedWaiting);
106 return;
107 case WAITING:
108 setBit(bitmap,0,Byte0.waiting);
109 return;
110 }
111 }
112
113 public static void checkOther(byte[] bitmap) {
114 if (((bitmap[0]&mask0)==(byte)0x00) &&
115 ((bitmap[1]&mask1)==(byte)0x00))
116 setBit(bitmap,1,Byte1.other);
117 }
118
119 public static Byte[] getState(ThreadInfo info) {
120 byte[] bitmap = new byte[] {(byte)0x00, (byte)0x00};
121 try {
122 final Thread.State state = info.getThreadState();
123 final boolean inNative = info.isInNative();
124 final boolean suspended = info.isSuspended();
125 log.debug("getJvmThreadInstState",
126 "[State=" + state +
127 ",isInNative=" + inNative +
128 ",isSuspended=" + suspended + "]");
129 setState(bitmap,state);
130 if (inNative) setNative(bitmap);
131 if (suspended) setSuspended(bitmap);
132 checkOther(bitmap);
133 } catch (RuntimeException r) {
134 bitmap[0]=(byte)0x00;
135 bitmap[1]=Byte1.other;
136 log.trace("getJvmThreadInstState",
137 "Unexpected exception: " + r);
138 log.debug("getJvmThreadInstState",r);
139 }
140 Byte[] result = { new Byte(bitmap[0]), new Byte(bitmap[1]) };
141 return result;
142 }
143 }
144
145 private final ThreadInfo info;
146 private final Byte[] index;
147
148 /**
149 * Constructor for the "JvmThreadInstanceEntry" group.
150 */
151 public JvmThreadInstanceEntryImpl(ThreadInfo info,
152 Byte[] index) {
153 this.info = info;
154 this.index = index;
155 }
156
157
158 private static String jvmThreadInstIndexOid = null;
159 public static String getJvmThreadInstIndexOid()
160 throws SnmpStatusException {
161 if (jvmThreadInstIndexOid == null) {
162 final SnmpOidTable table = new JVM_MANAGEMENT_MIBOidTable();
163 final SnmpOidRecord record =
164 table.resolveVarName("jvmThreadInstIndex");
165 jvmThreadInstIndexOid = record.getOid();
166 }
167 return jvmThreadInstIndexOid;
168 }
169
170
171
172 /**
173 * Getter for the "JvmThreadInstLockedOwnerId" variable.
174 */
175 public String getJvmThreadInstLockOwnerPtr() throws SnmpStatusException {
176 long id = info.getLockOwnerId();
177
178 if(id == -1)
179 return new String("0.0");
180
181 SnmpOid oid = JvmThreadInstanceTableMetaImpl.makeOid(id);
182
183 return getJvmThreadInstIndexOid() + "." + oid.toString();
184 }
185
186 private String validDisplayStringTC(String str) {
187 return JVM_MANAGEMENT_MIB_IMPL.validDisplayStringTC(str);
188 }
189
190 private String validJavaObjectNameTC(String str) {
191 return JVM_MANAGEMENT_MIB_IMPL.validJavaObjectNameTC(str);
192 }
193
194 private String validPathElementTC(String str) {
195 return JVM_MANAGEMENT_MIB_IMPL.validPathElementTC(str);
196 }
197
198 /**
199 * Getter for the "JvmThreadInstLockName" variable.
200 */
201 public String getJvmThreadInstLockName() throws SnmpStatusException {
202 return validJavaObjectNameTC(info.getLockName());
203 }
204
205 /**
206 * Getter for the "JvmThreadInstName" variable.
207 */
208 public String getJvmThreadInstName() throws SnmpStatusException {
209 return validJavaObjectNameTC(info.getThreadName());
210 }
211
212 /**
213 * Getter for the "JvmThreadInstCpuTimeNs" variable.
214 */
215 public Long getJvmThreadInstCpuTimeNs() throws SnmpStatusException {
216 long l = 0;
217 final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean();
218
219 try {
220 if (tmb.isThreadCpuTimeSupported()) {
221 l = tmb.getThreadCpuTime(info.getThreadId());
222 log.debug("getJvmThreadInstCpuTimeNs", "Cpu time ns : " + l);
223
224 //Cpu time measurement is disabled or the id is not valid.
225 if(l == -1) l = 0;
226 }
227 } catch (UnsatisfiedLinkError e) {
228 // XXX Revisit: catch TO BE EVENTUALLY REMOVED
229 log.debug("getJvmThreadInstCpuTimeNs",
230 "Operation not supported: " + e);
231 }
232 return new Long(l);
233 }
234
235 /**
236 * Getter for the "JvmThreadInstBlockTimeMs" variable.
237 */
238 public Long getJvmThreadInstBlockTimeMs() throws SnmpStatusException {
239 long l = 0;
240
241 final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean();
242
243 if (tmb.isThreadContentionMonitoringSupported()) {
244 l = info.getBlockedTime();
245
246 //Monitoring is disabled
247 if(l == -1) l = 0;
248 }
249 return new Long(l);
250 }
251
252 /**
253 * Getter for the "JvmThreadInstBlockCount" variable.
254 */
255 public Long getJvmThreadInstBlockCount() throws SnmpStatusException {
256 return new Long(info.getBlockedCount());
257 }
258
259 /**
260 * Getter for the "JvmThreadInstWaitTimeMs" variable.
261 */
262 public Long getJvmThreadInstWaitTimeMs() throws SnmpStatusException {
263 long l = 0;
264
265 final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean();
266
267 if (tmb.isThreadContentionMonitoringSupported()) {
268 l = info.getWaitedTime();
269
270 //Monitoring is disabled
271 if(l == -1) l = 0;
272 }
273 return new Long(l);
274 }
275
276 /**
277 * Getter for the "JvmThreadInstWaitCount" variable.
278 */
279 public Long getJvmThreadInstWaitCount() throws SnmpStatusException {
280 return new Long(info.getWaitedCount());
281 }
282
283 /**
284 * Getter for the "JvmThreadInstState" variable.
285 */
286 public Byte[] getJvmThreadInstState()
287 throws SnmpStatusException {
288 return ThreadStateMap.getState(info);
289 }
290
291 /**
292 * Getter for the "JvmThreadInstId" variable.
293 */
294 public Long getJvmThreadInstId() throws SnmpStatusException {
295 return new Long(info.getThreadId());
296 }
297
298 /**
299 * Getter for the "JvmThreadInstIndex" variable.
300 */
301 public Byte[] getJvmThreadInstIndex() throws SnmpStatusException {
302 return index;
303 }
304
305 /**
306 * Getter for the "JvmThreadInstStackTrace" variable.
307 */
308 private String getJvmThreadInstStackTrace() throws SnmpStatusException {
309 StackTraceElement[] stackTrace = info.getStackTrace();
310 //We append the stack trace in a buffer
311 // XXX Revisit: should check isDebugOn()
312 StringBuffer b = new StringBuffer();
313 final int stackSize = stackTrace.length;
314 log.debug("getJvmThreadInstStackTrace", "Stack size : " + stackSize);
315 for(int i = 0; i < stackSize; i++) {
316 log.debug("getJvmThreadInstStackTrace", "Append " +
317 stackTrace[i].toString());
318 b.append(stackTrace[i].toString());
319 //Append \n at the end of each line except the last one
320 if(i < stackSize)
321 b.append("\n");
322 }
323 //The stack trace is truncated if its size exceeds 255.
324 return validPathElementTC(b.toString());
325 }
326 static final MibLogger log =
327 new MibLogger(JvmThreadInstanceEntryImpl.class);
328}