public inbox for java-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [JVMTI] RFA: Implement GetAllThreads
@ 2006-09-27 15:29 Kyle Galloway
  2006-10-05 13:46 ` Kyle Galloway
  0 siblings, 1 reply; 2+ messages in thread
From: Kyle Galloway @ 2006-09-27 15:29 UTC (permalink / raw)
  To: Java Patch List

[-- Attachment #1: Type: text/plain, Size: 611 bytes --]

Hi,

The attached patch implements the JVMTI GetAllThreads function.  I have
included a test case using the jvmti testsuite as well.  Nothing too
complicated, gets the root ThreadGroup, then grabs all the threads.  Are
the variable names a problem? I've seen a few different conventions, and
I'll refactor them if need be.

Questions/comments/concerns?

Kyle

2006-09-27  Kyle Galloway  <kgallowa@redhat.com>

    * jvmti.cc (_Jv_JVMTI_GetAllThreads): New method.
    * testsuite/getallthreads.java: New test.
    * testsuite/natgetallthreads.cc: Ditto.
    * testsuite/getallthreads.out: Output file for test.

[-- Attachment #2: getallthread.patch --]
[-- Type: text/x-patch, Size: 4952 bytes --]

Index: /home/kgallowa/workspace/gcc/libjava/jvmti.cc
===================================================================
--- /home/kgallowa/workspace/gcc/libjava/jvmti.cc	(revision 117251)
+++ /home/kgallowa/workspace/gcc/libjava/jvmti.cc	(working copy)
@@ -25,6 +25,7 @@
 #include <java/lang/ClassLoader.h>
 #include <java/lang/Object.h>
 #include <java/lang/Thread.h>
+#include <java/lang/ThreadGroup.h>
 #include <java/lang/Throwable.h>
 #include <java/lang/VMClassLoader.h>
 #include <java/lang/reflect/Field.h>
@@ -103,6 +104,50 @@
 	return JVMTI_ERROR_ILLEGAL_ARGUMENT;	\
     }						\
   while (0)
+  
+static jvmtiError JNICALL
+_Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *threadCount,
+                        jthread **threads)
+{
+  REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
+  NULL_CHECK (threadCount);
+  NULL_CHECK (threads);
+  
+  using namespace java::lang;
+  Thread *thr = Thread::currentThread ();
+  
+  ThreadGroup *thrGrp = thr->getThreadGroup ();
+  ThreadGroup *parent = thrGrp->getParent ();
+  
+  //get the root thread group
+  while (parent != NULL)
+    {
+      thrGrp = parent;
+      parent = thrGrp->getParent ();
+    }
+  
+  jint estimate = thrGrp->activeCount ();
+  
+  //allocate some extra space since threads can be created between calls
+  JArray<Thread *> *thrArray 
+   = (JArray<Thread *> *) JvNewObjectArray ((estimate * 2), &Thread::class$, 
+                                            NULL);
+   
+  (*threadCount) = thrGrp->enumerate (thrArray);
+  
+  env->Allocate ((jlong) ((*threadCount) * sizeof (jthread)), 
+                 reinterpret_cast<unsigned char **> (threads));
+  
+  //now transfer the threads to the result array
+  jthread *tArrPtr = (*threads);
+  
+  for (int i = 0; i < (*threadCount); i++) 
+    {
+	  tArrPtr[i] = reinterpret_cast<jthread> (elements(thrArray)[i]);
+    }
+  
+  return JVMTI_ERROR_NONE;
+}
 
 static jvmtiError JNICALL
 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
@@ -1187,7 +1232,7 @@
   RESERVED,			// reserved1
   _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
   RESERVED,			// reserved3
-  UNIMPLEMENTED,		// GetAllThreads
+  _Jv_JVMTI_GetAllThreads,		// GetAllThreads
   _Jv_JVMTI_SuspendThread,	// SuspendThread
   _Jv_JVMTI_ResumeThread,	// ResumeThread
   UNIMPLEMENTED,		// StopThread
Index: /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/getallthreads.java
===================================================================
--- /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/getallthreads.java	(revision 0)
+++ /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/getallthreads.java	(revision 0)
@@ -0,0 +1,33 @@
+// Test JVMTI GetAllThreads method
+
+public class getallthreads extends Thread
+{
+  private boolean loop;
+  
+  public getallthreads ()
+  {
+    super ();
+    loop = true;
+  }
+  
+  public void run ()
+  {
+    while (loop);
+  }
+  
+  public void done ()
+  {
+	loop = false;
+  }
+
+  public static native void do_getallthreads_tests ();
+
+  public static void main (String[] args)
+  {
+    System.out.println ("JVMTI GetAllThreads test");
+    getallthreads t = new getallthreads ();
+    t.start ();
+    do_getallthreads_tests ();
+    t.done ();
+  }
+}
\ No newline at end of file
Index: /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/getallthreads.out
===================================================================
--- /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/getallthreads.out	(revision 0)
+++ /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/getallthreads.out	(revision 0)
@@ -0,0 +1,8 @@
+JVMTI GetAllThreads test
+Threads:
+
+Found thread 0
+Found thread 1
+Found thread 2
+
+Thread count: 3
Index: /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/natgetallthreads.cc
===================================================================
--- /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/natgetallthreads.cc	(revision 0)
+++ /home/kgallowa/workspace/gcc/libjava/testsuite/libjava.jvmti/natgetallthreads.cc	(revision 0)
@@ -0,0 +1,36 @@
+#include <gcj/cni.h>
+
+#include <jvm.h>
+#include <jvmti.h>
+#include <stdio.h>
+
+#include "jvmti-int.h"
+#include "getallthreads.h"
+
+static void
+print_threads (jthread *threads, jint threadCount)
+{
+  printf("Threads:\n\n");
+  
+  java::lang::Thread *t = NULL;
+  
+  for (int i = 0; i < threadCount; i++)
+    {
+      printf("Found thread %d\n", i);
+    }
+    
+      printf("\nThread count: %d\n", (int) threadCount);
+}
+
+void
+getallthreads::do_getallthreads_tests ()
+{
+  jvmtiEnv *env;
+  JavaVM *vm = _Jv_GetJavaVM ();
+  vm->GetEnv (reinterpret_cast<void **> (&env), JVMTI_VERSION_1_0);
+  jthread *threads;
+  jint threadCount;
+  env->GetAllThreads (&threadCount, &threads);
+  print_threads (threads, threadCount);
+  env->Deallocate (reinterpret_cast<unsigned char *> (threads));
+}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [JVMTI] RFA: Implement GetAllThreads
  2006-09-27 15:29 [JVMTI] RFA: Implement GetAllThreads Kyle Galloway
@ 2006-10-05 13:46 ` Kyle Galloway
  0 siblings, 0 replies; 2+ messages in thread
