This adds the missing implementation of a Thread MX bean at last.
This also removes the earlier VMThreadInfo interface, which turned
out to be unworkable for two reasons:

* The bean implementation and ThreadInfo exist in different packages,
and thus one can't construct the other from Java.  There are ways to
avoid this, but they are generally ugly.
* The real showstopper is that the information needs to be serialized to
a javax.management.openmbean.CompositeData object and back (see the
currently missing from(CompositeData) method of ThreadInfo).  This implies
that the information is not discovered on a as-needed basis, as I first thought,
but when the ThreadInfo is created.

Thus, the same information is still required from the VM, but instead of 
supplying
it via a series of native methods, it is supplied to the new private constructor
of ThreadInfo in one shot.  This also leaves the interpretation of maxDepth with
the VM.

A new interface, VMThreadMXBeanImpl, is supplied which includes the call to the
VM to get the ThreadInfo along with the other required methods.  This includes 
some
default implementations of some of the methods, which can be overridden with 
better
solutions by the VMs.

Changelog:

2006-07-01  Andrew John Hughes  <[EMAIL PROTECTED]>

        * gnu/java/lang/management/BeanImpl.java:
        New superclass for all bean implementations.
        * gnu/java/lang/management/ClassLoadingMXBeanImpl.java:
        Extend BeanImpl and call permission code there.
        * gnu/java/lang/management/OperatingSystemMXBeanImpl.java:
        Extend BeanImpl.
        * gnu/java/lang/management/RuntimeMXBeanImpl.java:
        Extend BeanImpl and call permission code there.
        * gnu/java/lang/management/ThreadMXBeanImpl.java:
        New file.
        * java/lang/management/ManagementFactory.java:
        (getThreadMXBean()): Implemented.
        * java/lang/management/ThreadInfo.java:
        (ThreadInfo(Thread,int)): Replaced...
        (ThreadInfo(Thread,long,long,Object,Thread,long,long,
        boolean, boolean, StackTraceElement[])): with this.
        (getBlockedCount()): Refactored to use local variables.
        (getBlockedTime()): Likewise.
        (getLockName()): Likewise.
        (getLockOwnerId()): Likewise.
        (getLockOwnerName()): Likewise.
        (getStackTrace()): Likewise.
        (getWaitedCount()): Likewise.
        (getWaitedTime()): Likewise.
        (isInNative()): Likewise.
        (isSuspended()): Likewise.
        (toString()): Changed to use new local variables.
        * java/lang/management/ThreadMXBean.java:
        (getThreadInfo(long, int)): Corrected documentation.
        (getThreadInfo(long[], int)): Likewise.
        * vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java:
        New file.
        * vm/reference/java/lang/management/VMThreadInfo.java:
        Removed.

-- 
Andrew :-)

Please avoid sending me Microsoft Office (e.g. Word, PowerPoint) attachments.
See http://www.fsf.org/philosophy/no-word-attachments.html

If you use Microsoft Office, support movement towards the end of vendor lock-in:
http://opendocumentfellowship.org/petition/

