jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceEntryImpl.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmThreadInstanceEntryImpl.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+}