diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 0c4b13ae6ec..af8efa01383 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,12 @@ +2007-01-16 Kyle Galloway + + * jvmti.cc (_Jv_JVMTI_GetAllThreads): New function. + * testsuite/libjava.jvmti/getallthreads.java: New test. + * testsuite/libjava.jvmti/natgetallthreads.cc: Ditto. + * testsuite/libjava.jvmti/getallthreads.out: Ditto. + * testsuite/libjava.jvmti/getallthreads.h: Ditto. + * testsuite/libjava.jvmti/getallthreads.jar: Ditto. + 2007-01-15 Keith Seitz * gnu/classpath/jdwp/natVMVirtualMachine.cc (suspendThread): Use diff --git a/libjava/jvmti.cc b/libjava/jvmti.cc index 8584c333d6d..b9646b7d101 100644 --- a/libjava/jvmti.cc +++ b/libjava/jvmti.cc @@ -28,7 +28,9 @@ details. */ #include #include #include +#include #include +#include #include #include #include @@ -196,6 +198,51 @@ _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread) return JVMTI_ERROR_NONE; } +jvmtiError +_Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt, + jthread **threads) +{ + REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); + NULL_CHECK (thread_cnt); + NULL_CHECK (threads); + + using namespace java::lang; + Thread *thr = Thread::currentThread (); + + ThreadGroup *root_grp = ThreadGroup::root; + jint estimate = root_grp->activeCount (); + + JArray *thr_arr; + + // Allocate some extra space since threads can be created between calls + try + { + thr_arr + = reinterpret_cast *> (JvNewObjectArray + ((estimate * 2), + &Thread::class$, NULL)); + } + catch (java::lang::OutOfMemoryError *err) + { + return JVMTI_ERROR_OUT_OF_MEMORY; + } + + *thread_cnt = root_grp->enumerate (thr_arr); + + jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)), + (unsigned char **) threads); + + if (jerr != JVMTI_ERROR_NONE) + return jerr; + + // Transfer the threads to the result array + jthread *tmp_arr = reinterpret_cast (elements (thr_arr)); + + memcpy ((*threads), tmp_arr, (*thread_cnt)); + + return JVMTI_ERROR_NONE; +} + static jvmtiError JNICALL _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name, jrawMonitorID *result) @@ -1362,7 +1409,7 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface = RESERVED, // reserved1 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode RESERVED, // reserved3 - UNIMPLEMENTED, // GetAllThreads + _Jv_JVMTI_GetAllThreads, // GetAllThreads _Jv_JVMTI_SuspendThread, // SuspendThread _Jv_JVMTI_ResumeThread, // ResumeThread UNIMPLEMENTED, // StopThread diff --git a/libjava/testsuite/libjava.jvmti/getallthreads.h b/libjava/testsuite/libjava.jvmti/getallthreads.h new file mode 100644 index 00000000000..7579892f3f7 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/getallthreads.h @@ -0,0 +1,35 @@ +// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*- + +#ifndef __getallthreads__ +#define __getallthreads__ + +#pragma interface + +#include +#include + +extern "Java" +{ + class getallthreads; +} + +class getallthreads : public ::java::lang::Thread +{ +public: + getallthreads (); + static void do_getallthreads_tests (); + virtual void run (); + virtual void natPlaceholder (); + virtual void natRunner (); + virtual void placeholder (); + virtual void runner (); + static void main (JArray< ::java::lang::String *> *); + static jint thread_num; + static ::java::util::ArrayList *threads; + jint __attribute__((aligned(__alignof__( ::java::lang::Thread )))) ex_frames; + jboolean done; + + static ::java::lang::Class class$; +}; + +#endif /* __getallthreads__ */ diff --git a/libjava/testsuite/libjava.jvmti/getallthreads.jar b/libjava/testsuite/libjava.jvmti/getallthreads.jar new file mode 100644 index 00000000000..3e59ccdc362 Binary files /dev/null and b/libjava/testsuite/libjava.jvmti/getallthreads.jar differ diff --git a/libjava/testsuite/libjava.jvmti/getallthreads.java b/libjava/testsuite/libjava.jvmti/getallthreads.java new file mode 100644 index 00000000000..00be3a75c00 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/getallthreads.java @@ -0,0 +1,80 @@ +// Test JVMTI GetAllThreads + +import java.util.ArrayList; + +public class getallthreads extends Thread +{ + public static int thread_num; + public static ArrayList threads; + + public int ex_frames; + public boolean done = false; + + public static native void do_getallthreads_tests (); + + public void run () + { + ex_frames = thread_num; + thread_num++; + + if (ex_frames > 0) + { + if ((ex_frames % 2) == 0) + placeholder (); + else + natPlaceholder (); + } + else + runner (); + } + + public native void natPlaceholder (); + public native void natRunner (); + + public void placeholder () + { + ex_frames--; + + if (ex_frames > 0) + { + if ((thread_num % 2) == 0) + placeholder (); + else + natPlaceholder (); + } + else + runner (); + } + + public void runner () + { + done = true; + while (done) + yield (); + } + + public static void main (String[] args) + { + System.out.println ("JVMTI GetAllThreads tests"); + threads = new ArrayList (20); + + getallthreads t; + + for (int i = 0; i < 20; i++) + { + t = new getallthreads (); + threads.add (t); + t.start (); + while (!t.done) + yield (); + } + + do_getallthreads_tests (); + + for (int i = 0; i < 20; i++) + { + t = (getallthreads) threads.get(i); + t.done = false; + } + } +} diff --git a/libjava/testsuite/libjava.jvmti/getallthreads.out b/libjava/testsuite/libjava.jvmti/getallthreads.out new file mode 100644 index 00000000000..8e05c4a4b62 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/getallthreads.out @@ -0,0 +1,23 @@ +JVMTI GetAllThreads tests +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 +Found thread 22 diff --git a/libjava/testsuite/libjava.jvmti/natgetallthreads.cc b/libjava/testsuite/libjava.jvmti/natgetallthreads.cc new file mode 100644 index 00000000000..9c4d69cde74 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/natgetallthreads.cc @@ -0,0 +1,55 @@ +#include + +#include +#include +#include + +#include "jvmti-int.h" +#include "getallthreads.h" + +void +getallthreads::natPlaceholder () +{ + ex_frames--; + + if (ex_frames > 0) + { + if ((getallthreads::thread_num % 2) == 0) + placeholder (); + else + natPlaceholder (); + } + else + natRunner (); +} + +void +getallthreads::natRunner () +{ + done = true; + while (done) + yield (); +} + +void +getallthreads::do_getallthreads_tests () +{ + jvmtiEnv *env; + JavaVM *vm = _Jv_GetJavaVM (); + vm->GetEnv (reinterpret_cast (&env), JVMTI_VERSION_1_0); + + jint num_threads; + jthread *thread_arr; + + jvmtiError jerr = env->GetAllThreads (&num_threads, &thread_arr); + if (jerr != JVMTI_ERROR_NONE) + { + printf ("Test Failed, JVMTI Error!\n"); + return; + } + env->Deallocate (reinterpret_cast (thread_arr)); + + for (int i = 0; i < num_threads; i++) + printf ("Found thread %d\n", i+1 ); +} +