"Value your freedom, or you will lose it, teaches history. 
`Don't bother us with politics' respond those who don't want to learn." 
-- Richard Stallman

Escape the Java Trap with GNU Classpath!
http://www.gnu.org/philosophy/java-trap.html
public class gcj extends Freedom implements Java { ... }
Index: gnu/java/lang/management/BeanImpl.java
===================================================================
RCS file: gnu/java/lang/management/BeanImpl.java
diff -N gnu/java/lang/management/BeanImpl.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/lang/management/BeanImpl.java      1 Jul 2006 10:34:10 -0000
@@ -0,0 +1,65 @@
+/* BeanImpl.java - A common superclass for bean implementations.
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ManagementPermission;
+
+/**
+ * A common superclass for bean implementations.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.5
+ */
+public class BeanImpl
+{
+
+  protected void checkMonitorPermissions()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPermission(new ManagementPermission("monitor"));
+  }
+
+  protected void checkControlPermissions()
+  {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null)
+      sm.checkPermission(new ManagementPermission("control"));
+  }
+
+}
Index: gnu/java/lang/management/ClassLoadingMXBeanImpl.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/management/ClassLoadingMXBeanImpl.java,v
retrieving revision 1.2
diff -u -3 -p -u -r1.2 ClassLoadingMXBeanImpl.java
--- gnu/java/lang/management/ClassLoadingMXBeanImpl.java        25 Jun 2006 
16:54:57 -0000      1.2
+++ gnu/java/lang/management/ClassLoadingMXBeanImpl.java        1 Jul 2006 
10:34:10 -0000
@@ -50,6 +50,7 @@ import java.lang.management.ManagementPe
  * @since 1.5
  */
 public final class ClassLoadingMXBeanImpl
+  extends BeanImpl
   implements ClassLoadingMXBean
 {
 
@@ -75,9 +76,7 @@ public final class ClassLoadingMXBeanImp
 
   public void setVerbose(boolean verbose)
   {
-    SecurityManager sm = System.getSecurityManager();
-    if (sm != null)
-      sm.checkPermission(new ManagementPermission("control"));
+    checkControlPermissions();
     VMClassLoadingMXBeanImpl.setVerbose(verbose);
   }
 
Index: gnu/java/lang/management/OperatingSystemMXBeanImpl.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/management/OperatingSystemMXBeanImpl.java,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 OperatingSystemMXBeanImpl.java
--- gnu/java/lang/management/OperatingSystemMXBeanImpl.java     28 May 2006 
15:04:14 -0000      1.1
+++ gnu/java/lang/management/OperatingSystemMXBeanImpl.java     1 Jul 2006 
10:34:10 -0000
@@ -47,6 +47,7 @@ import java.lang.management.OperatingSys
  * @since 1.5
  */
 public final class OperatingSystemMXBeanImpl
+  extends BeanImpl
   implements OperatingSystemMXBean
 {
   
Index: gnu/java/lang/management/RuntimeMXBeanImpl.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/management/RuntimeMXBeanImpl.java,v
retrieving revision 1.2
diff -u -3 -p -u -r1.2 RuntimeMXBeanImpl.java
--- gnu/java/lang/management/RuntimeMXBeanImpl.java     24 Jun 2006 21:20:34 
-0000      1.2
+++ gnu/java/lang/management/RuntimeMXBeanImpl.java     1 Jul 2006 10:34:10 
-0000
@@ -39,7 +39,6 @@ package gnu.java.lang.management;
 
 import gnu.classpath.SystemProperties;
 
-import java.lang.management.ManagementPermission;
 import java.lang.management.RuntimeMXBean;
 
 import java.util.Arrays;
@@ -57,6 +56,7 @@ import java.util.Properties;
  * @since 1.5
  */
 public final class RuntimeMXBeanImpl
+  extends BeanImpl
   implements RuntimeMXBean
 {
 
@@ -69,13 +69,6 @@ public final class RuntimeMXBeanImpl
 
   private boolean bootClassPathSupported = true;
 
-  void checkMonitorPermissions()
-  {
-    SecurityManager sm = System.getSecurityManager();
-    if (sm != null)
-      sm.checkPermission(new ManagementPermission("monitor"));
-  }
-
   public String getBootClassPath()
   {
     checkMonitorPermissions();
Index: gnu/java/lang/management/ThreadMXBeanImpl.java
===================================================================
RCS file: gnu/java/lang/management/ThreadMXBeanImpl.java
diff -N gnu/java/lang/management/ThreadMXBeanImpl.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/lang/management/ThreadMXBeanImpl.java      1 Jul 2006 10:34:10 
-0000
@@ -0,0 +1,283 @@
+/* ThreadMXBeanImpl.java - Implementation of a thread bean
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import gnu.classpath.SystemProperties;
+
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.lang.management.ManagementPermission;
+
+/**
+ * Provides access to information about the threads 
+ * of the virtual machine.  An instance of this bean is
+ * obtained by calling
+ * [EMAIL PROTECTED] ManagementFactory#getThreadMXBean()}.
+ * See [EMAIL PROTECTED] java.lang.management.ThreadMXBean} for
+ * full documentation.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.5
+ */
+public final class ThreadMXBeanImpl
+  extends BeanImpl
+  implements ThreadMXBean
+{
+
+  /**
+   * Constant for current thread time support.
+   */
+  private static final String CURRENT_THREAD_TIME_SUPPORT = 
+    "gnu.java.lang.management.CurrentThreadTimeSupport";
+
+  /**
+   * Constant for thread time support.
+   */
+  private static final String THREAD_TIME_SUPPORT = 
+    "gnu.java.lang.management.ThreadTimeSupport";
+
+  /**
+   * Constant for thread contention support.
+   */
+  private static final String CONTENTION_SUPPORT = 
+    "gnu.java.lang.management.ThreadContentionSupport";
+
+  /**
+   * Constant for initial value of thread time support.
+   */
+  private static final String TIME_ENABLED = 
+    "gnu.java.lang.management.ThreadTimeInitallyEnabled";
+  
+  /**
+   * Flag to indicate whether time monitoring is enabled or not.
+   */
+  private boolean timeEnabled;
+
+  /**
+   * Flag to indicate whether contention monitoring is enabled or not.
+   */
+  private boolean contentionEnabled;
+
+  /**
+   * Default constructor to set up flag states.  The
+   * VM has to specify whether time monitoring is initially
+   * enabled or not.
+   */
+  public ThreadMXBeanImpl()
+  {
+    timeEnabled = 
Boolean.parseBoolean(SystemProperties.getProperty(TIME_ENABLED));
+    contentionEnabled = false;
+  }
+
+  public long[] findMonitorDeadlockedThreads()
+  {
+    checkMonitorPermissions();
+    return VMThreadMXBeanImpl.findMonitorDeadlockedThreads();
+  }
+
+  public long[] getAllThreadIds()
+  {
+    checkMonitorPermissions();
+    return VMThreadMXBeanImpl.getAllThreadIds();
+  }
+
+  public long getCurrentThreadCpuTime()
+  {
+    if (!isCurrentThreadCpuTimeSupported())
+      throw new UnsupportedOperationException("Current thread CPU " +
+                                             "time not supported.");
+    if (!timeEnabled)
+      return -1;
+    return VMThreadMXBeanImpl.getCurrentThreadCpuTime();
+  }
+
+  public long getCurrentThreadUserTime()
+  {
+    if (!isCurrentThreadCpuTimeSupported())
+      throw new UnsupportedOperationException("Current thread user " +
+                                             "time not supported.");
+    if (!timeEnabled)
+      return -1;
+    return VMThreadMXBeanImpl.getCurrentThreadUserTime();
+  }
+
+  public int getDaemonThreadCount()
+  {
+    return VMThreadMXBeanImpl.getDaemonThreadCount();
+  }
+
+  public int getPeakThreadCount()
+  {
+    return VMThreadMXBeanImpl.getPeakThreadCount();
+  }
+
+  public int getThreadCount()
+  {
+    return VMThreadMXBeanImpl.getThreadCount();
+  }
+
+  public long getThreadCpuTime(long id)
+  {
+    if (!isThreadCpuTimeSupported())
+      throw new UnsupportedOperationException("Thread CPU time not " +
+                                             "supported.");
+    if (id <= 0)
+      throw new IllegalArgumentException("Invalid thread id: " + id);
+    if (!timeEnabled)
+      return -1;
+    return VMThreadMXBeanImpl.getThreadCpuTime(id);
+  }
+
+  public ThreadInfo getThreadInfo(long id)
+  {
+    return getThreadInfo(id, 0);
+  }
+
+  public ThreadInfo[] getThreadInfo(long[] ids)
+  {
+    return getThreadInfo(ids, 0);
+  }
+
+  public ThreadInfo getThreadInfo(long id, int maxDepth)
+  {
+    checkMonitorPermissions();
+    if (id <= 0)
+      throw new IllegalArgumentException("Invalid thread id: " + id);
+    if (maxDepth < 0)
+      throw new IllegalArgumentException("Invalid depth: " + maxDepth);
+    return VMThreadMXBeanImpl.getThreadInfoForId(id, maxDepth);
+  }
+
+  public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth)
+  {
+    checkMonitorPermissions();
+    if (maxDepth < 0)
+      throw new IllegalArgumentException("Invalid depth: " + maxDepth);
+    ThreadInfo[] infos = new ThreadInfo[ids.length];
+    for (int a = 0; a < ids.length; ++a)
+      {
+       if (ids[a] <= 0)
+         throw new IllegalArgumentException("Invalid thread id " + a +
+                                            ": " + ids[a]);
+       infos[a] = VMThreadMXBeanImpl.getThreadInfoForId(ids[a], maxDepth);
+      }
+    return infos;
+  }
+
+  public long getThreadUserTime(long id)
+  {
+    if (!isThreadCpuTimeSupported())
+      throw new UnsupportedOperationException("Thread user time not " +
+                                             "supported.");
+    if (id <= 0)
+      throw new IllegalArgumentException("Invalid thread id: " + id);
+    if (!timeEnabled)
+      return -1;
+    return VMThreadMXBeanImpl.getThreadUserTime(id);
+  }
+
+  public long getTotalStartedThreadCount()
+  {
+    return VMThreadMXBeanImpl.getTotalStartedThreadCount();
+  }
+
+  public boolean isCurrentThreadCpuTimeSupported()
+  {
+    if (isThreadCpuTimeSupported())
+      return true;
+    return SystemProperties.getProperty(CURRENT_THREAD_TIME_SUPPORT) != null;
+  }
+
+  public boolean isThreadContentionMonitoringEnabled()
+  {
+    if (isThreadContentionMonitoringSupported())
+      return contentionEnabled;
+    else
+      throw new UnsupportedOperationException("Contention monitoring " +
+                                             "not supported.");
+  }
+
+  public boolean isThreadContentionMonitoringSupported()
+  {
+    return SystemProperties.getProperty(CONTENTION_SUPPORT) != null;
+  }
+
+  public boolean isThreadCpuTimeEnabled()
+  {
+    if (isThreadCpuTimeSupported() ||
+       isCurrentThreadCpuTimeSupported())
+      return timeEnabled;
+    else
+      throw new UnsupportedOperationException("Thread time not " +
+                                             "supported.");
+  }
+  
+  public boolean isThreadCpuTimeSupported()
+  {
+    return SystemProperties.getProperty(THREAD_TIME_SUPPORT) != null;
+  }
+
+  public void resetPeakThreadCount()
+  {
+    checkControlPermissions();
+    VMThreadMXBeanImpl.resetPeakThreadCount();
+  }
+  
+  public void setThreadContentionMonitoringEnabled(boolean enable)
+  {
+    checkControlPermissions();
+    if (isThreadContentionMonitoringSupported())
+      contentionEnabled = enable;
+    else
+      throw new UnsupportedOperationException("Contention monitoring " +
+                                             "not supported.");
+  }    
+  
+  public void setThreadCpuTimeEnabled(boolean enable)
+  {
+    checkControlPermissions();
+    if (isThreadCpuTimeSupported() ||
+       isCurrentThreadCpuTimeSupported())
+      timeEnabled = enable;
+    else
+      throw new UnsupportedOperationException("Thread time not " +
+                                             "supported.");
+  }
+
+}
+
Index: java/lang/management/ManagementFactory.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/java/lang/management/ManagementFactory.java,v
retrieving revision 1.5
diff -u -3 -p -u -r1.5 ManagementFactory.java
--- java/lang/management/ManagementFactory.java 26 Jun 2006 20:56:58 -0000      
1.5
+++ java/lang/management/ManagementFactory.java 1 Jul 2006 10:34:11 -0000
@@ -37,11 +37,10 @@ exception statement from your version. *
 
 package java.lang.management;
 
-import gnu.classpath.NotImplementedException;
-
 import gnu.java.lang.management.ClassLoadingMXBeanImpl;
 import gnu.java.lang.management.OperatingSystemMXBeanImpl;
 import gnu.java.lang.management.RuntimeMXBeanImpl;
+import gnu.java.lang.management.ThreadMXBeanImpl;
 
 /**
  * <p>
@@ -79,6 +78,11 @@ public class ManagementFactory
   private static ClassLoadingMXBean classLoadingBean;
 
   /**
+   * The thread bean.
+   */
+  private static ThreadMXBean threadBean;
+
+  /**
    * Private constructor to prevent instance creation.
    */
   private ManagementFactory() {}
@@ -133,9 +137,10 @@ public class ManagementFactory
    *         this virtual machine.
    */
   public static ThreadMXBean getThreadMXBean()
-    throws NotImplementedException
   {
-    return null;
+    if (threadBean == null)
+      threadBean = new ThreadMXBeanImpl();
+    return threadBean;
   }
 
 }
Index: java/lang/management/ThreadInfo.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/management/ThreadInfo.java,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 ThreadInfo.java
--- java/lang/management/ThreadInfo.java        26 Jun 2006 20:56:58 -0000      
1.1
+++ java/lang/management/ThreadInfo.java        1 Jul 2006 10:34:11 -0000
@@ -88,9 +88,57 @@ public class ThreadInfo
   private Thread thread;
 
   /**
-   * The maximum depth of the stack traces for this thread.
+   * The number of times the thread has been blocked.
    */
-  private int maxDepth;
+  private long blockedCount;
+
+  /**
+   * The accumulated number of milliseconds the thread has
+   * been blocked (used only with thread contention monitoring
+   * support).
+   */
+  private long blockedTime;
+
+  /**
+   * The monitor lock on which this thread is blocked
+   * (if any).
+   */
+  private Object lock;
+
+  /**
+   * The thread which owns the monitor lock on which this
+   * thread is blocked, or <code>null</code> if there is
+   * no owner.
+   */
+  private Thread lockOwner;
+
+  /**
+   * The number of times the thread has been in a waiting
+   * state.
+   */
+  private long waitedCount;
+
+  /**
+   * The accumulated number of milliseconds the thread has
+   * been waiting (used only with thread contention monitoring
+   * support).
+   */
+  private long waitedTime;
+
+  /**
+   * True if the thread is in a native method.
+   */
+  private boolean isInNative;
+
+  /**
+   * True if the thread is suspended.
+   */
+  private boolean isSuspended;
+
+  /**
+   * The stack trace of the thread.
+   */
+  private StackTraceElement[] trace;
 
   /**
    * Cache a local reference to the thread management bean.
@@ -103,11 +151,41 @@ public class ThreadInfo
    *
    * @param thread the thread on which the new instance
    *               will be based.
-   */
-  ThreadInfo(Thread thread, int maxDepth)
+   * @param blockedCount the number of times the thread
+   *                     has been blocked.
+   * @param blockedTime the accumulated number of milliseconds
+   *                    the specified thread has been blocked
+   *                    (only used with contention monitoring enabled)
+   * @param lock the monitor lock the thread is waiting for
+   *             (only used if blocked)
+   * @param lockOwner the thread which owns the monitor lock, or
+   *                  <code>null</code> if it doesn't have an owner
+   *                  (only used if blocked)
+   * @param waitedCount the number of times the thread has been in a
+   *                    waiting state.
+   * @param waitedTime the accumulated number of milliseconds the
+   *                   specified thread has been waiting
+   *                   (only used with contention monitoring enabled)
+   * @param isInNative true if the thread is in a native method.
+   * @param isSuspended true if the thread is suspended.
+   * @param trace the stack trace of the thread to a pre-determined
+   *              depth (see VMThreadMXBeanImpl)
+   */
+  private ThreadInfo(Thread thread, long blockedCount, long blockedTime,
+                    Object lock, Thread lockOwner, long waitedCount,
+                    long waitedTime, boolean isInNative, boolean isSuspended,
+                    StackTraceElement[] trace)
   {
     this.thread = thread;
-    this.maxDepth = maxDepth;
+    this.blockedCount = blockedCount;
+    this.blockedTime = blockedTime;
+    this.lock = lock;
+    this.lockOwner = lockOwner;
+    this.waitedCount = waitedCount;
+    this.waitedTime = waitedTime;
+    this.isInNative = isInNative;
+    this.isSuspended = isSuspended;
+    this.trace = trace;
   }
 
   /**
@@ -123,7 +201,7 @@ public class ThreadInfo
    */
   public long getBlockedCount()
   {
-    return VMThreadInfo.getBlockedCount(thread);
+    return blockedCount;
   }
 
   /**
@@ -161,7 +239,7 @@ public class ThreadInfo
       bean = ManagementFactory.getThreadMXBean();
     // Will throw UnsupportedOperationException for us
     if (bean.isThreadContentionMonitoringEnabled())
-      return VMThreadInfo.getBlockedTime(thread);
+      return blockedTime;
     else
       return -1;
   }
@@ -196,7 +274,6 @@ public class ThreadInfo
   {
     if (thread.getState().equals("BLOCKED"))
       return null;
-    Object lock = VMThreadInfo.getLock(thread);
     return lock.getClass().getName() + "@" +
       Integer.toHexString(System.identityHashCode(lock));
   }
@@ -216,7 +293,6 @@ public class ThreadInfo
   {
     if (thread.getState().equals("BLOCKED"))
       return -1;
-    Thread lockOwner = VMThreadInfo.getLockOwner(thread);
     if (lockOwner == null)
       return -1;
     return lockOwner.getId();
@@ -237,7 +313,6 @@ public class ThreadInfo
   {
     if (thread.getState().equals("BLOCKED"))
       return null;
-    Thread lockOwner = VMThreadInfo.getLockOwner(thread);
     if (lockOwner == null)
       return null;
     return lockOwner.getName();
@@ -264,9 +339,7 @@ public class ThreadInfo
    */
   public StackTraceElement[] getStackTrace()
   {
-    if (maxDepth == 0)
-      return new StackTraceElement[0];
-    return VMThreadInfo.getStackTrace(thread, maxDepth);
+    return trace;
   }
 
   /**
@@ -316,7 +389,7 @@ public class ThreadInfo
    */
   public long getWaitedCount()
   {
-    return VMThreadInfo.getWaitedCount(thread);
+    return waitedCount;
   }
 
   /**
@@ -355,7 +428,7 @@ public class ThreadInfo
       bean = ManagementFactory.getThreadMXBean();
     // Will throw UnsupportedOperationException for us
     if (bean.isThreadContentionMonitoringEnabled())
-      return VMThreadInfo.getWaitedTime(thread);
+      return waitedTime;
     else
       return -1;
   }
@@ -371,7 +444,7 @@ public class ThreadInfo
    */
   public boolean isInNative()
   {
-    return VMThreadInfo.isInNative(thread);
+    return isInNative;
   }
 
   /**
@@ -382,7 +455,7 @@ public class ThreadInfo
    */
   public boolean isSuspended()
   {
-    return VMThreadInfo.isSuspended(thread);
+    return isSuspended;
   }
 
   /**
@@ -397,9 +470,18 @@ public class ThreadInfo
    */
   public String toString()
   {
+    String state = thread.getState();
     return getClass().getName() +
-      "[id=" + thread.getId() + ", maxDepth=" +
-      maxDepth + "]";
+      "[id=" + thread.getId() + 
+      ", name=" + thread.getName() +
+      ", state=" + state +
+      ", blockedCount=" + blockedCount +
+      ", waitedCount=" + waitedCount +
+      ", isInNative=" + isInNative + 
+      ", isSuspended=" + isSuspended +
+      (state.equals("BLOCKED") ? ", lock=" + lock +
+       ", lockOwner=" + lockOwner : "") +
+      "]";
   }
 
 }
Index: java/lang/management/ThreadMXBean.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/management/ThreadMXBean.java,v
retrieving revision 1.2
diff -u -3 -p -u -r1.2 ThreadMXBean.java
--- java/lang/management/ThreadMXBean.java      27 Jun 2006 18:26:52 -0000      
1.2
+++ java/lang/management/ThreadMXBean.java      1 Jul 2006 10:34:11 -0000
@@ -304,7 +304,7 @@ public interface ThreadMXBean
    *         thread, or <code>null</code> if the identifier specifies
    *         a thread that doesn't exist or is not alive.
    * @throws IllegalArgumentException if <code>id</code> <= 0.
-   * @throws IllegalArgumentException if <code>maxDepth</code> <= 0.
+   * @throws IllegalArgumentException if <code>maxDepth</code> < 0.
    * @throws SecurityException if a security manager exists and
    *                           denies ManagementPermission("monitor").
    */
@@ -332,7 +332,7 @@ public interface ThreadMXBean
    *         a thread that doesn't exist or is not alive.
    * @throws IllegalArgumentException if an identifier in the array is
    *                                  <= 0.
-   * @throws IllegalArgumentException if <code>maxDepth</code> <= 0.
+   * @throws IllegalArgumentException if <code>maxDepth</code> < 0.
    * @throws SecurityException if a security manager exists and
    *                           denies ManagementPermission("monitor").
    */
Index: vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
===================================================================
RCS file: vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
diff -N vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ vm/reference/gnu/java/lang/management/VMThreadMXBeanImpl.java       1 Jul 
2006 10:34:11 -0000
@@ -0,0 +1,207 @@
+/* VMThreadMXBeanImpl.java - VM impl. of a thread bean
+   Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.lang.management;
+
+import java.lang.management.ThreadInfo;
+
+/**
+ * Provides access to information about the threads 
+ * of the virtual machine.  An instance of this bean is
+ * obtained by calling
+ * [EMAIL PROTECTED] ManagementFactory#getThreadMXBean()}.
+ * See [EMAIL PROTECTED] java.lang.management.ThreadMXBean} for
+ * full documentation.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.5
+ */
+final class VMThreadMXBeanImpl
+{
+
+  /**
+   * Cache of how many threads were found.
+   */
+  private static int filled;
+
+  /**
+   * Returns the ids of cycles of deadlocked threads, occurring
+   * due to monitor ownership.
+   *
+   * @return the ids of the deadlocked threads.
+   */
+  static native long[] findMonitorDeadlockedThreads();
+
+  /* This is the same as in Thread.getAllStackTraces() */
+  static Thread[] getAllThreads()
+  {
+    ThreadGroup group = Thread.currentThread().getThreadGroup();
+    while (group.getParent() != null)
+      group = group.getParent();
+    int arraySize = group.activeCount();
+    Thread[] threadList = new Thread[arraySize];
+    filled = group.enumerate(threadList);
+    while (filled == arraySize)
+      {
+       arraySize *= 2;
+       threadList = new Thread[arraySize];
+       filled = group.enumerate(threadList);
+      }
+    return threadList;
+  }
+  
+  /**
+   * Returns the id of all live threads at the time of execution.
+   *
+   * @return the live thread ids.
+   */
+  static long[] getAllThreadIds()
+  {
+    Thread[] threadList = getAllThreads();
+    long[] ids = new long[filled];
+    for (int a = 0; a < filled; ++a)
+      ids[a] = threadList[a].getId();
+    return ids;
+  }
+
+  /**
+   * Returns the number of nanoseconds of CPU time
+   * the current thread has used in total.   This is
+   * only called if this feature is enabled and
+   * supported.
+   *
+   * @return the nanoseconds of CPU time used by
+   *         the current thread.
+   */
+  static native long getCurrentThreadCpuTime();
+
+  /**
+   * Returns the number of nanoseconds of user time
+   * the current thread has used in total.   This is
+   * only called if this feature is enabled and
+   * supported.
+   *
+   * @return the nanoseconds of user time used by
+   *         the current thread.
+   */
+  static native long getCurrentThreadUserTime();
+
+  /**
+   * Returns the number of live daemon threads.
+   *
+   * @return the number of live daemon threads.
+   */
+  static int getDaemonThreadCount()
+  {
+    Thread[] threadList = getAllThreads();
+    int daemonCount = 0;
+    for (int a = 0; a < filled; ++a)
+      {
+       if (threadList[a].isDaemon())
+         ++daemonCount;
+      }
+    return daemonCount;
+  }
+
+  /**
+   * Returns the current peak number of live threads.
+   *
+   * @return the peak number of live threads.
+   */
+  static native int getPeakThreadCount();
+
+  /**
+   * Returns the number of live threads.
+   *
+   * @return the number of live threads.
+   */
+  static int getThreadCount()
+  {
+    getAllThreads();
+    return filled;
+  }
+
+  /**
+   * Returns the number of nanoseconds of CPU time
+   * the specified thread has used in total.   This is
+   * only called if this feature is enabled and
+   * supported.
+   *
+   * @param id the thread to obtain statistics on.
+   * @return the nanoseconds of CPU time used by
+   *         the thread.
+   */
+  static native long getThreadCpuTime(long id);
+
+  /**
+   * Returns the [EMAIL PROTECTED] java.lang.management.ThreadInfo}
+   * which corresponds to the specified id.
+   *
+   * @param id the id of the thread.
+   * @param maxDepth the depth of the stack trace.
+   * @return the corresponding <code>ThreadInfo</code>.
+   */
+  static native ThreadInfo getThreadInfoForId(long id, int maxDepth);
+  
+  /**
+   * Returns the number of nanoseconds of user time
+   * the specified thread has used in total.   This is
+   * only called if this feature is enabled and
+   * supported.
+   *
+   * @param id the thread to obtain statistics on.
+   * @return the nanoseconds of user time used by
+   *         the thread.
+   */
+  static native long getThreadUserTime(long id);
+  
+  /**
+   * Returns the total number of threads that have
+   * been started over the lifetime of the virtual
+   * machine.
+   *
+   * @return the total number of threads started.
+   */
+  static native long getTotalStartedThreadCount();
+
+  /**
+   * Resets the peak thread count to the current
+   * number of live threads.
+   */
+  static native void resetPeakThreadCount();
+
+}
Index: vm/reference/java/lang/management/VMThreadInfo.java
===================================================================
RCS file: vm/reference/java/lang/management/VMThreadInfo.java
diff -N vm/reference/java/lang/management/VMThreadInfo.java
--- vm/reference/java/lang/management/VMThreadInfo.java 26 Jun 2006 20:56:58 
-0000      1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,159 +0,0 @@
-/* VMThreadInfo.java - Information on a thread
-   Copyright (C) 2006 Free Software Foundation
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath 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 for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package java.lang.management;
-
-/**
- * Provides low-level information about a thread.
- *
- * @author Andrew John Hughes ([EMAIL PROTECTED])
- * @since 1.5
- * @see java.lang.management.ThreadInfo
- */
-final class VMThreadInfo
-{
-
-  /**
-   * Return the number of times the specified thread
-   * has been in the [EMAIL PROTECTED] java.lang.Thread.State#BLOCKED}
-   * state.
-   *
-   * @param thread the thread to return statistics on.
-   * @return the number of times the thread has been blocked.
-   */
-  static native long getBlockedCount(Thread thread);
-
-  /**
-   * Returns the accumulated number of milliseconds the
-   * specified thread has spent in the
-   * [EMAIL PROTECTED] java.lang.Thread.State#BLOCKED} state.  This
-   * method is only called if thread contention monitoring
-   * is both supported and enabled.
-   *
-   * @param thread the thread to return statistics on.
-   * @return the accumulated number of milliseconds the
-   *         thread has been blocked for.
-   */
-  static native long getBlockedTime(Thread thread);
-
-  /**
-   * Returns the monitor lock the specified thread is
-   * waiting for.  This is only called when the thread
-   * is in the [EMAIL PROTECTED] java.lang.Thread.State#BLOCKED}
-   * state.
-   *
-   * @param thread the thread to return statistics on.
-   * @return the monitor lock the thread is waiting for.
-   */
-  static native Object getLock(Thread thread);
-
-  /**
-   * Returns the thread which currently owns the monitor
-   * lock the specified thread is waiting for.  This is
-   * only called when the thread is in the
-   * [EMAIL PROTECTED] java.lang.Thread.State#BLOCKED} state.  It
-   * may return <code>null</code> if the lock is not held
-   * by another thread.
-   *
-   * @param thread the thread to return statistics on.
-   * @return the thread which owns the monitor lock the
-   *         thread is waiting for, or <code>null</code>
-   *         if it doesn't have an owner.
-   */
-  static native Thread getLockOwner(Thread thread);
-
-  /**
-   * Return the number of times the specified thread
-   * has been in the [EMAIL PROTECTED] java.lang.Thread.State#WAITING}
-   * or [EMAIL PROTECTED] java.lang.Thread.State#TIMED_WAITING} states.
-   *
-   * @param thread the thread to return statistics on.
-   * @return the number of times the thread has been in 
-   *         waiting state.
-   */
-  static native long getWaitedCount(Thread thread);
-
-  /**
-   * Returns the accumulated number of milliseconds the
-   * specified thread has spent in either the
-   * [EMAIL PROTECTED] java.lang.Thread.State#WAITING} or
-   * [EMAIL PROTECTED] java.lang.Thread.State#TIMED_WAITING} states.
-   * This method is only called if thread contention
-   * monitoring is both supported and enabled.
-   *
-   * @param thread the thread to return statistics on.
-   * @return the accumulated number of milliseconds the
-   *         thread has been in a waiting state for.
-   */
-  static native long getWaitedTime(Thread thread);
-
-  /**
-   * Returns true if the specified thread is in a native
-   * method.
-   *
-   * @param thread the thread to return statistics on.
-   * @return true if the thread is in a native method, false
-   *         otherwise.
-   */
-  static native boolean isInNative(Thread thread);
-
-  /**
-   * Returns true if the specified thread is suspended.
-   *
-   * @param thread the thread to return statistics on.
-   * @return true if the thread is suspended, false otherwise.
-   */
-  static native boolean isSuspended(Thread thread);
-
-  /**
-   * Returns a stack trace for the specified thread of
-   * the supplied depth.  If the depth is
-   * <code>Integer.MAX_VALUE</code>, then the returned
-   * depth is equal to the full stack trace available.
-   * The depth will be greater than zero, due to
-   * filtering in methods prior to this call.
-   *
-   * @param thread the thread whose stack trace should
-   *               be returned.
-   * @param maxDepth the maximum depth of the trace.
-   *                 This will be greater than zero.
-   *                 <code>Integer.MAX_VALUE</code>
-   *                 represents the full trace.
-   */
-  static native StackTraceElement[] getStackTrace(Thread thread,
-                                                 int maxDepth);
-}

Attachment: signature.asc
Description: Digital signature

Reply via email to