1 /*
   2  * Copyright (c) 2003, 2004, 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 package sun.management.snmp.jvminstr;
  26 
  27 // java imports
  28 //
  29 import java.io.Serializable;
  30 
  31 import java.lang.management.ThreadMXBean;
  32 import java.lang.management.ManagementFactory;
  33 
  34 // jmx imports
  35 //
  36 import javax.management.MBeanServer;
  37 import com.sun.jmx.snmp.SnmpString;
  38 import com.sun.jmx.snmp.SnmpStatusException;
  39 
  40 // jdmk imports
  41 //
  42 import com.sun.jmx.snmp.agent.SnmpMib;
  43 import com.sun.jmx.snmp.SnmpDefinitions;
  44 
  45 import sun.management.snmp.jvmmib.JvmThreadingMBean;
  46 import sun.management.snmp.jvmmib.EnumJvmThreadCpuTimeMonitoring;
  47 import sun.management.snmp.jvmmib.EnumJvmThreadContentionMonitoring;
  48 import sun.management.snmp.util.MibLogger;
  49 
  50 /**
  51  * The class is used for implementing the "JvmThreading" group.
  52  */
  53 public class JvmThreadingImpl implements JvmThreadingMBean {
  54 
  55     /**
  56      * Variable for storing the value of "JvmThreadCpuTimeMonitoring".
  57      *
  58      * "The state of the Thread CPU Time Monitoring feature.
  59      * This feature can be:
  60      *
  61      * unsupported: The JVM does not support Thread CPU Time Monitoring.
  62      * enabled    : The JVM supports Thread CPU Time Monitoring, and it
  63      * is enabled.
  64      * disabled   : The JVM supports Thread CPU Time Monitoring, and it
  65      * is disabled.
  66      *
  67      * Only enabled(3) and disabled(4) may be supplied as values to a
  68      * SET request. unsupported(1) can only be set internally by the
  69      * agent.
  70      *
  71      * See java.lang.management.ThreadMXBean.isThreadCpuTimeSupported(),
  72      * java.lang.management.ThreadMXBean.isThreadCpuTimeEnabled(),
  73      * java.lang.management.ThreadMXBean.setThreadCpuTimeEnabled()
  74      * "
  75      *
  76      */
  77     final static EnumJvmThreadCpuTimeMonitoring
  78         JvmThreadCpuTimeMonitoringUnsupported =
  79         new EnumJvmThreadCpuTimeMonitoring("unsupported");
  80     final static EnumJvmThreadCpuTimeMonitoring
  81         JvmThreadCpuTimeMonitoringEnabled =
  82         new EnumJvmThreadCpuTimeMonitoring("enabled");
  83     final static EnumJvmThreadCpuTimeMonitoring
  84         JvmThreadCpuTimeMonitoringDisabled =
  85         new EnumJvmThreadCpuTimeMonitoring("disabled");
  86 
  87 
  88     /**
  89      * Variable for storing the value of "JvmThreadContentionMonitoring".
  90      *
  91      * "The state of the Thread Contention Monitoring feature.
  92      * This feature can be:
  93      *
  94      * unsupported: The JVM does not support Thread Contention Monitoring.
  95      * enabled    : The JVM supports Thread Contention Monitoring, and it
  96      * is enabled.
  97      * disabled   : The JVM supports Thread Contention Monitoring, and it
  98      * is disabled.
  99      *
 100      * Only enabled(3) and disabled(4) may be supplied as values to a
 101      * SET request. unsupported(1) can only be set internally by the
 102      * agent.
 103      *
 104      * See java.lang.management.ThreadMXBean.isThreadContentionMonitoringSupported(),
 105      * java.lang.management.ThreadMXBean.isThreadContentionMonitoringEnabled(),
 106      * java.lang.management.ThreadMXBean.setThreadContentionMonitoringEnabled()
 107      * "
 108      *
 109      */
 110     static final EnumJvmThreadContentionMonitoring
 111         JvmThreadContentionMonitoringUnsupported =
 112         new EnumJvmThreadContentionMonitoring("unsupported");
 113     static final EnumJvmThreadContentionMonitoring
 114         JvmThreadContentionMonitoringEnabled =
 115         new EnumJvmThreadContentionMonitoring("enabled");
 116     static final EnumJvmThreadContentionMonitoring
 117         JvmThreadContentionMonitoringDisabled =
 118         new EnumJvmThreadContentionMonitoring("disabled");
 119 
 120     /**
 121      * Constructor for the "JvmThreading" group.
 122      * If the group contains a table, the entries created through an SNMP SET
 123      * will not be registered in Java DMK.
 124      */
 125     public JvmThreadingImpl(SnmpMib myMib) {
 126         log.debug("JvmThreadingImpl","Constructor");
 127     }
 128 
 129 
 130     /**
 131      * Constructor for the "JvmThreading" group.
 132      * If the group contains a table, the entries created through an SNMP SET
 133      * will be AUTOMATICALLY REGISTERED in Java DMK.
 134      */
 135     public JvmThreadingImpl(SnmpMib myMib, MBeanServer server) {
 136         log.debug("JvmThreadingImpl","Constructor with server");
 137     }
 138 
 139     /**
 140      * ThreadMXBean accessor. It is acquired from the
 141      * java.lang.management.ManagementFactory
 142      * @return The local ThreadMXBean.
 143      */
 144     static ThreadMXBean getThreadMXBean() {
 145         return ManagementFactory.getThreadMXBean();
 146     }
 147 
 148     /**
 149      * Getter for the "JvmThreadCpuTimeMonitoring" variable.
 150      */
 151     public EnumJvmThreadCpuTimeMonitoring getJvmThreadCpuTimeMonitoring()
 152         throws SnmpStatusException {
 153 
 154         ThreadMXBean mbean = getThreadMXBean();
 155 
 156         if(!mbean.isThreadCpuTimeSupported()) {
 157             log.debug("getJvmThreadCpuTimeMonitoring",
 158                       "Unsupported ThreadCpuTimeMonitoring");
 159             return JvmThreadCpuTimeMonitoringUnsupported;
 160         }
 161 
 162         try {
 163             if(mbean.isThreadCpuTimeEnabled()) {
 164                 log.debug("getJvmThreadCpuTimeMonitoring",
 165                       "Enabled ThreadCpuTimeMonitoring");
 166                 return JvmThreadCpuTimeMonitoringEnabled;
 167             } else {
 168                 log.debug("getJvmThreadCpuTimeMonitoring",
 169                           "Disabled ThreadCpuTimeMonitoring");
 170                 return JvmThreadCpuTimeMonitoringDisabled;
 171             }
 172         }catch(UnsupportedOperationException e) {
 173             log.debug("getJvmThreadCpuTimeMonitoring",
 174                       "Newly unsupported ThreadCpuTimeMonitoring");
 175 
 176             return JvmThreadCpuTimeMonitoringUnsupported;
 177         }
 178     }
 179 
 180     /**
 181      * Setter for the "JvmThreadCpuTimeMonitoring" variable.
 182      */
 183     public void setJvmThreadCpuTimeMonitoring(EnumJvmThreadCpuTimeMonitoring x)
 184         throws SnmpStatusException {
 185 
 186         ThreadMXBean mbean = getThreadMXBean();
 187 
 188         // We can trust the received value, it has been checked in
 189         // checkJvmThreadCpuTimeMonitoring
 190         if(JvmThreadCpuTimeMonitoringEnabled.intValue() == x.intValue())
 191             mbean.setThreadCpuTimeEnabled(true);
 192         else
 193             mbean.setThreadCpuTimeEnabled(false);
 194     }
 195 
 196     /**
 197      * Checker for the "JvmThreadCpuTimeMonitoring" variable.
 198      */
 199     public void checkJvmThreadCpuTimeMonitoring(EnumJvmThreadCpuTimeMonitoring
 200                                                 x)
 201         throws SnmpStatusException {
 202 
 203         //Can't be set externaly to unsupported state.
 204         if(JvmThreadCpuTimeMonitoringUnsupported.intValue() == x.intValue()) {
 205              log.debug("checkJvmThreadCpuTimeMonitoring",
 206                       "Try to set to illegal unsupported value");
 207             throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 208         }
 209 
 210         if ((JvmThreadCpuTimeMonitoringEnabled.intValue() == x.intValue()) ||
 211             (JvmThreadCpuTimeMonitoringDisabled.intValue() == x.intValue())) {
 212 
 213             // The value is a valid value. But is the feature supported?
 214             ThreadMXBean mbean = getThreadMXBean();
 215             if(mbean.isThreadCpuTimeSupported()) return;
 216 
 217             // Not supported.
 218             log.debug("checkJvmThreadCpuTimeMonitoring",
 219                       "Unsupported operation, can't set state");
 220             throw new
 221                 SnmpStatusException(SnmpDefinitions.snmpRspInconsistentValue);
 222         }
 223 
 224         // Unknown value.
 225         log.debug("checkJvmThreadCpuTimeMonitoring",
 226                   "unknown enum value ");
 227         throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 228     }
 229 
 230     /**
 231      * Getter for the "JvmThreadContentionMonitoring" variable.
 232      */
 233     public EnumJvmThreadContentionMonitoring getJvmThreadContentionMonitoring()
 234         throws SnmpStatusException {
 235 
 236         ThreadMXBean mbean = getThreadMXBean();
 237 
 238         if(!mbean.isThreadContentionMonitoringSupported()) {
 239             log.debug("getJvmThreadContentionMonitoring",
 240                       "Unsupported ThreadContentionMonitoring");
 241             return JvmThreadContentionMonitoringUnsupported;
 242         }
 243 
 244         if(mbean.isThreadContentionMonitoringEnabled()) {
 245             log.debug("getJvmThreadContentionMonitoring",
 246                       "Enabled ThreadContentionMonitoring");
 247             return JvmThreadContentionMonitoringEnabled;
 248         } else {
 249             log.debug("getJvmThreadContentionMonitoring",
 250                       "Disabled ThreadContentionMonitoring");
 251             return JvmThreadContentionMonitoringDisabled;
 252         }
 253     }
 254 
 255     /**
 256      * Setter for the "JvmThreadContentionMonitoring" variable.
 257      */
 258     public void setJvmThreadContentionMonitoring(
 259                             EnumJvmThreadContentionMonitoring x)
 260         throws SnmpStatusException {
 261         ThreadMXBean mbean = getThreadMXBean();
 262 
 263         // We can trust the received value, it has been checked in
 264         // checkJvmThreadContentionMonitoring
 265         if(JvmThreadContentionMonitoringEnabled.intValue() == x.intValue())
 266             mbean.setThreadContentionMonitoringEnabled(true);
 267         else
 268             mbean.setThreadContentionMonitoringEnabled(false);
 269     }
 270 
 271     /**
 272      * Checker for the "JvmThreadContentionMonitoring" variable.
 273      */
 274     public void checkJvmThreadContentionMonitoring(
 275                               EnumJvmThreadContentionMonitoring x)
 276         throws SnmpStatusException {
 277         //Can't be set externaly to unsupported state.
 278         if(JvmThreadContentionMonitoringUnsupported.intValue()==x.intValue()) {
 279             log.debug("checkJvmThreadContentionMonitoring",
 280                       "Try to set to illegal unsupported value");
 281             throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 282         }
 283 
 284         if ((JvmThreadContentionMonitoringEnabled.intValue()==x.intValue()) ||
 285             (JvmThreadContentionMonitoringDisabled.intValue()==x.intValue())) {
 286 
 287             // The value is valid, but is the feature supported ?
 288             ThreadMXBean mbean = getThreadMXBean();
 289             if(mbean.isThreadContentionMonitoringSupported()) return;
 290 
 291             log.debug("checkJvmThreadContentionMonitoring",
 292                       "Unsupported operation, can't set state");
 293             throw new
 294                 SnmpStatusException(SnmpDefinitions.snmpRspInconsistentValue);
 295         }
 296 
 297         log.debug("checkJvmThreadContentionMonitoring",
 298                   "Try to set to unknown value");
 299         throw new SnmpStatusException(SnmpDefinitions.snmpRspWrongValue);
 300     }
 301 
 302     /**
 303      * Getter for the "JvmThreadTotalStartedCount" variable.
 304      */
 305     public Long getJvmThreadTotalStartedCount() throws SnmpStatusException {
 306         return new Long(getThreadMXBean().getTotalStartedThreadCount());
 307     }
 308 
 309     /**
 310      * Getter for the "JvmThreadPeakCount" variable.
 311      */
 312     public Long getJvmThreadPeakCount() throws SnmpStatusException {
 313         return  new Long(getThreadMXBean().getPeakThreadCount());
 314     }
 315 
 316     /**
 317      * Getter for the "JvmThreadDaemonCount" variable.
 318      */
 319     public Long getJvmThreadDaemonCount() throws SnmpStatusException {
 320         return new Long(getThreadMXBean().getDaemonThreadCount());
 321     }
 322 
 323     /**
 324      * Getter for the "JvmThreadCount" variable.
 325      */
 326     public Long getJvmThreadCount() throws SnmpStatusException {
 327         return new Long(getThreadMXBean().getThreadCount());
 328     }
 329 
 330    /**
 331      * Getter for the "JvmThreadPeakCountReset" variable.
 332      */
 333     public synchronized Long getJvmThreadPeakCountReset()
 334         throws SnmpStatusException {
 335         return new Long(jvmThreadPeakCountReset);
 336     }
 337 
 338     /**
 339      * Setter for the "JvmThreadPeakCountReset" variable.
 340      */
 341     public synchronized void setJvmThreadPeakCountReset(Long x)
 342         throws SnmpStatusException {
 343         final long l = x.longValue();
 344         if (l > jvmThreadPeakCountReset) {
 345             final long stamp = System.currentTimeMillis();
 346             getThreadMXBean().resetPeakThreadCount();
 347             jvmThreadPeakCountReset = stamp;
 348             log.debug("setJvmThreadPeakCountReset",
 349                       "jvmThreadPeakCountReset="+stamp);
 350         }
 351     }
 352 
 353     /**
 354      * Checker for the "JvmThreadPeakCountReset" variable.
 355      */
 356     public void checkJvmThreadPeakCountReset(Long x)
 357         throws SnmpStatusException {
 358     }
 359 
 360     /* Last time thread peak count was reset */
 361     private long jvmThreadPeakCountReset=0;
 362 
 363     static final MibLogger log = new MibLogger(JvmThreadingImpl.class);
 364 }