* 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.
#include "threads/lock.hpp"
#include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
#include "toolbox/logging.hpp"
#include "toolbox/list.hpp"
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;
}
// 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);
}
}
+/**
+ * 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.
*
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();
#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). */
#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);