/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.management.snmp.jvminstr;

// java imports
//
import java.io.Serializable;
import java.lang.management.ThreadInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

// jmx imports
//
import com.sun.jmx.snmp.SnmpStatusException;

// jdmk imports
//
import com.sun.jmx.snmp.agent.SnmpMib;
import com.sun.jmx.snmp.SnmpOid;
import com.sun.jmx.snmp.SnmpDefinitions;
import com.sun.jmx.snmp.SnmpOidTable;
import com.sun.jmx.snmp.SnmpOidRecord;

import sun.management.snmp.jvmmib.JvmThreadInstanceEntryMBean;
import sun.management.snmp.jvmmib.JVM_MANAGEMENT_MIBOidTable;
import sun.management.snmp.util.MibLogger;

The class is used for implementing the "JvmThreadInstanceEntry" group.
/** * The class is used for implementing the "JvmThreadInstanceEntry" group. */
public class JvmThreadInstanceEntryImpl implements JvmThreadInstanceEntryMBean, Serializable { public final static class ThreadStateMap { public final static class Byte0 { public final static byte inNative = (byte)0x80; // bit 1 public final static byte suspended = (byte)0x40; // bit 2 public final static byte newThread = (byte)0x20; // bit 3 public final static byte runnable = (byte)0x10; // bit 4 public final static byte blocked = (byte)0x08; // bit 5 public final static byte terminated = (byte)0x04; // bit 6 public final static byte waiting = (byte)0x02; // bit 7 public final static byte timedWaiting = (byte)0x01; // bit 8 } public final static class Byte1 { public final static byte other = (byte)0x80; // bit 9 public final static byte reserved10 = (byte)0x40; // bit 10 public final static byte reserved11 = (byte)0x20; // bit 11 public final static byte reserved12 = (byte)0x10; // bit 12 public final static byte reserved13 = (byte)0x08; // bit 13 public final static byte reserved14 = (byte)0x04; // bit 14 public final static byte reserved15 = (byte)0x02; // bit 15 public final static byte reserved16 = (byte)0x01; // bit 16 } public final static byte mask0 = (byte)0x3F; public final static byte mask1 = (byte)0x80; private static void setBit(byte[] bitmap, int index, byte state) { bitmap[index] = (byte) (bitmap[index] | state); } public static void setNative(byte[] bitmap) { setBit(bitmap,0,Byte0.inNative); } public static void setSuspended(byte[] bitmap) { setBit(bitmap,0,Byte0.suspended); } public static void setState(byte[] bitmap, Thread.State state) { switch(state) { case BLOCKED: setBit(bitmap,0,Byte0.blocked); return; case NEW: setBit(bitmap,0,Byte0.newThread); return; case RUNNABLE: setBit(bitmap,0,Byte0.runnable); return; case TERMINATED: setBit(bitmap,0,Byte0.terminated); return; case TIMED_WAITING: setBit(bitmap,0,Byte0.timedWaiting); return; case WAITING: setBit(bitmap,0,Byte0.waiting); return; } } public static void checkOther(byte[] bitmap) { if (((bitmap[0]&mask0)==(byte)0x00) && ((bitmap[1]&mask1)==(byte)0x00)) setBit(bitmap,1,Byte1.other); } public static Byte[] getState(ThreadInfo info) { byte[] bitmap = new byte[] {(byte)0x00, (byte)0x00}; try { final Thread.State state = info.getThreadState(); final boolean inNative = info.isInNative(); final boolean suspended = info.isSuspended(); log.debug("getJvmThreadInstState", "[State=" + state + ",isInNative=" + inNative + ",isSuspended=" + suspended + "]"); setState(bitmap,state); if (inNative) setNative(bitmap); if (suspended) setSuspended(bitmap); checkOther(bitmap); } catch (RuntimeException r) { bitmap[0]=(byte)0x00; bitmap[1]=Byte1.other; log.trace("getJvmThreadInstState", "Unexpected exception: " + r); log.debug("getJvmThreadInstState",r); } Byte[] result = { new Byte(bitmap[0]), new Byte(bitmap[1]) }; return result; } } private final ThreadInfo info; private final Byte[] index;
Constructor for the "JvmThreadInstanceEntry" group.
/** * Constructor for the "JvmThreadInstanceEntry" group. */
public JvmThreadInstanceEntryImpl(ThreadInfo info, Byte[] index) { this.info = info; this.index = index; } private static String jvmThreadInstIndexOid = null; public static String getJvmThreadInstIndexOid() throws SnmpStatusException { if (jvmThreadInstIndexOid == null) { final SnmpOidTable table = new JVM_MANAGEMENT_MIBOidTable(); final SnmpOidRecord record = table.resolveVarName("jvmThreadInstIndex"); jvmThreadInstIndexOid = record.getOid(); } return jvmThreadInstIndexOid; }
Getter for the "JvmThreadInstLockedOwnerId" variable.
/** * Getter for the "JvmThreadInstLockedOwnerId" variable. */
public String getJvmThreadInstLockOwnerPtr() throws SnmpStatusException { long id = info.getLockOwnerId(); if(id == -1) return new String("0.0"); SnmpOid oid = JvmThreadInstanceTableMetaImpl.makeOid(id); return getJvmThreadInstIndexOid() + "." + oid.toString(); } private String validDisplayStringTC(String str) { return JVM_MANAGEMENT_MIB_IMPL.validDisplayStringTC(str); } private String validJavaObjectNameTC(String str) { return JVM_MANAGEMENT_MIB_IMPL.validJavaObjectNameTC(str); } private String validPathElementTC(String str) { return JVM_MANAGEMENT_MIB_IMPL.validPathElementTC(str); }
Getter for the "JvmThreadInstLockName" variable.
/** * Getter for the "JvmThreadInstLockName" variable. */
public String getJvmThreadInstLockName() throws SnmpStatusException { return validJavaObjectNameTC(info.getLockName()); }
Getter for the "JvmThreadInstName" variable.
/** * Getter for the "JvmThreadInstName" variable. */
public String getJvmThreadInstName() throws SnmpStatusException { return validJavaObjectNameTC(info.getThreadName()); }
Getter for the "JvmThreadInstCpuTimeNs" variable.
/** * Getter for the "JvmThreadInstCpuTimeNs" variable. */
public Long getJvmThreadInstCpuTimeNs() throws SnmpStatusException { long l = 0; final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean(); try { if (tmb.isThreadCpuTimeSupported()) { l = tmb.getThreadCpuTime(info.getThreadId()); log.debug("getJvmThreadInstCpuTimeNs", "Cpu time ns : " + l); //Cpu time measurement is disabled or the id is not valid. if(l == -1) l = 0; } } catch (UnsatisfiedLinkError e) { // XXX Revisit: catch TO BE EVENTUALLY REMOVED log.debug("getJvmThreadInstCpuTimeNs", "Operation not supported: " + e); } return new Long(l); }
Getter for the "JvmThreadInstBlockTimeMs" variable.
/** * Getter for the "JvmThreadInstBlockTimeMs" variable. */
public Long getJvmThreadInstBlockTimeMs() throws SnmpStatusException { long l = 0; final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean(); if (tmb.isThreadContentionMonitoringSupported()) { l = info.getBlockedTime(); //Monitoring is disabled if(l == -1) l = 0; } return new Long(l); }
Getter for the "JvmThreadInstBlockCount" variable.
/** * Getter for the "JvmThreadInstBlockCount" variable. */
public Long getJvmThreadInstBlockCount() throws SnmpStatusException { return new Long(info.getBlockedCount()); }
Getter for the "JvmThreadInstWaitTimeMs" variable.
/** * Getter for the "JvmThreadInstWaitTimeMs" variable. */
public Long getJvmThreadInstWaitTimeMs() throws SnmpStatusException { long l = 0; final ThreadMXBean tmb = JvmThreadingImpl.getThreadMXBean(); if (tmb.isThreadContentionMonitoringSupported()) { l = info.getWaitedTime(); //Monitoring is disabled if(l == -1) l = 0; } return new Long(l); }
Getter for the "JvmThreadInstWaitCount" variable.
/** * Getter for the "JvmThreadInstWaitCount" variable. */
public Long getJvmThreadInstWaitCount() throws SnmpStatusException { return new Long(info.getWaitedCount()); }
Getter for the "JvmThreadInstState" variable.
/** * Getter for the "JvmThreadInstState" variable. */
public Byte[] getJvmThreadInstState() throws SnmpStatusException { return ThreadStateMap.getState(info); }
Getter for the "JvmThreadInstId" variable.
/** * Getter for the "JvmThreadInstId" variable. */
public Long getJvmThreadInstId() throws SnmpStatusException { return new Long(info.getThreadId()); }
Getter for the "JvmThreadInstIndex" variable.
/** * Getter for the "JvmThreadInstIndex" variable. */
public Byte[] getJvmThreadInstIndex() throws SnmpStatusException { return index; }
Getter for the "JvmThreadInstStackTrace" variable.
/** * Getter for the "JvmThreadInstStackTrace" variable. */
private String getJvmThreadInstStackTrace() throws SnmpStatusException { StackTraceElement[] stackTrace = info.getStackTrace(); //We append the stack trace in a buffer // XXX Revisit: should check isDebugOn() StringBuffer b = new StringBuffer(); final int stackSize = stackTrace.length; log.debug("getJvmThreadInstStackTrace", "Stack size : " + stackSize); for(int i = 0; i < stackSize; i++) { log.debug("getJvmThreadInstStackTrace", "Append " + stackTrace[i].toString()); b.append(stackTrace[i].toString()); //Append \n at the end of each line except the last one if(i < stackSize) b.append("\n"); } //The stack trace is truncated if its size exceeds 255. return validPathElementTC(b.toString()); } static final MibLogger log = new MibLogger(JvmThreadInstanceEntryImpl.class); }