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 + +#include +#include +#include + +#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 (&env), JVMTI_VERSION_1_0); + jthread *threads; + jint threadCount; + env->GetAllThreads (&threadCount, &threads); + print_threads (threads, threadCount); + env->Deallocate (reinterpret_cast (threads)); +} Index: libjava/jvmti.cc =================================================================== --- libjava/jvmti.cc (revision 117434) +++ libjava/jvmti.cc (working copy) @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -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 *thrArray; + //allocate some extra space since threads can be created between calls + try + { + thrArray = (JArray *) 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 (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