#include "mm/memory.h"
+#if defined(ENABLE_GC_BOEHM)
+/* We need to include Boehm's gc.h here for GC_register_my_thread and
+ friends. */
+# include "mm/boehm-gc/include/gc.h"
+#endif
+
#include "native/jni.h"
#include "native/llni.h"
#include "native/native.h"
# include "native/include/java_lang_ThreadGroup.h"
#endif
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
# include "native/include/java_lang_VMThread.h"
#endif
-#include "threads/critical.h"
#include "threads/lock-common.h"
#include "threads/threadlist.h"
#include "threads/thread.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/stringlocal.h"
-#include "vm/vm.h"
+#include "vm/vm.hpp"
-#include "vm/jit/stacktrace.h"
+#include "vm/jit/stacktrace.hpp"
#include "vmcore/class.h"
+#include "vmcore/globals.hpp"
#include "vmcore/method.h"
#include "vmcore/options.h"
/* global variables ***********************************************************/
-methodinfo *thread_method_init;
-
-#if defined(ENABLE_JAVASE)
-static java_lang_ThreadGroup *threadgroup_system;
-static java_lang_ThreadGroup *threadgroup_main;
-#endif
+static methodinfo *thread_method_init;
+static java_handle_t *threadgroup_system;
+static java_handle_t *threadgroup_main;
#if defined(__LINUX__)
/* XXX Remove for exact-GC. */
/* static functions ***********************************************************/
-static void thread_create_initial_threadgroups(void);
-static void thread_create_initial_thread(void);
+static void thread_create_initial_threadgroups(void);
+static void thread_create_initial_thread(void);
+static threadobject *thread_new(void);
/* threads_preinit *************************************************************
threads_impl_preinit();
- /* create internal thread data-structure for the main thread */
+ /* Create internal thread data-structure for the main thread. */
+
+ mainthread = thread_new();
- mainthread = threads_thread_new();
+ /* The main thread should always have index 1. */
+
+ if (mainthread->index != 1)
+ vm_abort("threads_preinit: main thread index not 1: %d != 1",
+ mainthread->index);
/* thread is a Java thread and running */
/* Cache the java.lang.Thread initialization method. */
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
thread_method_init =
class_resolveclassmethod(class_java_lang_Thread,
class_java_lang_Thread,
true);
-#elif defined(WITH_CLASSPATH_SUN)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
thread_method_init =
class_resolveclassmethod(class_java_lang_Thread,
class_java_lang_Thread,
true);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
thread_method_init =
class_resolveclassmethod(class_java_lang_Thread,
/* thread_create_object ********************************************************
+ Create a Java thread object for the given thread data-structure,
+ initializes it and adds the thread to the threadgroup.
+
+ ARGUMENTS:
+
+ t ....... thread
+ name .... thread name
+ group ... threadgroup
+
+ RETURN:
+
*******************************************************************************/
-static void thread_create_object(void)
+static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
{
-#warning refactor thread_create_initial_thread and threads_attach_current_thread, maybe threads_thread_start_internal
+ java_handle_t *o;
+ java_lang_Thread *to;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+ java_lang_VMThread *vmto;
+ classinfo *c;
+ methodinfo *m;
+ bool isdaemon;
+#endif
+
+ /* Create a java.lang.Thread Java object. */
+
+ o = builtin_new(class_java_lang_Thread);
+
+ if (o == NULL)
+ return false;
+
+ to = (java_lang_Thread *) o;
+
+ /* Set the Java object in the thread data-structure. This
+ indicates that the thread is attached to the VM. */
+
+ thread_set_object(t, (java_handle_t *) to);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+ /* Create a java.lang.VMThread Java object. */
+
+ vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+
+ if (vmto == NULL)
+ return false;
+
+ /* Set the Java thread object in the Java VM-thread object. */
+
+ LLNI_field_set_ref(vmto, thread, to);
+
+ /* Set the thread data-structure in the Java VM-thread object. */
+
+ LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
+
+ /* Call:
+ java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
+
+ isdaemon = thread_is_daemon(t);
+
+ (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
+ isdaemon);
+
+ if (exceptions_get_exception())
+ return false;
+
+ /* Set the threadgroup in the Java thread object. */
+
+ LLNI_field_set_ref(to, group, (java_lang_ThreadGroup *) group);
+
+ /* Add thread to the threadgroup. */
+
+ LLNI_class_get(group, c);
+
+ m = class_resolveclassmethod(c,
+ utf_addThread,
+ utf_java_lang_Thread__V,
+ class_java_lang_ThreadGroup,
+ true);
+
+ if (m == NULL)
+ return false;
+
+ (void) vm_call_method(m, group, to);
+
+ if (exceptions_get_exception())
+ return false;
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+ /* OpenJDK's java.lang.Thread does not have a VMThread field in
+ the class. Nothing to do here. */
+
+ /* Set the priority. java.lang.Thread.<init> requires it because
+ it sets the priority of the current thread to the parent's one
+ (which is the current thread in this case). */
+
+ LLNI_field_set_val(to, priority, NORM_PRIORITY);
+
+ /* Call:
+ java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
+
+ (void) vm_call_method(thread_method_init, o, group, name);
+
+ if (exceptions_get_exception())
+ return false;
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+ /* Set the thread data-structure in the Java thread object. */
+
+ LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
+
+ /* Call: public Thread(Ljava/lang/String;)V */
+
+ (void) vm_call_method(thread_method_init, o, name);
+
+ if (exceptions_get_exception())
+ return false;
+
+#else
+# error unknown classpath configuration
+#endif
+
+ return true;
}
static void thread_create_initial_threadgroups(void)
{
#if defined(ENABLE_JAVASE)
-# if defined(WITH_CLASSPATH_GNU)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
/* Allocate and initialize the main thread group. */
- threadgroup_main = (java_lang_ThreadGroup *)
- native_new_and_init(class_java_lang_ThreadGroup);
+ threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
if (threadgroup_main == NULL)
vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
threadgroup_system = threadgroup_main;
-# elif defined(WITH_CLASSPATH_SUN)
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
java_handle_t *name;
methodinfo *m;
- java_handle_t *o;
/* Allocate and initialize the system thread group. */
- threadgroup_system = (java_lang_ThreadGroup *)
- native_new_and_init(class_java_lang_ThreadGroup);
+ threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
if (threadgroup_system == NULL)
vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
/* Allocate and initialize the main thread group. */
- threadgroup_main =
- (java_lang_ThreadGroup *) builtin_new(class_java_lang_ThreadGroup);
+ threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
if (threadgroup_main == NULL)
vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
if (m == NULL)
vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
- o = (java_handle_t *) threadgroup_main;
-
- (void) vm_call_method(m, o, threadgroup_system, name);
+ (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
if (exceptions_get_exception())
vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
static void thread_create_initial_thread(void)
{
- threadobject *mainthread;
- java_handle_t *name;
- java_lang_Thread *to; /* java.lang.Thread object */
- java_handle_t *o;
-
-#if defined(WITH_CLASSPATH_GNU)
- java_lang_VMThread *vmto; /* java.lang.VMThread object */
- methodinfo *m;
-#endif
+ threadobject *t;
+ java_handle_t *name;
/* Get the main-thread (NOTE: The main thread is always the first
thread in the list). */
- mainthread = threadlist_first();
-
- /* Create a java.lang.Thread object for the main thread. */
+ t = threadlist_first();
- to = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-
- if (to == NULL)
- vm_abort("threads_init: failed to allocate java.lang.Thread object");
-
- /* set the object in the internal data structure */
+ /* The thread name. */
- threads_thread_set_object(mainthread, (java_handle_t *) to);
+ name = javastring_new(utf_main);
#if defined(ENABLE_INTRP)
/* create interpreter stack */
}
#endif
- name = javastring_new(utf_main);
-
-#if defined(WITH_CLASSPATH_GNU)
- /* Create a java.lang.VMThread for the main thread. */
-
- vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
- if (vmto == NULL)
- vm_abort("threads_init: failed to allocate java.lang.VMThread object");
-
- /* Set the thread. */
-
- LLNI_field_set_ref(vmto, thread, to);
- LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) mainthread);
-
- /* Set the thread group. */
-
- LLNI_field_set_ref(to, group, threadgroup_main);
-
- /* Call:
- java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
-
- o = (java_handle_t *) to;
-
- (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
- false);
-
- if (exceptions_get_exception())
- vm_abort("threads_init: exception while initializing main thread");
-
- /* Add main thread to main threadgroup. */
-
- m = class_resolveclassmethod(class_java_lang_ThreadGroup,
- utf_addThread,
- utf_java_lang_Thread__V,
- class_java_lang_ThreadGroup,
- true);
-
- o = (java_handle_t *) threadgroup_main;
-
- (void) vm_call_method(m, o, to);
-
- if (exceptions_get_exception())
- vm_abort("threads_init: exception while adding main thread to main threadgroup");
-
-#elif defined(WITH_CLASSPATH_SUN)
-
- /* Set the priority. java.lang.Thread.<init> requires it because
- it sets the priority of the current thread to the parent's one
- (which is the current thread in this case). */
-
- LLNI_field_set_val(to, priority, NORM_PRIORITY);
-
- /* Call:
- java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
-
- o = (java_object_t *) to;
-
- (void) vm_call_method(thread_method_init, o, threadgroup_main, name);
-
- if (exceptions_get_exception())
- vm_abort("threads_init: exception while initializing main thread");
-
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-
- /* Set the thread. */
-
- LLNI_field_set_val(to, vm_thread, (java_lang_Object *) mainthread);
-
- /* Call public Thread(String name). */
-
- o = (java_handle_t *) to;
-
- (void) vm_call_method(thread_method_init, o, name);
-
- if (exceptions_get_exception())
- vm_abort("threads_init: exception while initializing main thread");
+ /* Create the Java thread object. */
-#else
-# error unknown classpath configuration
-#endif
+ if (!thread_create_object(t, name, threadgroup_main))
+ vm_abort("thread_create_initial_thread: failed to create Java object");
/* Initialize the implementation specific bits. */
threads_impl_init();
- DEBUGTHREADS("starting (main)", mainthread);
+ DEBUGTHREADS("starting (main)", t);
}
-/* threads_thread_new **********************************************************
+/* thread_new ******************************************************************
Allocates and initializes an internal thread data-structure and
adds it to the threads list.
*******************************************************************************/
-threadobject *threads_thread_new(void)
+static threadobject *thread_new(void)
{
- int32_t index;
- threadobject *t;
+ int32_t index;
+ threadobject *t;
/* Lock the thread lists */
}
-/* threads_thread_free *********************************************************
+/* thread_free *****************************************************************
Remove the thread from the threads-list and free the internal
thread data structure. The thread index is added to the
thread-index free-list.
IN:
- t....thread data structure
+ t ... thread data structure
*******************************************************************************/
-void threads_thread_free(threadobject *t)
+void thread_free(threadobject *t)
{
/* Lock the thread lists. */
/* Set the reference to the Java object to NULL. */
- threads_thread_set_object(t, NULL);
+ thread_set_object(t, NULL);
/* Add the thread data structure to the free list. */
bool threads_thread_start_internal(utf *name, functionptr f)
{
- threadobject *t;
- java_lang_Thread *to; /* java.lang.Thread object */
-#if defined(WITH_CLASSPATH_GNU)
- java_lang_VMThread *vmto; /* java.lang.VMThread object */
-#endif
+ threadobject *t;
/* Enter the join-mutex, so if the main-thread is currently
waiting to join all threads, the number of non-daemon threads
threads_mutex_join_lock();
- /* create internal thread data-structure */
+ /* Create internal thread data-structure. */
- t = threads_thread_new();
+ t = thread_new();
t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
/* Create the Java thread object. */
- to = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
-
- /* XXX memory leak!!! */
- if (to == NULL)
- return false;
-
-#if defined(WITH_CLASSPATH_GNU)
-
- vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
-
- /* XXX memory leak!!! */
- if (vmto == NULL)
+ if (!thread_create_object(t, javastring_new(name), threadgroup_system))
return false;
- LLNI_field_set_ref(vmto, thread, to);
- LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
-
- LLNI_field_set_ref(to, vmThread, vmto);
-
-#elif defined(WITH_CLASSPATH_SUN)
-
- /* Nothing to do. */
-
-#elif defined(WITH_CLASSPATH_CLDC1_1)
-
- LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
-
-#else
-# error unknown classpath configuration
-#endif
-
- threads_thread_set_object(t, (java_handle_t *) to);
-
- /* Set java.lang.Thread fields. */
-
-#if defined(WITH_CLASSPATH_GNU)
-
- LLNI_field_set_ref(to, name, (java_lang_String *) javastring_new(name));
-
-#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
-
- /* FIXME: In cldc the name is a char[] */
-/* LLNI_field_set_ref(to, name, (java_chararray *) name); */
- LLNI_field_set_ref(to, name, NULL);
-
-#else
-# error unknow classpath configuration
-#endif
-
- LLNI_field_set_val(to, priority, NORM_PRIORITY);
-
-#if defined(ENABLE_JAVASE)
- LLNI_field_set_val(to, daemon, true);
- LLNI_field_set_ref(to, group, threadgroup_system);
-#endif
-
/* Start the thread. */
threads_impl_thread_start(t, f);
{
java_lang_Thread *to;
threadobject *t;
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
java_lang_VMThread *vmto;
#endif
threads_mutex_join_lock();
- /* create internal thread data-structure */
+ /* Create internal thread data-structure. */
- t = threads_thread_new();
+ t = thread_new();
/* this is a normal Java thread */
/* Link the two objects together. */
- threads_thread_set_object(t, object);
+ thread_set_object(t, object);
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
/* Get the java.lang.VMThread object and do some sanity checks. */
LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
-#elif defined(WITH_CLASSPATH_SUN)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
/* Nothing to do. */
-#elif defined(WITH_CLASSPATH_CLDC1_1)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
}
-/* threads_attach_current_thread ***********************************************
-
- Attaches the current thread to the VM. Used in JNI.
-
-*******************************************************************************/
-
-bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
+/**
+ * Attaches the current thread to the VM.
+ *
+ * @param vm_aargs Attach arguments.
+ * @param isdaemon true if the attached thread should be a daemon
+ * thread.
+ *
+ * @return true on success, false otherwise.
+ */
+bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
{
- bool result;
- threadobject *t;
- utf *u;
- java_handle_t *s;
- java_handle_t *o;
- java_lang_Thread *to;
-
-#if defined(ENABLE_JAVASE)
- java_lang_ThreadGroup *group;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
- java_lang_VMThread *vmt;
- classinfo *c;
- methodinfo *m;
-#endif
+ bool result;
+ threadobject *t;
+ utf *u;
+ java_handle_t *name;
+ java_handle_t *group;
/* If the current thread has already been attached, this operation
is a no-op. */
/* Create internal thread data structure. */
- t = threads_thread_new();
+ t = thread_new();
/* Thread is a Java thread and running. */
if (isdaemon)
t->flags |= THREAD_FLAG_DAEMON;
+ /* Store the internal thread data-structure in the TSD. */
+
+ thread_set_current(t);
+
/* The thread is flagged and (non-)daemon thread, we can leave the
mutex. */
threads_mutex_join_unlock();
- /* create a java.lang.Thread object */
+ DEBUGTHREADS("attaching", t);
- to = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+ /* Get the thread name. */
- /* XXX memory leak!!! */
- if (to == NULL)
- return false;
+ if (vm_aargs != NULL) {
+ u = utf_new_char(vm_aargs->name);
+ }
+ else {
+ u = utf_null;
+ }
- threads_thread_set_object(t, (java_handle_t *) to);
+ name = javastring_new(u);
- /* Thread is completely initialized. */
+#if defined(ENABLE_JAVASE)
+ /* Get the threadgroup. */
- threads_thread_state_runnable(t);
+ if (vm_aargs != NULL)
+ group = (java_handle_t *) vm_aargs->group;
+ else
+ group = NULL;
- DEBUGTHREADS("attaching", t);
+ /* If no threadgroup was given, use the main threadgroup. */
+
+ if (group == NULL)
+ group = threadgroup_main;
+#endif
#if defined(ENABLE_INTRP)
/* create interpreter stack */
}
#endif
-#if defined(WITH_CLASSPATH_GNU)
-
- /* create a java.lang.VMThread object */
-
- vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+ /* Create the Java thread object. */
- /* XXX memory leak!!! */
- if (vmt == NULL)
+ if (!thread_create_object(t, name, group))
return false;
- /* set the thread */
-
- LLNI_field_set_ref(vmt, thread, to);
- LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) t);
+ /* The thread is completely initialized. */
-#elif defined(WITH_CLASSPATH_SUN)
+ thread_set_state_runnable(t);
- /* Sun's java.lang.Thread does not have a VMThread field in the
- class. Nothing to do here. */
+ return true;
+}
-#elif defined(WITH_CLASSPATH_CLDC1_1)
- LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
+/**
+ * Attaches the current external thread to the VM. This function is
+ * called by JNI's AttachCurrentThread.
+ *
+ * @param vm_aargs Attach arguments.
+ * @param isdaemon true if the attached thread should be a daemon
+ * thread.
+ *
+ * @return true on success, false otherwise.
+ */
+bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
+{
+ int result;
-#else
-# error unknown classpath configuration
+#if defined(ENABLE_GC_BOEHM)
+ struct GC_stack_base sb;
#endif
- /* Get the thread name. */
+#if defined(ENABLE_GC_BOEHM)
+ /* Register the thread with Boehm-GC. This must happen before the
+ thread allocates any memory from the GC heap.*/
- if (vm_aargs != NULL) {
- u = utf_new_char(vm_aargs->name);
- }
- else {
- u = utf_null;
- }
+ result = GC_get_stack_base(&sb);
-#if defined(ENABLE_JAVASE)
- /* Get the threadgroup. If no threadgroup was given, use the main
- threadgroup. */
+ if (result != GC_SUCCESS)
+ vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
- if (vm_aargs != NULL)
- group = (java_lang_ThreadGroup *) vm_aargs->group;
-
- if (group == NULL)
- group = threadgroup_main;
+ GC_register_my_thread(&sb);
#endif
- /* The thread name. */
+ result = thread_attach_current_thread(vm_aargs, isdaemon);
- s = javastring_new(u);
+ if (result == false) {
+#if defined(ENABLE_GC_BOEHM)
+ /* Unregister the thread. */
- /* for convenience */
+ GC_unregister_my_thread();
+#endif
- o = (java_handle_t *) to;
+ return false;
+ }
-#if defined(WITH_CLASSPATH_GNU)
+ return true;
+}
- (void) vm_call_method(thread_method_init, o, vmt, s, NORM_PRIORITY,
- isdaemon);
- if (exceptions_get_exception())
+/**
+ * Detaches the current external thread from the VM. This function is
+ * called by JNI's DetachCurrentThread.
+ *
+ * @return true on success, false otherwise.
+ */
+bool thread_detach_current_external_thread(void)
+{
+ int result;
+
+ result = thread_detach_current_thread();
+
+ if (result == false)
return false;
- /* Store the threadgroup in the Java object. */
+#if defined(ENABLE_GC_BOEHM)
+ /* Unregister the thread with Boehm-GC. This must happen after
+ the thread allocates any memory from the GC heap. */
- LLNI_field_set_ref(to, group, group);
+ /* Don't detach the main thread. This is a workaround for
+ OpenJDK's java binary. */
+ if (thread_get_current()->index != 1)
+ GC_unregister_my_thread();
+#endif
- /* Add thread to given threadgroup. */
+ return true;
+}
- LLNI_class_get(group, c);
- m = class_resolveclassmethod(c,
- utf_addThread,
- utf_java_lang_Thread__V,
- class_java_lang_ThreadGroup,
- true);
+/* thread_fprint_name **********************************************************
- if (m == NULL)
- return false;
+ Print the name of the given thread to the given stream.
- o = (java_handle_t *) group;
+ ARGUMENTS:
+ t ........ thread data-structure
+ stream ... stream to print to
- (void) vm_call_method(m, o, to);
+*******************************************************************************/
- if (exceptions_get_exception())
- return false;
+void thread_fprint_name(threadobject *t, FILE *stream)
+{
+ java_lang_Thread *to;
-#elif defined(WITH_CLASSPATH_SUN)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+ java_lang_String *name;
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+ java_chararray_t *name;
+#endif
- /* Set the priority. java.lang.Thread.<init> requires it because
- it sets the priority of the current thread to the parent's one
- (which is the current thread in this case). */
+ to = (java_lang_Thread *) thread_get_object(t);
- LLNI_field_set_val(to, priority, NORM_PRIORITY);
+ if (to == NULL)
+ vm_abort("");
- (void) vm_call_method(thread_method_init, o, group, s);
+ LLNI_field_get_ref(to, name, name);
- if (exceptions_get_exception())
- return false;
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-#elif defined(WITH_CLASSPATH_CLDC1_1)
+ javastring_fprint((java_handle_t *) name, stream);
- (void) vm_call_method(thread_method_init, o, s);
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
- if (exceptions_get_exception())
- return false;
+ /* FIXME: In OpenJDK and CLDC the name is a char[]. */
+ /* FIXME This prints to stdout. */
+ utf_display_printable_ascii(utf_null);
#else
# error unknown classpath configuration
#endif
-
- return true;
}
-/* threads_thread_print_info ***************************************************
+/* thread_print_info ***********************************************************
Print information of the passed thread.
-
+
+ ARGUMENTS:
+ t ... thread data-structure.
+
*******************************************************************************/
-void threads_thread_print_info(threadobject *t)
+void thread_print_info(threadobject *t)
{
- java_lang_Thread *object;
-#if defined(WITH_CLASSPATH_GNU)
- java_lang_String *namestring;
-#endif
- utf *name;
-
- assert(t->state != THREAD_STATE_NEW);
+ java_lang_Thread *to;
+ int state;
- /* the thread may be currently in initalization, don't print it */
+ /* If the thread is currently in initalization, don't print it. */
- object = (java_lang_Thread *) threads_thread_get_object(t);
+ to = (java_lang_Thread *) thread_get_object(t);
- if (object != NULL) {
- /* get thread name */
+ /* Print as much as we can when we are in state NEW. */
-#if defined(WITH_CLASSPATH_GNU)
- LLNI_field_get_ref(object, name, namestring);
- name = javastring_toutf((java_handle_t *) namestring, false);
-#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
- /* FIXME: In cldc the name is a char[] */
-/* name = object->name; */
- name = utf_null;
-#else
-# error unknown classpath configuration
-#endif
+ if (to != NULL) {
+ /* Print thread name. */
printf("\"");
- utf_display_printable_ascii(name);
+ thread_fprint_name(t, stdout);
printf("\"");
+ }
+ else {
+ }
- if (t->flags & THREAD_FLAG_DAEMON)
- printf(" daemon");
+ if (thread_is_daemon(t))
+ printf(" daemon");
- printf(" prio=%d", LLNI_field_direct(object, priority));
+ if (to != NULL) {
+ printf(" prio=%d", LLNI_field_direct(to, priority));
+ }
#if SIZEOF_VOID_P == 8
- printf(" t=0x%016lx tid=0x%016lx (%ld)",
- (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
+ printf(" t=0x%016lx tid=0x%016lx (%ld)",
+ (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
#else
- printf(" t=0x%08x tid=0x%08x (%d)",
- (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
+ printf(" t=0x%08x tid=0x%08x (%d)",
+ (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
#endif
- printf(" index=%d", t->index);
+ printf(" index=%d", t->index);
- /* print thread state */
+ /* Print thread state. */
- switch (t->state) {
- case THREAD_STATE_NEW:
- printf(" new");
- break;
- case THREAD_STATE_RUNNABLE:
- printf(" runnable");
- break;
- case THREAD_STATE_BLOCKED:
- printf(" blocked");
- break;
- case THREAD_STATE_WAITING:
- printf(" waiting");
- break;
- case THREAD_STATE_TIMED_WAITING:
- printf(" waiting on condition");
- break;
- case THREAD_STATE_TERMINATED:
- printf(" terminated");
- break;
- default:
- vm_abort("threads_thread_print_info: unknown thread state %d",
- t->state);
- }
+ state = cacaothread_get_state(t);
+
+ switch (state) {
+ case THREAD_STATE_NEW:
+ printf(" new");
+ break;
+ case THREAD_STATE_RUNNABLE:
+ printf(" runnable");
+ break;
+ case THREAD_STATE_BLOCKED:
+ printf(" blocked");
+ break;
+ case THREAD_STATE_WAITING:
+ printf(" waiting");
+ break;
+ case THREAD_STATE_TIMED_WAITING:
+ printf(" waiting on condition");
+ break;
+ case THREAD_STATE_TERMINATED:
+ printf(" terminated");
+ break;
+ default:
+ vm_abort("thread_print_info: unknown thread state %d", state);
}
}
}
-/* threads_thread_state_runnable ***********************************************
+/* thread_set_state_runnable ***************************************************
Set the current state of the given thread to THREAD_STATE_RUNNABLE.
*******************************************************************************/
-void threads_thread_state_runnable(threadobject *t)
+void thread_set_state_runnable(threadobject *t)
{
/* Set the state inside a lock. */
threadlist_lock();
- if (t->state != THREAD_STATE_TERMINATED)
+ if (t->state != THREAD_STATE_TERMINATED) {
t->state = THREAD_STATE_RUNNABLE;
- DEBUGTHREADS("is RUNNABLE", t);
+ DEBUGTHREADS("is RUNNABLE", t);
+ }
threadlist_unlock();
}
-/* threads_thread_state_waiting ************************************************
+/* thread_set_state_waiting ****************************************************
Set the current state of the given thread to THREAD_STATE_WAITING.
*******************************************************************************/
-void threads_thread_state_waiting(threadobject *t)
+void thread_set_state_waiting(threadobject *t)
{
/* Set the state inside a lock. */
threadlist_lock();
- if (t->state != THREAD_STATE_TERMINATED)
+ if (t->state != THREAD_STATE_TERMINATED) {
t->state = THREAD_STATE_WAITING;
- DEBUGTHREADS("is WAITING", t);
+ DEBUGTHREADS("is WAITING", t);
+ }
threadlist_unlock();
}
-/* threads_thread_state_timed_waiting ******************************************
+/* thread_set_state_timed_waiting **********************************************
Set the current state of the given thread to
THREAD_STATE_TIMED_WAITING.
*******************************************************************************/
-void threads_thread_state_timed_waiting(threadobject *t)
+void thread_set_state_timed_waiting(threadobject *t)
{
/* Set the state inside a lock. */
threadlist_lock();
- if (t->state != THREAD_STATE_TERMINATED)
+ if (t->state != THREAD_STATE_TERMINATED) {
t->state = THREAD_STATE_TIMED_WAITING;
- DEBUGTHREADS("is TIMED_WAITING", t);
+ DEBUGTHREADS("is TIMED_WAITING", t);
+ }
threadlist_unlock();
}
-/* threads_thread_state_terminated *********************************************
+/* thread_set_state_terminated *************************************************
Set the current state of the given thread to
THREAD_STATE_TERMINATED.
*******************************************************************************/
-void threads_thread_state_terminated(threadobject *t)
+void thread_set_state_terminated(threadobject *t)
{
- /* set the state in the lock */
+ /* Set the state inside a lock. */
threadlist_lock();
}
-/* threads_thread_get_state ****************************************************
-
- Returns the current state of the given thread.
-
-*******************************************************************************/
-
-utf *threads_thread_get_state(threadobject *t)
-{
- utf *u;
-
- switch (t->state) {
- case THREAD_STATE_NEW:
- u = utf_new_char("NEW");
- break;
- case THREAD_STATE_RUNNABLE:
- u = utf_new_char("RUNNABLE");
- break;
- case THREAD_STATE_BLOCKED:
- u = utf_new_char("BLOCKED");
- break;
- case THREAD_STATE_WAITING:
- u = utf_new_char("WAITING");
- break;
- case THREAD_STATE_TIMED_WAITING:
- u = utf_new_char("TIMED_WAITING");
- break;
- case THREAD_STATE_TERMINATED:
- u = utf_new_char("TERMINATED");
- break;
- default:
- vm_abort("threads_get_state: unknown thread state %d", t->state);
-
- /* keep compiler happy */
-
- u = NULL;
- }
-
- return u;
-}
-
-
/* thread_get_thread **********************************************************
Return the thread data structure of the given Java thread object.
threadobject *thread_get_thread(java_handle_t *h)
{
threadobject *t;
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
java_lang_VMThread *vmto;
java_lang_Object *to;
#endif
-#if defined(WITH_CLASSPATH_SUN)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
bool equal;
#endif
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
vmto = (java_lang_VMThread *) h;
t = (threadobject *) to;
-#elif defined(WITH_CLASSPATH_SUN)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
/* XXX This is just a quick hack. */
threadlist_unlock();
-#elif defined(WITH_CLASSPATH_CLDC1_1)
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
log_println("threads_get_thread: IMPLEMENT ME!");
bool threads_thread_is_alive(threadobject *t)
{
- switch (t->state) {
+ int state;
+
+ state = cacaothread_get_state(t);
+
+ switch (state) {
case THREAD_STATE_NEW:
case THREAD_STATE_TERMINATED:
return false;
return true;
default:
- vm_abort("threads_thread_is_alive: unknown thread state %d", t->state);
+ vm_abort("threads_thread_is_alive: unknown thread state %d", state);
}
/* keep compiler happy */
/* Print thread info. */
printf("\n");
- threads_thread_print_info(t);
+ thread_print_info(t);
printf("\n");
/* Print trace of thread. */
- threads_thread_print_stacktrace(t);
+ stacktrace_print_of_thread(t);
#if defined(ENABLE_GC_CACAO)
/* Resume the thread. */
}
-/* threads_thread_print_stacktrace *********************************************
-
- Print the current stacktrace of the given thread.
-
-*******************************************************************************/
-
-void threads_thread_print_stacktrace(threadobject *thread)
-{
- stackframeinfo_t *sfi;
- java_handle_bytearray_t *ba;
- stacktrace_t *st;
-
- /* Build a stacktrace for the passed thread. */
-
- sfi = thread->_stackframeinfo;
- ba = stacktrace_get(sfi);
-
- if (ba != NULL) {
- /* We need a critical section here as we use the byte-array
- data pointer directly. */
-
- LLNI_CRITICAL_START;
-
- st = (stacktrace_t *) LLNI_array_data(ba);
-
- /* Print stacktrace. */
-
- stacktrace_print(st);
-
- LLNI_CRITICAL_END;
- }
- else {
- puts("\t<<No stacktrace available>>");
- fflush(stdout);
- }
-}
-
-
-/* threads_print_stacktrace ****************************************************
-
- Print the current stacktrace of the current thread.
-
-*******************************************************************************/
-
-void threads_print_stacktrace(void)
-{
- threadobject *thread;
-
- thread = THREADOBJECT;
-
- threads_thread_print_stacktrace(thread);
-}
-
-
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where