This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[JVMTI] RFA: Implement GetAllThreads
- From: Kyle Galloway <kgallowa at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: Wed, 27 Sep 2006 11:29:32 -0400
- Subject: [JVMTI] RFA: Implement GetAllThreads
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.
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));
+}