* src/threads/threadlist.hpp (ThreadList::get_active_threads): Added.
authorMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 17 Dec 2008 18:26:38 +0000 (19:26 +0100)
committerMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 17 Dec 2008 18:26:38 +0000 (19:26 +0100)
* src/threads/threadlist.cpp: Likewise.
* src/native/vm/openjdk/jvm.cpp (JVM_GetAllThreads): Implemented.
(JVM_DumpThreads): Fixed if stacktrace is not available.
* src/vm/jit/stacktrace.cpp (stacktrace_get_StackTraceElements): Return empty
array if stacktrace is not available.

src/native/vm/openjdk/jvm.cpp
src/threads/threadlist.cpp
src/threads/threadlist.hpp
src/vm/jit/stacktrace.cpp

index 8bd45d0560d5d6a7d1e3b05707560ad57c848ef0..c137d35db0d9af992665e17d61502169f1e9d691 100644 (file)
@@ -64,6 +64,7 @@
 
 #include "threads/lock.hpp"
 #include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
 
 #include "toolbox/logging.hpp"
 #include "toolbox/list.hpp"
@@ -3192,9 +3193,31 @@ jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlon
 
 jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 {
-       log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+       // Get a list of all active threads.
+       list<threadobject*> active_threads;
+       ThreadList::get_active_threads(active_threads);
 
-       return NULL;
+       // Allocate array to hold the java.lang.Thread objects.
+       int32_t length = active_threads.size();
+       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_Thread);
+
+       if (oa == NULL)
+               return NULL;
+
+       // Iterate over all threads (which were active just a second ago).
+       int32_t index = 0;
+       for (List<threadobject*>::iterator it = active_threads.begin(); it != active_threads.end(); it++) {
+               threadobject* t = *it;
+
+               java_handle_t* h = thread_get_object(t);
+               assert(h != NULL);
+
+               array_objectarray_element_set(oa, index, h);
+
+               index++;
+       }
+
+       return oa;
 }
 
 
@@ -3240,12 +3263,12 @@ jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threa
                // Get stacktrace for given thread.
                stacktrace_t* st = stacktrace_get_of_thread(t);
 
-               if (st == NULL)
-                       continue;
-
                // Convert stacktrace into array of StackTraceElements.
                java_handle_objectarray_t* oa = stacktrace_get_StackTraceElements(st);
 
+               if (oa == NULL)
+                       return NULL;
+
                array_objectarray_element_set(oas, i, (java_handle_t*) oa);
        }
 
index 18720899ccb23d577cade9c0b2f17b7a60efc149..9284bdb8412cc58226563cbba8279a9e76b17ac1 100644 (file)
@@ -101,6 +101,26 @@ void ThreadList::dump_threads()
 }
 
 
+/**
+ * Fills the passed list with all currently active threads. Creating a copy
+ * of the thread list here, is the only way to ensure we do not end up in a
+ * dead-lock when iterating over the list.
+ *
+ * @param list list class to be filled
+ */
+void ThreadList::get_active_threads(list<threadobject*> &list)
+{
+       // Lock the thread lists.
+       lock();
+
+       // Use the assignment operator to create a copy of the thread list.
+       list = _active_thread_list;
+
+       // Unlock the thread lists.
+       unlock();
+}
+
+
 /**
  * Return a free thread object.
  *
index 2a9f2059c296ce538ca1e60be51fe0d01424ff15..4df7b93456df1d87f928b570658c0e350edafe25 100644 (file)
@@ -73,6 +73,7 @@ public:
        static inline void          add_to_active_thread_list(threadobject* t);
 
        static void                 dump_threads();
+       static void                 get_active_threads(list<threadobject*> &list);
        static inline threadobject* get_main_thread();
        static threadobject*        get_free_thread();
        static int32_t              get_free_thread_index();
index 6d8d51d0c4e39a76a3c0c782f95c77e087172dfd..8efa4b25bcfe75e72a730f6f78fbaae542274ab6 100644 (file)
@@ -685,6 +685,8 @@ java_handle_bytearray_t *stacktrace_get_current(void)
 #if defined(ENABLE_JAVASE)
 java_handle_t* stacktrace_get_StackTraceElement(stacktrace_t* st, int32_t index)
 {
+       assert(st != NULL);
+
        if ((index < 0) || (index >= st->length)) {
                /* XXX This should be an IndexOutOfBoundsException (check this
                   again). */
@@ -767,14 +769,18 @@ java_handle_t* stacktrace_get_StackTraceElement(stacktrace_t* st, int32_t index)
 #if defined(ENABLE_JAVASE)
 java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t* st)
 {
+       // Get length of stacktrace. If stacktrace is not available
+       // an empty array should be returned.
+       int32_t length = (st != NULL) ? st->length : 0;
+
        // Create the stacktrace element array.
-       java_handle_objectarray_t* oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
+       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_StackTraceElement);
 
        if (oa == NULL)
                return NULL;
 
        // Iterate over all stacktrace elements.
-       for (int i = 0; i < st->length; i++) {
+       for (int i = 0; i < length; i++) {
 
                // Get stacktrace element at current index.
                java_handle_t* h = stacktrace_get_StackTraceElement(st, i);