328 lines · 11.4 KB · Java
RawDownload
/* * 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. */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.     */    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.     */    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.     */    public String getJvmThreadInstLockName() throws SnmpStatusException {        return validJavaObjectNameTC(info.getLockName());    }     /**     * Getter for the "JvmThreadInstName" variable.     */    public String getJvmThreadInstName() throws SnmpStatusException {        return validJavaObjectNameTC(info.getThreadName());    }     /**     * 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.     */    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.     */    public Long getJvmThreadInstBlockCount() throws SnmpStatusException {        return new Long(info.getBlockedCount());    }     /**     * 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.     */    public Long getJvmThreadInstWaitCount() throws SnmpStatusException {        return new Long(info.getWaitedCount());    }     /**     * Getter for the "JvmThreadInstState" variable.     */    public Byte[] getJvmThreadInstState()        throws SnmpStatusException {        return ThreadStateMap.getState(info);    }     /**     * Getter for the "JvmThreadInstId" variable.     */    public Long getJvmThreadInstId() throws SnmpStatusException {        return new Long(info.getThreadId());    }     /**     * Getter for the "JvmThreadInstIndex" variable.     */    public Byte[] getJvmThreadInstIndex() throws SnmpStatusException {        return index;    }     /**     * 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);}