From: Kyle Galloway @ 2006-10-05 13:46 UTC (permalink / raw)
  To: Kyle Galloway; +Cc: Java Patch List

[-- Attachment #1: Type: text/plain, Size: 566 bytes --]

Keith responded to this off-list with some comments.  I have made some 
small changes, mostly some additional error checking, and a few 
formatting things I missed.  I also expanded the test case to a larger 
number of threads (22 instead of 3).  New patch is attached.

Comments, or is this ok to commit?

Kyle

2006-10-05  Kyle Galloway  <kgallowa@redhat.com>

    * jvmti.cc (_Jv_JVMTI_GetAllThreads): New method.
    * testsuite/getallthreads.java: New test.
    * testsuite/natgetallthreads.cc: Ditto.
    * testsuite/getallthreads.out: Output file for test.



[-- Attachment #2: getallthread.patch --]
[-- Type: text/x-patch, Size: 5377 bytes --]

Index: libjava/testsuite/libjava.jvmti/getallthreads.java
===================================================================
--- libjava/testsuite/libjava.jvmti/getallthreads.java	(revision 0)
+++ libjava/testsuite/libjava.jvmti/getallthreads.java	(revision 0)
@@ -0,0 +1,47 @@
+// Test JVMTI GetAllThreads method
+
+public class getallthreads extends Thread
+{
+  private boolean loop;
+  
+  public getallthreads ()
+  {
+    super ();
+    loop = true;
+  }
+  
+  public void run ()
+  {
+    while (loop)
+    {
+      try
+        {
+    	  sleep (100);
+        }
+      catch (Throwable t)
+        {
+        }
+    }
+  }
+  
+  public void done ()
+  {
+	loop = false;
+  }
+
+  public static native void do_getallthreads_tests ();
+
+  public static void main (String[] args)
+  {
+    System.out.println ("JVMTI GetAllThreads test");
+    getallthreads[] t = new getallthreads[20];
+    for (int i = 0; i < 20; i++)
+      {
+        t[i] = new getallthreads ();
+        t[i].start ();
+      }
+    do_getallthreads_tests ();
+    for (int i = 0; i < 20; i++)
+      t[i].done ();
+  }
+}
Index: libjava/testsuite/libjava.jvmti/getallthreads.out
===================================================================
--- libjava/testsuite/libjava.jvmti/getallthreads.out	(revision 0)
+++ libjava/testsuite/libjava.jvmti/getallthreads.out	(revision 0)
@@ -0,0 +1,27 @@
+JVMTI GetAllThreads test
+Threads:
+
+Found thread 0
+Found thread 1
+Found thread 2
+Found thread 3
+Found thread 4
+Found thread 5
+Found thread 6
+Found thread 7
+Found thread 8
+Found thread 9
+Found thread 10
+Found thread 11
+Found thread 12
+Found thread 13
+Found thread 14
+Found thread 15
+Found thread 16
+Found thread 17
+Found thread 18
+Found thread 19
+Found thread 20
+Found thread 21
+
+Thread count: 22
Index: libjava/testsuite/libjava.jvmti/natgetallthreads.cc
===================================================================
--- libjava/testsuite/libjava.jvmti/natgetallthreads.cc	(revision 0)
+++ libjava/testsuite/libjava.jvmti/natgetallthreads.cc	(revision 0)
@@ -0,0 +1,36 @@
+#include <gcj/cni.h>
+
+#include <jvm.h>
+#include <jvmti.h>
+#include <stdio.h>
+
+#include "jvmti-int.h"
+#include "getallthreads.h"
+
+static void
+print_threads (jthread *threads, jint threadCount)
+{
+  printf ("Threads:\n\n");
+  
+  java::lang::Thread *t = NULL;
+  
+  for (int i = 0; i < threadCount; i++)
+    {
+      printf ("Found thread %d\n", i);
+    }
+    
+  printf ("\nThread count: %d\n", (int) threadCount);
+}
+
+void
+getallthreads::do_getallthreads_tests ()
+{
+  jvmtiEnv *env;
+  JavaVM *vm = _Jv_GetJavaVM ();
+  vm->GetEnv (reinterpret_cast<void **> (&env), JVMTI_VERSION_1_0);
+  jthread *threads;
+  jint threadCount;
+  env->GetAllThreads (&threadCount, &threads);
+  print_threads (threads, threadCount);
+  env->Deallocate (reinterpret_cast<unsigned char *> (threads));
+}
Index: libjava/jvmti.cc
===================================================================
--- libjava/jvmti.cc	(revision 117434)
+++ libjava/jvmti.cc	(working copy)
@@ -24,7 +24,9 @@
 #include <java/lang/Class.h>
 #include <java/lang/ClassLoader.h>
 #include <java/lang/Object.h>
+#include <java/lang/OutOfMemoryError.h>
 #include <java/lang/Thread.h>
+#include <java/lang/ThreadGroup.h>
 #include <java/lang/Throwable.h>
 #include <java/lang/VMClassLoader.h>
 #include <java/lang/reflect/Field.h>
@@ -103,7 +105,61 @@
 	return JVMTI_ERROR_ILLEGAL_ARGUMENT;	\
     }						\
   while (0)
+  
+static jvmtiError JNICALL
+_Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *threadCount,
+                        jthread **threads)
+{
+  REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
+  NULL_CHECK (threadCount);
+  NULL_CHECK (threads);
+  
+  using namespace java::lang;
+  Thread *thr = Thread::currentThread ();
+  
+  ThreadGroup *thrGrp = thr->getThreadGroup ();
+  ThreadGroup *parent = thrGrp->getParent ();
+  
+  //get the root thread group
+  while (parent != NULL)
+    {
+      thrGrp = parent;
+      parent = thrGrp->getParent ();
+    }
+  
+  jint estimate = thrGrp->activeCount ();
+  
+  JArray<Thread *> *thrArray;
 
+  //allocate some extra space since threads can be created between calls
+  try
+    { 
+      thrArray = (JArray<Thread *> *) JvNewObjectArray ((estimate * 2),
+                  &Thread::class$, NULL);
+    }
+  catch (java::lang::OutOfMemoryError *err)
+    {
+      return JVMTI_ERROR_OUT_OF_MEMORY;
+    }
+   
+  (*threadCount) = thrGrp->enumerate (thrArray);
+  
+  jvmtiError ret
+    = env->Allocate ((jlong) ((*threadCount) * sizeof (jthread)),
+                     reinterpret_cast<unsigned char **> (threads));
+
+  if (ret != JVMTI_ERROR_NONE)
+    return ret;
+  
+  //now transfer the threads to the result array
+  jthread *tArrPtr = (*threads);
+  jthread *tmpArr = (jthread *) elements (thrArray);
+
+  memcpy (tArrPtr, tmpArr, (*threadCount));
+  
+  return JVMTI_ERROR_NONE;
+}
+
 static jvmtiError JNICALL
 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
 {
@@ -1187,7 +1243,7 @@
   RESERVED,			// reserved1
   _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
   RESERVED,			// reserved3
-  UNIMPLEMENTED,		// GetAllThreads
+  _Jv_JVMTI_GetAllThreads,		// GetAllThreads
   _Jv_JVMTI_SuspendThread,	// SuspendThread
   _Jv_JVMTI_ResumeThread,	// ResumeThread
   UNIMPLEMENTED,		// StopThread

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-10-05 13:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-27 15:29 [JVMTI] RFA: Implement GetAllThreads Kyle Galloway
2006-10-05 13:46 ` Kyle Galloway

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).