* src/threads/thread.c: Moved to .cpp.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Tue, 22 Jul 2008 09:55:41 +0000 (11:55 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Tue, 22 Jul 2008 09:55:41 +0000 (11:55 +0200)
* src/threads/thread.h: Likewise.
* src/threads/thread.cpp: New file.
* src/threads/thread.hpp: Likewise.
* src/threads/Makefile.am (libthreads_la_SOURCES): Changed filenames.
* src/mm/cacao-gc/gc.c,
src/mm/cacao-gc/gc.h,
src/mm/cacao-gc/rootset.c,
src/mm/cacao-gc/rootset.h,
src/mm/codememory.c,
src/mm/dumpmemory.c,
src/mm/memory.c,
src/native/jni.cpp,
src/native/jvmti/cacaodbg.c,
src/native/jvmti/cacaodbg.h,
src/native/jvmti/jvmti.c,
src/native/llni.c,
src/native/llni.h,
src/native/localref.c,
src/native/vm/cldc1.1/java_lang_Thread.c,
src/native/vm/gnuclasspath/java_lang_VMThread.c,
src/native/vm/openjdk/jvm.c,
src/threads/Makefile.am,
src/threads/none/thread-none.c,
src/threads/posix/lock.c,
src/threads/posix/thread-posix.cpp,
src/threads/threadlist.c,
src/threads/threadlist.h,
src/toolbox/logging.c,
src/vm/builtin.c,
src/vm/exceptions.c,
src/vm/finalizer.c,
src/vm/jit/alpha/linux/md-os.c,
src/vm/jit/arm/linux/md-os.c,
src/vm/jit/codegen-common.c,
src/vm/jit/i386/darwin/md-os.c,
src/vm/jit/i386/linux/md-os.c,
src/vm/jit/i386/solaris/md-os.c,
src/vm/jit/inline/inline.c,
src/vm/jit/intrp/asmpart.c,
src/vm/jit/intrp/engine.c,
src/vm/jit/methodtree.c,
src/vm/jit/optimizing/profile.c,
src/vm/jit/optimizing/recompile.c,
src/vm/jit/powerpc/darwin/md-os.c,
src/vm/jit/powerpc/linux/md-os.c,
src/vm/jit/powerpc64/linux/md-os.c,
src/vm/jit/replace.c,
src/vm/jit/s390/md.c,
src/vm/jit/show.c,
src/vm/jit/stacktrace.cpp,
src/vm/jit/stacktrace.hpp,
src/vm/jit/trace.cpp,
src/vm/jit/x86_64/freebsd/md-os.c,
src/vm/jit/x86_64/linux/md-os.c,
src/vm/jit/x86_64/solaris/md-os.c,
src/vm/signal.c,
src/vm/vm.cpp: Changed include.

--HG--
rename : src/threads/thread.c => src/threads/thread.cpp
rename : src/threads/thread.h => src/threads/thread.hpp

57 files changed:
src/mm/cacao-gc/gc.c
src/mm/cacao-gc/gc.h
src/mm/cacao-gc/rootset.c
src/mm/cacao-gc/rootset.h
src/mm/codememory.c
src/mm/dumpmemory.c
src/mm/memory.c
src/native/jni.cpp
src/native/jvmti/cacaodbg.c
src/native/jvmti/cacaodbg.h
src/native/jvmti/jvmti.c
src/native/llni.c
src/native/llni.h
src/native/localref.c
src/native/vm/cldc1.1/java_lang_Thread.c
src/native/vm/gnuclasspath/java_lang_VMThread.c
src/native/vm/openjdk/jvm.c
src/threads/Makefile.am
src/threads/none/thread-none.c
src/threads/posix/lock.c
src/threads/posix/thread-posix.cpp
src/threads/thread.c [deleted file]
src/threads/thread.cpp [new file with mode: 0644]
src/threads/thread.h [deleted file]
src/threads/thread.hpp [new file with mode: 0644]
src/threads/threadlist.c
src/threads/threadlist.h
src/toolbox/logging.c
src/vm/builtin.c
src/vm/exceptions.c
src/vm/finalizer.c
src/vm/jit/alpha/linux/md-os.c
src/vm/jit/arm/linux/md-os.c
src/vm/jit/codegen-common.c
src/vm/jit/i386/darwin/md-os.c
src/vm/jit/i386/linux/md-os.c
src/vm/jit/i386/solaris/md-os.c
src/vm/jit/inline/inline.c
src/vm/jit/intrp/asmpart.c
src/vm/jit/intrp/engine.c
src/vm/jit/methodtree.c
src/vm/jit/optimizing/profile.c
src/vm/jit/optimizing/recompile.c
src/vm/jit/powerpc/darwin/md-os.c
src/vm/jit/powerpc/linux/md-os.c
src/vm/jit/powerpc64/linux/md-os.c
src/vm/jit/replace.c
src/vm/jit/s390/md.c
src/vm/jit/show.c
src/vm/jit/stacktrace.cpp
src/vm/jit/stacktrace.hpp
src/vm/jit/trace.cpp
src/vm/jit/x86_64/freebsd/md-os.c
src/vm/jit/x86_64/linux/md-os.c
src/vm/jit/x86_64/solaris/md-os.c
src/vm/signal.c
src/vm/vm.cpp

index 0f954b3bb2e6dfc6c7020112d60bdfbc59c6f948..cb8cdcc00d329e1a310bc7221f05a28fec074b9a 100644 (file)
@@ -31,7 +31,7 @@
 #include "vm/types.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "compact.h"
 #include "copy.h"
index 31060381d73868057a9a8dcbfb33960a0ee6cf40..952d6be3c6e0837af33a58a43ca0423bdd98e6ac 100644 (file)
@@ -35,7 +35,7 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/list.h"
 #include "vm/jit/replace.h"
index 4e3e9589901a1d4de9a5abce7c4d4fb124443e37..fe3253579640d3797d90d0761ed45946c3d9c869 100644 (file)
@@ -33,7 +33,7 @@
 #include "mm/memory.h"
 
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index e61315f555a6fae6bdd8955515b270bcd31c65fa..8c5c4980f9680c04df50f4df673c1ea4526055ba 100644 (file)
@@ -31,7 +31,7 @@ typedef struct rootset_t rootset_t;
 #include "config.h"
 #include "vm/types.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/jit/replace.h"
 #include "vmcore/method.h"
index 7d2fd89c867dfbda7c993c547ed614af1043c8fa..875557344e06a0b4fef168746610cf4409d3fa3b 100644 (file)
@@ -30,7 +30,7 @@
 #include <sys/mman.h> /* REMOVEME */
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "mm/codememory.h"
 #include "mm/memory.h"
index ca98e5e901eb89989b4ad3e3c81cc9c7c9d349bf..bf74e3f7ce3646c12d8811551a78f404ef5f06ef 100644 (file)
@@ -30,7 +30,7 @@
 #include "mm/dumpmemory.h"
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vmcore/options.h"
 
index 80951ee5e6e34f13bf88ea66b40586786d2385c9..ab24c1d17fee3de41c16627852c18279d884e936 100644 (file)
@@ -47,7 +47,7 @@
 #include "native/native.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index 9fe5703a8686a1e99187da22811bbbf07dfd7daf..e3d53e759dfd170c27234fb3396af83851e1786d 100644 (file)
@@ -96,7 +96,7 @@ struct java_lang_ClassLoader;
 #endif
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index 7c11aafe180eaf76d6677db0f2571b609d974467..8362c44e4a7af943a370ff2e60d265534cd6ea5e 100644 (file)
@@ -34,7 +34,7 @@
 #include "vm/stringlocal.h"
 #include "toolbox/logging.h"
 #include "threads/mutex.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include <sys/types.h>
 #include <unistd.h>
index 4b4a219eb7025cd7e2b4dc57d8f111821369e188..04abbd85c2a04d45fef38bc426c7a8557e85d100 100644 (file)
@@ -26,7 +26,7 @@
 #define _CACAODBG_H
 
 #include "threads/mutex.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 #include "native/jvmti/jvmti.h"
 #include "native/include/java_lang_String.h"
 #include <ltdl.h>
index d7d7d13f7e9791dc6243c3eface59d766903bb81..293af3e11f9c8c2f3d810eac3db797b021d72b7c 100644 (file)
@@ -53,7 +53,7 @@
 #include "vm/stringlocal.h"
 #include "mm/memory.h"
 #include "threads/mutex.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 #include "threads/lock-common.h"
 #include "vm/exceptions.h"
 #include "native/include/java_io_PrintStream.h"
index e9df0d64328252041395f42b32d6abbe3af08c55..02c171b7bc1ef05ac449846de7a967609a6502b4 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <assert.h>
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 
 /* LLNI critical sections ******************************************************
index f83af25b448a33475850ba234937b27fc668f563..85162111def807b3945e0942988175b1e2543230 100644 (file)
@@ -57,7 +57,7 @@ extern "C" {
 
 #include "native/localref.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 
 /* LLNI macros *****************************************************************
index 9ef934e9f6d638e3c5b979d750bddc7460ca4dce..e5791ab4f2507ac5e9116adcc3c17ec52a325014 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "native/localref.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index da9ffd01a604c358179e4883a802ab22e1945a0f..4743b8b9fbfd8c138460ce6f04342d3ec93b3598 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "native/include/java_lang_Thread.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index 9956ef34eb99a53d0f9f24b1902caddc2b056e87..0686e51cfe4e23e005bc415e5922fd9181a61694 100644 (file)
@@ -1,4 +1,4 @@
-/* src/native/vm/gnu/java_lang_VMThread.c
+/* src/native/vm/gnuclasspath/java_lang_VMThread.c
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
@@ -39,7 +39,7 @@
 #include "native/include/java_lang_Thread.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/exceptions.h"
 #include "vm/stringlocal.h"
index e74423e3a63838aca4ec63679f60db9ca8900ad6..b70b02b314b637901ece51b0d3e48b603b0e5eb3 100644 (file)
@@ -66,7 +66,7 @@
 #include "native/vm/openjdk/hpi.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 #include "toolbox/list.h"
index 3b11a8ec68bdc40979087e2b14cedee2f837287e..68cdfd9ec4d5c5c5b8373aa33cc3a9fa55949196 100644 (file)
@@ -57,8 +57,8 @@ libthreads_la_SOURCES = \
        mutex.hpp \
        threadlist.c \
        threadlist.h \
-       thread.c \
-       thread.h
+       thread.cpp \
+       thread.hpp
 else
 libthreads_la_SOURCES =
 endif
index 2e40fb8d398638b534f06a98e62242225234af38..de21e8aed7278da8ff2d65fc403b290e03cec976 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <stdint.h>
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/jit/stacktrace.hpp"
 
index 3567f64e796fc8071b5478c0a3d9fec5170c6cdf..55ad704184ad7f50b24e269196b2399cf04523f4 100644 (file)
@@ -41,7 +41,7 @@
 #include "threads/lock-common.h"
 #include "threads/mutex.hpp"
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "threads/posix/lock.h"
 
index f5f45d170f06f0633fa70501d2d2e936e8259c21..cefde2696894c0fba5df791bf6ce3a57f3cf495c 100644 (file)
@@ -71,7 +71,7 @@
 #include "threads/lock-common.h"
 #include "threads/mutex.hpp"
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
diff --git a/src/threads/thread.c b/src/threads/thread.c
deleted file mode 100644 (file)
index c857e00..0000000
+++ /dev/null
@@ -1,1308 +0,0 @@
-/* src/threads/thread.c - machine independent thread functions
-
-   Copyright (C) 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include "vm/types.h"
-
-#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_Object.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Thread.h"
-
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_ThreadGroup.h"
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-# include "native/include/java_lang_VMThread.h"
-#endif
-
-#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.hpp"
-
-#include "vm/jit/stacktrace.hpp"
-
-#include "vmcore/class.h"
-#include "vmcore/globals.hpp"
-#include "vmcore/method.h"
-#include "vmcore/options.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vmcore/statistics.h"
-#endif
-
-#include "vmcore/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-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. */
-bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* static functions ***********************************************************/
-
-static void          thread_create_initial_threadgroups(void);
-static void          thread_create_initial_thread(void);
-static threadobject *thread_new(void);
-
-
-/* threads_preinit *************************************************************
-
-   Do some early initialization of stuff required.
-
-*******************************************************************************/
-
-void threads_preinit(void)
-{
-       threadobject *mainthread;
-#if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
-       char         *pathbuf;
-       size_t        len;
-#endif
-
-       TRACESUBSYSTEMINITIALIZATION("threads_preinit");
-
-#if defined(__LINUX__)
-       /* XXX Remove for exact-GC. */
-
-       /* On Linux we need to check the pthread implementation. */
-
-       /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
-       /* If the glibc is a pre-2.3.2 version, we fall back to
-          linuxthreads. */
-
-# if defined(_CS_GNU_LIBPTHREAD_VERSION)
-       len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
-
-       /* Some systems return as length 0 (maybe cross-compilation
-          related).  In this case we also fall back to linuxthreads. */
-
-       if (len > 0) {
-               pathbuf = MNEW(char, len);
-
-               (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
-
-               if (strstr(pathbuf, "NPTL") != NULL)
-                       threads_pthreads_implementation_nptl = true;
-               else
-                       threads_pthreads_implementation_nptl = false;
-       }
-       else
-               threads_pthreads_implementation_nptl = false;
-# else
-       threads_pthreads_implementation_nptl = false;
-# endif
-#endif
-
-       /* Initialize the threads implementation (sets the thinlock on the
-          main thread). */
-
-       threads_impl_preinit();
-
-       /* Create internal thread data-structure for the main thread. */
-
-       mainthread = 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 */
-
-       mainthread->flags |= THREAD_FLAG_JAVA;
-       mainthread->state = THREAD_STATE_RUNNABLE;
-
-       /* Store the internal thread data-structure in the TSD. */
-
-       thread_set_current(mainthread);
-}
-
-
-/* threads_init ****************************************************************
-
-   Initialize the main thread.
-
-*******************************************************************************/
-
-void threads_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("threads_init");
-
-       /* Create the system and main thread groups. */
-
-       thread_create_initial_threadgroups();
-
-       /* Cache the java.lang.Thread initialization method. */
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       thread_method_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       thread_method_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
-                                                                class_java_lang_Thread,
-                                                                true);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       thread_method_init =
-               class_resolveclassmethod(class_java_lang_Thread,
-                                                                utf_init,
-                                                                utf_java_lang_String__void,
-                                                                class_java_lang_Thread,
-                                                                true);
-
-#else
-# error unknown classpath configuration
-#endif
-
-       if (thread_method_init == NULL)
-               vm_abort("threads_init: failed to resolve thread init method");
-
-       thread_create_initial_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 bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
-{
-       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;
-}
-
-
-/* thread_create_initial_threadgroups ******************************************
-
-   Create the initial threadgroups.
-
-   GNU Classpath:
-       Create the main threadgroup only and set the system
-       threadgroup to the main threadgroup.
-
-   SUN:
-       Create the system and main threadgroup.
-
-   CLDC:
-       This function is a no-op.
-
-*******************************************************************************/
-
-static void thread_create_initial_threadgroups(void)
-{
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Allocate and initialize the main thread group. */
-
-       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");
-
-       /* Use the same threadgroup for system as for main. */
-
-       threadgroup_system = threadgroup_main;
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       java_handle_t *name;
-       methodinfo    *m;
-
-       /* Allocate and initialize the system thread group. */
-
-       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 = builtin_new(class_java_lang_ThreadGroup);
-
-       if (threadgroup_main == NULL)
-               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
-
-       name = javastring_new(utf_main);
-
-       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
-                                                                utf_init,
-                                                                utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
-                                                                class_java_lang_ThreadGroup,
-                                                                true);
-
-       if (m == NULL)
-               vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
-
-       (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");
-
-# else
-#  error unknown classpath configuration
-# endif
-#endif
-}
-
-
-/* thread_create_initial_thread ***********************************************
-
-   Create the initial thread: main
-
-*******************************************************************************/
-
-static void thread_create_initial_thread(void)
-{
-       threadobject  *t;
-       java_handle_t *name;
-
-       /* Get the main-thread (NOTE: The main thread is always the first
-          thread in the list). */
-
-       t = threadlist_first();
-
-       /* The thread name. */
-
-       name = javastring_new(utf_main);
-
-#if defined(ENABLE_INTRP)
-       /* create interpreter stack */
-
-       if (opt_intrp) {
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
-               mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
-       }
-#endif
-
-       /* Create the Java thread object. */
-
-       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)", t);
-}
-
-
-/* thread_new ******************************************************************
-
-   Allocates and initializes an internal thread data-structure and
-   adds it to the threads list.
-
-*******************************************************************************/
-
-static threadobject *thread_new(void)
-{
-       int32_t       index;
-       threadobject *t;
-       
-       /* Lock the thread lists */
-
-       threadlist_lock();
-
-       index = threadlist_get_free_index();
-
-       /* Allocate a thread data structure. */
-
-       /* First, try to get one from the free-list. */
-
-       t = threadlist_free_first();
-
-       if (t != NULL) {
-               /* Remove from free list. */
-
-               threadlist_free_remove(t);
-
-               /* Equivalent of MZERO on the else path */
-
-               threads_impl_thread_clear(t);
-       }
-       else {
-#if defined(ENABLE_GC_BOEHM)
-               t = GCNEW_UNCOLLECTABLE(threadobject, 1);
-#else
-               t = NEW(threadobject);
-#endif
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       size_threadobject += sizeof(threadobject);
-#endif
-
-               /* Clear memory. */
-
-               MZERO(t, threadobject, 1);
-
-#if defined(ENABLE_GC_CACAO)
-               /* Register reference to java.lang.Thread with the GC. */
-               /* FIXME is it ok to do this only once? */
-
-               gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
-               gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
-#endif
-
-               /* Initialize the implementation-specific bits. */
-
-               threads_impl_thread_init(t);
-       }
-
-       /* Pre-compute the thinlock-word. */
-
-       assert(index != 0);
-
-       t->index     = index;
-       t->thinlock  = lock_pre_compute_thinlock(t->index);
-       t->flags     = 0;
-       t->state     = THREAD_STATE_NEW;
-
-#if defined(ENABLE_GC_CACAO)
-       t->flags    |= THREAD_FLAG_IN_NATIVE; 
-#endif
-
-       /* Initialize the implementation-specific bits. */
-
-       threads_impl_thread_reuse(t);
-
-       /* Add the thread to the thread list. */
-
-       threadlist_add(t);
-
-       /* Unlock the thread lists. */
-
-       threadlist_unlock();
-
-       return t;
-}
-
-
-/* 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
-
-*******************************************************************************/
-
-void thread_free(threadobject *t)
-{
-       /* Lock the thread lists. */
-
-       threadlist_lock();
-
-       /* Remove the thread from the thread-list. */
-
-       threadlist_remove(t);
-
-       /* Add the thread index to the free list. */
-
-       threadlist_index_add(t->index);
-
-       /* Set the reference to the Java object to NULL. */
-
-       thread_set_object(t, NULL);
-
-       /* Add the thread data structure to the free list. */
-
-       threadlist_free_add(t);
-
-       /* Unlock the thread lists. */
-
-       threadlist_unlock();
-}
-
-
-/* threads_thread_start_internal ***********************************************
-
-   Start an internal thread in the JVM.  No Java thread objects exists
-   so far.
-
-   IN:
-      name.......UTF-8 name of the thread
-      f..........function pointer to C function to start
-
-*******************************************************************************/
-
-bool threads_thread_start_internal(utf *name, functionptr f)
-{
-       threadobject *t;
-
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
-       /* Create internal thread data-structure. */
-
-       t = thread_new();
-
-       t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
-
-       /* The thread is flagged as (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
-
-       /* Create the Java thread object. */
-
-       if (!thread_create_object(t, javastring_new(name), threadgroup_system))
-               return false;
-
-       /* Start the thread. */
-
-       threads_impl_thread_start(t, f);
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* threads_thread_start ********************************************************
-
-   Start a Java thread in the JVM.  Only the java thread object exists
-   so far.
-
-   IN:
-      object.....the java thread object java.lang.Thread
-
-*******************************************************************************/
-
-void threads_thread_start(java_handle_t *object)
-{
-       java_lang_Thread   *to;
-       threadobject       *t;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThread *vmto;
-#endif
-
-       to = (java_lang_Thread *) object;
-
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
-       /* Create internal thread data-structure. */
-
-       t = thread_new();
-
-       /* this is a normal Java thread */
-
-       t->flags |= THREAD_FLAG_JAVA;
-
-#if defined(ENABLE_JAVASE)
-       /* Is this a daemon thread? */
-
-       if (LLNI_field_direct(to, daemon) == true)
-               t->flags |= THREAD_FLAG_DAEMON;
-#endif
-
-       /* The thread is flagged and (non-)daemon thread, we can leave the
-          mutex. */
-
-       threads_mutex_join_unlock();
-
-       /* Link the two objects together. */
-
-       thread_set_object(t, object);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Get the java.lang.VMThread object and do some sanity checks. */
-
-       LLNI_field_get_ref(to, vmThread, vmto);
-
-       assert(vmto);
-       assert(LLNI_field_direct(vmto, vmdata) == NULL);
-
-       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* Nothing to do. */
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
-
-#else
-# error unknown classpath configuration
-#endif
-
-       /* Start the thread.  Don't pass a function pointer (NULL) since
-          we want Thread.run()V here. */
-
-       threads_impl_thread_start(t, NULL);
-}
-
-
-/**
- * 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 *name;
-       java_handle_t *group;
-
-    /* If the current thread has already been attached, this operation
-          is a no-op. */
-
-       result = thread_current_is_attached();
-
-       if (result == true)
-               return true;
-
-       /* Enter the join-mutex, so if the main-thread is currently
-          waiting to join all threads, the number of non-daemon threads
-          is correct. */
-
-       threads_mutex_join_lock();
-
-       /* Create internal thread data structure. */
-
-       t = thread_new();
-
-       /* Thread is a Java thread and running. */
-
-       t->flags = THREAD_FLAG_JAVA;
-
-       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();
-
-       DEBUGTHREADS("attaching", t);
-
-       /* Get the thread name. */
-
-       if (vm_aargs != NULL) {
-               u = utf_new_char(vm_aargs->name);
-       }
-       else {
-               u = utf_null;
-       }
-
-       name = javastring_new(u);
-
-#if defined(ENABLE_JAVASE)
-       /* Get the threadgroup. */
-
-       if (vm_aargs != NULL)
-               group = (java_handle_t *) vm_aargs->group;
-       else
-               group = NULL;
-
-       /* If no threadgroup was given, use the main threadgroup. */
-
-       if (group == NULL)
-               group = threadgroup_main;
-#endif
-
-#if defined(ENABLE_INTRP)
-       /* create interpreter stack */
-
-       if (opt_intrp) {
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
-               thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
-       }
-#endif
-
-       /* Create the Java thread object. */
-
-       if (!thread_create_object(t, name, group))
-               return false;
-
-       /* The thread is completely initialized. */
-
-       thread_set_state_runnable(t);
-
-       return true;
-}
-
-
-/**
- * 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;
-
-#if defined(ENABLE_GC_BOEHM)
-       struct GC_stack_base sb;
-#endif
-
-#if defined(ENABLE_GC_BOEHM)
-       /* Register the thread with Boehm-GC.  This must happen before the
-          thread allocates any memory from the GC heap.*/
-
-       result = GC_get_stack_base(&sb);
-
-       if (result != GC_SUCCESS)
-               vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
-
-       GC_register_my_thread(&sb);
-#endif
-
-       result = thread_attach_current_thread(vm_aargs, isdaemon);
-
-       if (result == false) {
-#if defined(ENABLE_GC_BOEHM)
-               /* Unregister the thread. */
-
-               GC_unregister_my_thread();
-#endif
-
-               return false;
-       }
-
-       return true;
-}
-
-
-/**
- * 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;
-
-#if defined(ENABLE_GC_BOEHM)
-       /* Unregister the thread with Boehm-GC.  This must happen after
-          the thread allocates any memory from the GC heap. */
-
-       /* 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
-
-       return true;
-}
-
-
-/* thread_fprint_name **********************************************************
-
-   Print the name of the given thread to the given stream.
-
-   ARGUMENTS:
-       t ........ thread data-structure
-       stream ... stream to print to
-
-*******************************************************************************/
-
-void thread_fprint_name(threadobject *t, FILE *stream)
-{
-       java_lang_Thread *to;
-
-#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
-
-       to = (java_lang_Thread *) thread_get_object(t);
-
-       if (to == NULL)
-               vm_abort("");
-
-       LLNI_field_get_ref(to, name, name);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       javastring_fprint((java_handle_t *) name, stream);
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       /* 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
-}
-
-
-/* thread_print_info ***********************************************************
-
-   Print information of the passed thread.
-
-   ARGUMENTS:
-       t ... thread data-structure.
-
-*******************************************************************************/
-
-void thread_print_info(threadobject *t)
-{
-       java_lang_Thread *to;
-       int               state;
-
-       /* If the thread is currently in initalization, don't print it. */
-
-       to = (java_lang_Thread *) thread_get_object(t);
-
-       /* Print as much as we can when we are in state NEW. */
-
-       if (to != NULL) {
-               /* Print thread name. */
-
-               printf("\"");
-               thread_fprint_name(t, stdout);
-               printf("\"");
-       }
-       else {
-       }
-
-       if (thread_is_daemon(t))
-               printf(" daemon");
-
-       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);
-#else
-       printf(" t=0x%08x tid=0x%08x (%d)",
-                  (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
-#endif
-
-       printf(" index=%d", t->index);
-
-       /* Print thread 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_get_current_tid *****************************************************
-
-   Return the tid of the current thread.
-   
-   RETURN VALUE:
-       the current tid
-
-*******************************************************************************/
-
-intptr_t threads_get_current_tid(void)
-{
-       threadobject *thread;
-
-       thread = THREADOBJECT;
-
-       /* this may happen during bootstrap */
-
-       if (thread == NULL)
-               return 0;
-
-       return (intptr_t) thread->tid;
-}
-
-
-/* thread_set_state_runnable ***************************************************
-
-   Set the current state of the given thread to THREAD_STATE_RUNNABLE.
-
-   NOTE: If the thread has already terminated, don't set the state.
-         This is important for threads_detach_thread.
-
-*******************************************************************************/
-
-void thread_set_state_runnable(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_RUNNABLE;
-
-               DEBUGTHREADS("is RUNNABLE", t);
-       }
-
-       threadlist_unlock();
-}
-
-
-/* thread_set_state_waiting ****************************************************
-
-   Set the current state of the given thread to THREAD_STATE_WAITING.
-
-   NOTE: If the thread has already terminated, don't set the state.
-         This is important for threads_detach_thread.
-
-*******************************************************************************/
-
-void thread_set_state_waiting(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_WAITING;
-
-               DEBUGTHREADS("is WAITING", t);
-       }
-
-       threadlist_unlock();
-}
-
-
-/* thread_set_state_timed_waiting **********************************************
-
-   Set the current state of the given thread to
-   THREAD_STATE_TIMED_WAITING.
-
-   NOTE: If the thread has already terminated, don't set the state.
-         This is important for threads_detach_thread.
-
-*******************************************************************************/
-
-void thread_set_state_timed_waiting(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_TIMED_WAITING;
-
-               DEBUGTHREADS("is TIMED_WAITING", t);
-       }
-
-       threadlist_unlock();
-}
-
-
-/* thread_set_state_terminated *************************************************
-
-   Set the current state of the given thread to
-   THREAD_STATE_TERMINATED.
-
-*******************************************************************************/
-
-void thread_set_state_terminated(threadobject *t)
-{
-       /* Set the state inside a lock. */
-
-       threadlist_lock();
-
-       t->state = THREAD_STATE_TERMINATED;
-
-       DEBUGTHREADS("is TERMINATED", t);
-
-       threadlist_unlock();
-}
-
-
-/* thread_get_thread **********************************************************
-
-   Return the thread data structure of the given Java thread object.
-
-   ARGUMENTS:
-       h ... java.lang.{VM}Thread object
-
-   RETURN VALUE:
-       the thread object
-
-*******************************************************************************/
-
-threadobject *thread_get_thread(java_handle_t *h)
-{
-       threadobject       *t;
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       java_lang_VMThread *vmto;
-       java_lang_Object   *to;
-#endif
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       bool                equal;
-#endif
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       vmto = (java_lang_VMThread *) h;
-
-       LLNI_field_get_val(vmto, vmdata, to);
-
-       t = (threadobject *) to;
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       /* XXX This is just a quick hack. */
-
-       threadlist_lock();
-
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               LLNI_equals(t->object, h, equal);
-
-               if (equal == true)
-                       break;
-       }
-
-       threadlist_unlock();
-
-#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
-
-       log_println("threads_get_thread: IMPLEMENT ME!");
-
-#else
-# error unknown classpath configuration
-#endif
-
-       return t;
-}
-
-
-/* threads_thread_is_alive *****************************************************
-
-   Returns if the give thread is alive.
-
-*******************************************************************************/
-
-bool threads_thread_is_alive(threadobject *t)
-{
-       int state;
-
-       state = cacaothread_get_state(t);
-
-       switch (state) {
-       case THREAD_STATE_NEW:
-       case THREAD_STATE_TERMINATED:
-               return false;
-
-       case THREAD_STATE_RUNNABLE:
-       case THREAD_STATE_BLOCKED:
-       case THREAD_STATE_WAITING:
-       case THREAD_STATE_TIMED_WAITING:
-               return true;
-
-       default:
-               vm_abort("threads_thread_is_alive: unknown thread state %d", state);
-       }
-
-       /* keep compiler happy */
-
-       return false;
-}
-
-
-/* threads_dump ****************************************************************
-
-   Dumps info for all threads running in the JVM.  This function is
-   called when SIGQUIT (<ctrl>-\) is sent to CACAO.
-
-*******************************************************************************/
-
-void threads_dump(void)
-{
-       threadobject *t;
-
-       /* XXX we should stop the world here */
-
-       /* Lock the thread lists. */
-
-       threadlist_lock();
-
-       printf("Full thread dump CACAO "VERSION":\n");
-
-       /* iterate over all started threads */
-
-       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
-               /* ignore threads which are in state NEW */
-               if (t->state == THREAD_STATE_NEW)
-                       continue;
-
-#if defined(ENABLE_GC_CACAO)
-               /* Suspend the thread. */
-               /* XXX Is the suspend reason correct? */
-
-               if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
-                       vm_abort("threads_dump: threads_suspend_thread failed");
-#endif
-
-               /* Print thread info. */
-
-               printf("\n");
-               thread_print_info(t);
-               printf("\n");
-
-               /* Print trace of thread. */
-
-               stacktrace_print_of_thread(t);
-
-#if defined(ENABLE_GC_CACAO)
-               /* Resume the thread. */
-
-               if (threads_resume_thread(t) == false)
-                       vm_abort("threads_dump: threads_resume_thread failed");
-#endif
-       }
-
-       /* Unlock the thread lists. */
-
-       threadlist_unlock();
-}
-
-
-/*
- * 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
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/threads/thread.cpp b/src/threads/thread.cpp
new file mode 100644 (file)
index 0000000..6e77e7c
--- /dev/null
@@ -0,0 +1,1313 @@
+/* src/threads/thread.cpp - machine independent thread functions
+
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "vm/types.h"
+
+#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_Object.h"
+#include "native/include/java_lang_String.h"
+#include "native/include/java_lang_Thread.h"
+
+#if defined(ENABLE_JAVASE)
+# include "native/include/java_lang_ThreadGroup.h"
+#endif
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+# include "native/include/java_lang_VMThread.h"
+#endif
+
+#include "threads/lock-common.h"
+#include "threads/threadlist.h"
+#include "threads/thread.hpp"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/stacktrace.hpp"
+
+#include "vmcore/class.h"
+#include "vmcore/globals.hpp"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/utf8.h"
+
+
+// FIXME
+extern "C" {
+
+/* global variables ***********************************************************/
+
+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. */
+bool threads_pthreads_implementation_nptl;
+#endif
+
+
+/* static functions ***********************************************************/
+
+static void          thread_create_initial_threadgroups(void);
+static void          thread_create_initial_thread(void);
+static threadobject *thread_new(void);
+
+
+/* threads_preinit *************************************************************
+
+   Do some early initialization of stuff required.
+
+*******************************************************************************/
+
+void threads_preinit(void)
+{
+       threadobject *mainthread;
+#if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
+       char         *pathbuf;
+       size_t        len;
+#endif
+
+       TRACESUBSYSTEMINITIALIZATION("threads_preinit");
+
+#if defined(__LINUX__)
+       /* XXX Remove for exact-GC. */
+
+       /* On Linux we need to check the pthread implementation. */
+
+       /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
+       /* If the glibc is a pre-2.3.2 version, we fall back to
+          linuxthreads. */
+
+# if defined(_CS_GNU_LIBPTHREAD_VERSION)
+       len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
+
+       /* Some systems return as length 0 (maybe cross-compilation
+          related).  In this case we also fall back to linuxthreads. */
+
+       if (len > 0) {
+               pathbuf = MNEW(char, len);
+
+               (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
+
+               if (strstr(pathbuf, "NPTL") != NULL)
+                       threads_pthreads_implementation_nptl = true;
+               else
+                       threads_pthreads_implementation_nptl = false;
+       }
+       else
+               threads_pthreads_implementation_nptl = false;
+# else
+       threads_pthreads_implementation_nptl = false;
+# endif
+#endif
+
+       /* Initialize the threads implementation (sets the thinlock on the
+          main thread). */
+
+       threads_impl_preinit();
+
+       /* Create internal thread data-structure for the main thread. */
+
+       mainthread = 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 */
+
+       mainthread->flags |= THREAD_FLAG_JAVA;
+       mainthread->state = THREAD_STATE_RUNNABLE;
+
+       /* Store the internal thread data-structure in the TSD. */
+
+       thread_set_current(mainthread);
+}
+
+
+/* threads_init ****************************************************************
+
+   Initialize the main thread.
+
+*******************************************************************************/
+
+void threads_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("threads_init");
+
+       /* Create the system and main thread groups. */
+
+       thread_create_initial_threadgroups();
+
+       /* Cache the java.lang.Thread initialization method. */
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
+                                                                class_java_lang_Thread,
+                                                                true);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       thread_method_init =
+               class_resolveclassmethod(class_java_lang_Thread,
+                                                                utf_init,
+                                                                utf_java_lang_String__void,
+                                                                class_java_lang_Thread,
+                                                                true);
+
+#else
+# error unknown classpath configuration
+#endif
+
+       if (thread_method_init == NULL)
+               vm_abort("threads_init: failed to resolve thread init method");
+
+       thread_create_initial_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 bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
+{
+       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;
+}
+
+
+/* thread_create_initial_threadgroups ******************************************
+
+   Create the initial threadgroups.
+
+   GNU Classpath:
+       Create the main threadgroup only and set the system
+       threadgroup to the main threadgroup.
+
+   SUN:
+       Create the system and main threadgroup.
+
+   CLDC:
+       This function is a no-op.
+
+*******************************************************************************/
+
+static void thread_create_initial_threadgroups(void)
+{
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Allocate and initialize the main thread group. */
+
+       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");
+
+       /* Use the same threadgroup for system as for main. */
+
+       threadgroup_system = threadgroup_main;
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       java_handle_t *name;
+       methodinfo    *m;
+
+       /* Allocate and initialize the system thread group. */
+
+       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 = builtin_new(class_java_lang_ThreadGroup);
+
+       if (threadgroup_main == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
+
+       name = javastring_new(utf_main);
+
+       m = class_resolveclassmethod(class_java_lang_ThreadGroup,
+                                                                utf_init,
+                                                                utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
+                                                                class_java_lang_ThreadGroup,
+                                                                true);
+
+       if (m == NULL)
+               vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
+
+       (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");
+
+# else
+#  error unknown classpath configuration
+# endif
+#endif
+}
+
+
+/* thread_create_initial_thread ***********************************************
+
+   Create the initial thread: main
+
+*******************************************************************************/
+
+static void thread_create_initial_thread(void)
+{
+       threadobject  *t;
+       java_handle_t *name;
+
+       /* Get the main-thread (NOTE: The main thread is always the first
+          thread in the list). */
+
+       t = threadlist_first();
+
+       /* The thread name. */
+
+       name = javastring_new(utf_main);
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+               mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
+       }
+#endif
+
+       /* Create the Java thread object. */
+
+       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)", t);
+}
+
+
+/* thread_new ******************************************************************
+
+   Allocates and initializes an internal thread data-structure and
+   adds it to the threads list.
+
+*******************************************************************************/
+
+static threadobject *thread_new(void)
+{
+       int32_t       index;
+       threadobject *t;
+       
+       /* Lock the thread lists */
+
+       threadlist_lock();
+
+       index = threadlist_get_free_index();
+
+       /* Allocate a thread data structure. */
+
+       /* First, try to get one from the free-list. */
+
+       t = threadlist_free_first();
+
+       if (t != NULL) {
+               /* Remove from free list. */
+
+               threadlist_free_remove(t);
+
+               /* Equivalent of MZERO on the else path */
+
+               threads_impl_thread_clear(t);
+       }
+       else {
+#if defined(ENABLE_GC_BOEHM)
+               t = GCNEW_UNCOLLECTABLE(threadobject, 1);
+#else
+               t = NEW(threadobject);
+#endif
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       size_threadobject += sizeof(threadobject);
+#endif
+
+               /* Clear memory. */
+
+               MZERO(t, threadobject, 1);
+
+#if defined(ENABLE_GC_CACAO)
+               /* Register reference to java.lang.Thread with the GC. */
+               /* FIXME is it ok to do this only once? */
+
+               gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
+               gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
+#endif
+
+               /* Initialize the implementation-specific bits. */
+
+               threads_impl_thread_init(t);
+       }
+
+       /* Pre-compute the thinlock-word. */
+
+       assert(index != 0);
+
+       t->index     = index;
+       t->thinlock  = lock_pre_compute_thinlock(t->index);
+       t->flags     = 0;
+       t->state     = THREAD_STATE_NEW;
+
+#if defined(ENABLE_GC_CACAO)
+       t->flags    |= THREAD_FLAG_IN_NATIVE; 
+#endif
+
+       /* Initialize the implementation-specific bits. */
+
+       threads_impl_thread_reuse(t);
+
+       /* Add the thread to the thread list. */
+
+       threadlist_add(t);
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+
+       return t;
+}
+
+
+/* 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
+
+*******************************************************************************/
+
+void thread_free(threadobject *t)
+{
+       /* Lock the thread lists. */
+
+       threadlist_lock();
+
+       /* Remove the thread from the thread-list. */
+
+       threadlist_remove(t);
+
+       /* Add the thread index to the free list. */
+
+       threadlist_index_add(t->index);
+
+       /* Set the reference to the Java object to NULL. */
+
+       thread_set_object(t, NULL);
+
+       /* Add the thread data structure to the free list. */
+
+       threadlist_free_add(t);
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+}
+
+
+/* threads_thread_start_internal ***********************************************
+
+   Start an internal thread in the JVM.  No Java thread objects exists
+   so far.
+
+   IN:
+      name.......UTF-8 name of the thread
+      f..........function pointer to C function to start
+
+*******************************************************************************/
+
+bool threads_thread_start_internal(utf *name, functionptr f)
+{
+       threadobject *t;
+
+       /* Enter the join-mutex, so if the main-thread is currently
+          waiting to join all threads, the number of non-daemon threads
+          is correct. */
+
+       threads_mutex_join_lock();
+
+       /* Create internal thread data-structure. */
+
+       t = thread_new();
+
+       t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
+
+       /* The thread is flagged as (non-)daemon thread, we can leave the
+          mutex. */
+
+       threads_mutex_join_unlock();
+
+       /* Create the Java thread object. */
+
+       if (!thread_create_object(t, javastring_new(name), threadgroup_system))
+               return false;
+
+       /* Start the thread. */
+
+       threads_impl_thread_start(t, f);
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* threads_thread_start ********************************************************
+
+   Start a Java thread in the JVM.  Only the java thread object exists
+   so far.
+
+   IN:
+      object.....the java thread object java.lang.Thread
+
+*******************************************************************************/
+
+void threads_thread_start(java_handle_t *object)
+{
+       java_lang_Thread   *to;
+       threadobject       *t;
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       java_lang_VMThread *vmto;
+#endif
+
+       to = (java_lang_Thread *) object;
+
+       /* Enter the join-mutex, so if the main-thread is currently
+          waiting to join all threads, the number of non-daemon threads
+          is correct. */
+
+       threads_mutex_join_lock();
+
+       /* Create internal thread data-structure. */
+
+       t = thread_new();
+
+       /* this is a normal Java thread */
+
+       t->flags |= THREAD_FLAG_JAVA;
+
+#if defined(ENABLE_JAVASE)
+       /* Is this a daemon thread? */
+
+       if (LLNI_field_direct(to, daemon) == true)
+               t->flags |= THREAD_FLAG_DAEMON;
+#endif
+
+       /* The thread is flagged and (non-)daemon thread, we can leave the
+          mutex. */
+
+       threads_mutex_join_unlock();
+
+       /* Link the two objects together. */
+
+       thread_set_object(t, object);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Get the java.lang.VMThread object and do some sanity checks. */
+
+       LLNI_field_get_ref(to, vmThread, vmto);
+
+       assert(vmto);
+       assert(LLNI_field_direct(vmto, vmdata) == NULL);
+
+       LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       /* Nothing to do. */
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
+
+#else
+# error unknown classpath configuration
+#endif
+
+       /* Start the thread.  Don't pass a function pointer (NULL) since
+          we want Thread.run()V here. */
+
+       threads_impl_thread_start(t, NULL);
+}
+
+
+/**
+ * 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 *name;
+       java_handle_t *group;
+
+    /* If the current thread has already been attached, this operation
+          is a no-op. */
+
+       result = thread_current_is_attached();
+
+       if (result == true)
+               return true;
+
+       /* Enter the join-mutex, so if the main-thread is currently
+          waiting to join all threads, the number of non-daemon threads
+          is correct. */
+
+       threads_mutex_join_lock();
+
+       /* Create internal thread data structure. */
+
+       t = thread_new();
+
+       /* Thread is a Java thread and running. */
+
+       t->flags = THREAD_FLAG_JAVA;
+
+       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();
+
+       DEBUGTHREADS("attaching", t);
+
+       /* Get the thread name. */
+
+       if (vm_aargs != NULL) {
+               u = utf_new_char(vm_aargs->name);
+       }
+       else {
+               u = utf_null;
+       }
+
+       name = javastring_new(u);
+
+#if defined(ENABLE_JAVASE)
+       /* Get the threadgroup. */
+
+       if (vm_aargs != NULL)
+               group = (java_handle_t *) vm_aargs->group;
+       else
+               group = NULL;
+
+       /* If no threadgroup was given, use the main threadgroup. */
+
+       if (group == NULL)
+               group = threadgroup_main;
+#endif
+
+#if defined(ENABLE_INTRP)
+       /* create interpreter stack */
+
+       if (opt_intrp) {
+               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+               thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
+       }
+#endif
+
+       /* Create the Java thread object. */
+
+       if (!thread_create_object(t, name, group))
+               return false;
+
+       /* The thread is completely initialized. */
+
+       thread_set_state_runnable(t);
+
+       return true;
+}
+
+
+/**
+ * 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;
+
+#if defined(ENABLE_GC_BOEHM)
+       struct GC_stack_base sb;
+#endif
+
+#if defined(ENABLE_GC_BOEHM)
+       /* Register the thread with Boehm-GC.  This must happen before the
+          thread allocates any memory from the GC heap.*/
+
+       result = GC_get_stack_base(&sb);
+
+       if (result != GC_SUCCESS)
+               vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
+
+       GC_register_my_thread(&sb);
+#endif
+
+       result = thread_attach_current_thread(vm_aargs, isdaemon);
+
+       if (result == false) {
+#if defined(ENABLE_GC_BOEHM)
+               /* Unregister the thread. */
+
+               GC_unregister_my_thread();
+#endif
+
+               return false;
+       }
+
+       return true;
+}
+
+
+/**
+ * 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;
+
+#if defined(ENABLE_GC_BOEHM)
+       /* Unregister the thread with Boehm-GC.  This must happen after
+          the thread allocates any memory from the GC heap. */
+
+       /* 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
+
+       return true;
+}
+
+
+/* thread_fprint_name **********************************************************
+
+   Print the name of the given thread to the given stream.
+
+   ARGUMENTS:
+       t ........ thread data-structure
+       stream ... stream to print to
+
+*******************************************************************************/
+
+void thread_fprint_name(threadobject *t, FILE *stream)
+{
+       java_lang_Thread *to;
+
+#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
+
+       to = (java_lang_Thread *) thread_get_object(t);
+
+       if (to == NULL)
+               vm_abort("");
+
+       LLNI_field_get_ref(to, name, name);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       javastring_fprint((java_handle_t *) name, stream);
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       /* 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
+}
+
+
+/* thread_print_info ***********************************************************
+
+   Print information of the passed thread.
+
+   ARGUMENTS:
+       t ... thread data-structure.
+
+*******************************************************************************/
+
+void thread_print_info(threadobject *t)
+{
+       java_lang_Thread *to;
+       int               state;
+
+       /* If the thread is currently in initalization, don't print it. */
+
+       to = (java_lang_Thread *) thread_get_object(t);
+
+       /* Print as much as we can when we are in state NEW. */
+
+       if (to != NULL) {
+               /* Print thread name. */
+
+               printf("\"");
+               thread_fprint_name(t, stdout);
+               printf("\"");
+       }
+       else {
+       }
+
+       if (thread_is_daemon(t))
+               printf(" daemon");
+
+       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);
+#else
+       printf(" t=0x%08x tid=0x%08x (%d)",
+                  (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
+#endif
+
+       printf(" index=%d", t->index);
+
+       /* Print thread 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_get_current_tid *****************************************************
+
+   Return the tid of the current thread.
+   
+   RETURN VALUE:
+       the current tid
+
+*******************************************************************************/
+
+intptr_t threads_get_current_tid(void)
+{
+       threadobject *thread;
+
+       thread = THREADOBJECT;
+
+       /* this may happen during bootstrap */
+
+       if (thread == NULL)
+               return 0;
+
+       return (intptr_t) thread->tid;
+}
+
+
+/* thread_set_state_runnable ***************************************************
+
+   Set the current state of the given thread to THREAD_STATE_RUNNABLE.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_runnable(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               t->state = THREAD_STATE_RUNNABLE;
+
+               DEBUGTHREADS("is RUNNABLE", t);
+       }
+
+       threadlist_unlock();
+}
+
+
+/* thread_set_state_waiting ****************************************************
+
+   Set the current state of the given thread to THREAD_STATE_WAITING.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_waiting(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               t->state = THREAD_STATE_WAITING;
+
+               DEBUGTHREADS("is WAITING", t);
+       }
+
+       threadlist_unlock();
+}
+
+
+/* thread_set_state_timed_waiting **********************************************
+
+   Set the current state of the given thread to
+   THREAD_STATE_TIMED_WAITING.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_timed_waiting(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               t->state = THREAD_STATE_TIMED_WAITING;
+
+               DEBUGTHREADS("is TIMED_WAITING", t);
+       }
+
+       threadlist_unlock();
+}
+
+
+/* thread_set_state_terminated *************************************************
+
+   Set the current state of the given thread to
+   THREAD_STATE_TERMINATED.
+
+*******************************************************************************/
+
+void thread_set_state_terminated(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       threadlist_lock();
+
+       t->state = THREAD_STATE_TERMINATED;
+
+       DEBUGTHREADS("is TERMINATED", t);
+
+       threadlist_unlock();
+}
+
+
+/* thread_get_thread **********************************************************
+
+   Return the thread data structure of the given Java thread object.
+
+   ARGUMENTS:
+       h ... java.lang.{VM}Thread object
+
+   RETURN VALUE:
+       the thread object
+
+*******************************************************************************/
+
+threadobject *thread_get_thread(java_handle_t *h)
+{
+       threadobject       *t;
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       java_lang_VMThread *vmto;
+       java_lang_Object   *to;
+#endif
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       bool                equal;
+#endif
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       vmto = (java_lang_VMThread *) h;
+
+       LLNI_field_get_val(vmto, vmdata, to);
+
+       t = (threadobject *) to;
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       /* XXX This is just a quick hack. */
+
+       threadlist_lock();
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               LLNI_equals(t->object, h, equal);
+
+               if (equal == true)
+                       break;
+       }
+
+       threadlist_unlock();
+
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
+
+       log_println("threads_get_thread: IMPLEMENT ME!");
+
+#else
+# error unknown classpath configuration
+#endif
+
+       return t;
+}
+
+
+/* threads_thread_is_alive *****************************************************
+
+   Returns if the give thread is alive.
+
+*******************************************************************************/
+
+bool threads_thread_is_alive(threadobject *t)
+{
+       int state;
+
+       state = cacaothread_get_state(t);
+
+       switch (state) {
+       case THREAD_STATE_NEW:
+       case THREAD_STATE_TERMINATED:
+               return false;
+
+       case THREAD_STATE_RUNNABLE:
+       case THREAD_STATE_BLOCKED:
+       case THREAD_STATE_WAITING:
+       case THREAD_STATE_TIMED_WAITING:
+               return true;
+
+       default:
+               vm_abort("threads_thread_is_alive: unknown thread state %d", state);
+       }
+
+       /* keep compiler happy */
+
+       return false;
+}
+
+
+/* threads_dump ****************************************************************
+
+   Dumps info for all threads running in the JVM.  This function is
+   called when SIGQUIT (<ctrl>-\) is sent to CACAO.
+
+*******************************************************************************/
+
+void threads_dump(void)
+{
+       threadobject *t;
+
+       /* XXX we should stop the world here */
+
+       /* Lock the thread lists. */
+
+       threadlist_lock();
+
+       printf("Full thread dump CACAO "VERSION":\n");
+
+       /* iterate over all started threads */
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               /* ignore threads which are in state NEW */
+               if (t->state == THREAD_STATE_NEW)
+                       continue;
+
+#if defined(ENABLE_GC_CACAO)
+               /* Suspend the thread. */
+               /* XXX Is the suspend reason correct? */
+
+               if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
+                       vm_abort("threads_dump: threads_suspend_thread failed");
+#endif
+
+               /* Print thread info. */
+
+               printf("\n");
+               thread_print_info(t);
+               printf("\n");
+
+               /* Print trace of thread. */
+
+               stacktrace_print_of_thread(t);
+
+#if defined(ENABLE_GC_CACAO)
+               /* Resume the thread. */
+
+               if (threads_resume_thread(t) == false)
+                       vm_abort("threads_dump: threads_resume_thread failed");
+#endif
+       }
+
+       /* Unlock the thread lists. */
+
+       threadlist_unlock();
+}
+
+} // extern "C"
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/threads/thread.h b/src/threads/thread.h
deleted file mode 100644 (file)
index 20a9565..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/* src/threads/thread.h - machine independent thread functions
-
-   Copyright (C) 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _THREAD_H
-#define _THREAD_H
-
-#include "config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vmcore/system.h"
-
-#include "threads/mutex.hpp"
-
-#if defined(ENABLE_THREADS)
-# include "threads/posix/thread-posix.hpp"
-#else
-# include "threads/none/thread-none.h"
-#endif
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-#include "native/jni.h"
-#include "native/llni.h"
-
-#include "vmcore/utf8.h"
-
-
-/* only define the following stuff with thread enabled ************************/
-
-#if defined(ENABLE_THREADS)
-
-/* thread states **************************************************************/
-
-#define THREAD_STATE_NEW              0
-#define THREAD_STATE_RUNNABLE         1
-#define THREAD_STATE_BLOCKED          2
-#define THREAD_STATE_WAITING          3
-#define THREAD_STATE_TIMED_WAITING    4
-#define THREAD_STATE_TERMINATED       5
-
-
-/* thread priorities **********************************************************/
-
-#define MIN_PRIORITY     1
-#define NORM_PRIORITY    5
-#define MAX_PRIORITY     10
-
-
-/* debug **********************************************************************/
-
-#if !defined(NDEBUG)
-# define DEBUGTHREADS(message, thread) \
-       do { \
-               if (opt_DebugThreads) { \
-                       printf("[Thread %-16s: ", message); \
-                       thread_print_info(thread); \
-                       printf("]\n"); \
-               } \
-       } while (0)
-#else
-# define DEBUGTHREADS(message, thread)
-#endif
-
-
-/* global variables ***********************************************************/
-
-#if defined(__LINUX__)
-/* XXX Remove for exact-GC. */
-extern bool threads_pthreads_implementation_nptl;
-#endif
-
-
-/* inline functions ***********************************************************/
-
-/* thread_get_object ***********************************************************
-
-   Return the Java for the given thread.
-
-   ARGUMENTS:
-       t ... thread
-
-   RETURN:
-       the Java object
-
-*******************************************************************************/
-
-inline static java_handle_t *thread_get_object(threadobject *t)
-{
-       return LLNI_WRAP(t->object);
-}
-
-
-/* threads_thread_set_object ***************************************************
-
-   Set the Java object for the given thread.
-
-   ARGUMENTS:
-       t ... thread
-          o ... Java object
-
-*******************************************************************************/
-
-inline static void thread_set_object(threadobject *t, java_handle_t *o)
-{
-       t->object = LLNI_DIRECT(o);
-}
-
-
-/* thread_get_current_object **************************************************
-
-   Return the Java object of the current thread.
-   
-   RETURN VALUE:
-       the Java object
-
-*******************************************************************************/
-
-inline static java_handle_t *thread_get_current_object(void)
-{
-       threadobject  *t;
-       java_handle_t *o;
-
-       t = THREADOBJECT;
-       o = thread_get_object(t);
-
-       return o;
-}
-
-
-/* cacaothread_get_state *******************************************************
-
-   Returns the current state of the given thread.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN:
-       thread state
-
-*******************************************************************************/
-
-inline static int cacaothread_get_state(threadobject *t)
-{
-       return t->state;
-}
-
-
-/* thread_is_attached **********************************************************
-
-   Returns if the given thread is attached to the VM.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN:
-       true .... the thread is attached to the VM
-       false ... the thread is not
-
-*******************************************************************************/
-
-inline static bool thread_is_attached(threadobject *t)
-{
-       java_handle_t *o;
-
-       o = thread_get_object(t);
-
-       if (o != NULL)
-               return true;
-       else
-               return false;
-}
-
-
-/* thread_is_interrupted *******************************************************
-
-   Check if the given thread has been interrupted.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN VALUE:
-      true, if the given thread had been interrupted
-
-*******************************************************************************/
-
-inline static bool thread_is_interrupted(threadobject *t)
-{
-       bool interrupted;
-
-       /* We need the mutex because classpath will call this function when
-          a blocking system call is interrupted. The mutex ensures that it will
-          see the correct value for the interrupted flag. */
-
-#ifdef __cplusplus
-       t->waitmutex->lock();
-       interrupted = t->interrupted;
-       t->waitmutex->unlock();
-#else
-       Mutex_lock(t->waitmutex);
-       interrupted = t->interrupted;
-       Mutex_unlock(t->waitmutex);
-#endif
-
-       return interrupted;
-}
-
-
-/* thread_set_interrupted ******************************************************
-
-   Set the interrupted flag to the given value.
-
-   ARGUMENTS:
-       interrupted ... value to set
-
-*******************************************************************************/
-
-inline static void thread_set_interrupted(threadobject *t, bool interrupted)
-{
-#ifdef __cplusplus
-       t->waitmutex->lock();
-       t->interrupted = interrupted;
-       t->waitmutex->unlock();
-#else
-       Mutex_lock(t->waitmutex);
-       t->interrupted = interrupted;
-       Mutex_unlock(t->waitmutex);
-#endif
-}
-
-
-/* thread_is_daemon ************************************************************
-
-   Returns if the given thread is a daemon thread.
-
-   ARGUMENTS:
-       t ... the thread to check
-
-   RETURN:
-       true .... the thread is a daemon thread
-       false ... the thread is not
-
-*******************************************************************************/
-
-inline static bool thread_is_daemon(threadobject *t)
-{
-       if (t->flags & THREAD_FLAG_DAEMON)
-               return true;
-       else
-               return false;
-}
-
-
-/* thread_current_is_attached **************************************************
-
-   Returns if the current thread is attached to the VM.
-
-   RETURN:
-       true .... the thread is attached to the VM
-       false ... the thread is not
-
-*******************************************************************************/
-
-inline static bool thread_current_is_attached(void)
-{
-       threadobject  *t;
-       bool           result;
-
-       t = thread_get_current();
-
-       if (t == NULL)
-               return false;
-
-       result = thread_is_attached(t);
-
-       return result;
-}
-
-
-/* function prototypes ********************************************************/
-
-void          threads_preinit(void);
-void          threads_init(void);
-
-void          thread_free(threadobject *t);
-
-bool          threads_thread_start_internal(utf *name, functionptr f);
-void          threads_thread_start(java_handle_t *object);
-
-bool          thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
-bool          thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
-bool          thread_detach_current_thread(void);
-
-bool          thread_detach_current_external_thread(void);
-
-void          thread_fprint_name(threadobject *t, FILE *stream);
-void          thread_print_info(threadobject *t);
-
-intptr_t      threads_get_current_tid(void);
-
-void          thread_set_state_runnable(threadobject *t);
-void          thread_set_state_waiting(threadobject *t);
-void          thread_set_state_timed_waiting(threadobject *t);
-void          thread_set_state_terminated(threadobject *t);
-
-threadobject *thread_get_thread(java_handle_t *h);
-
-bool          threads_thread_is_alive(threadobject *t);
-
-void          threads_dump(void);
-
-
-/* implementation specific functions */
-
-void          threads_impl_preinit(void);
-void          threads_impl_init(void);
-
-#if defined(ENABLE_GC_CACAO)
-void          threads_mutex_gc_lock(void);
-void          threads_mutex_gc_unlock(void);
-#endif
-
-void          threads_mutex_join_lock(void);
-void          threads_mutex_join_unlock(void);
-
-void          threads_impl_thread_init(threadobject *t);
-void          threads_impl_thread_clear(threadobject *t);
-void          threads_impl_thread_reuse(threadobject *t);
-void          threads_impl_thread_free(threadobject *t);
-void          threads_impl_thread_start(threadobject *thread, functionptr f);
-
-void          threads_yield(void);
-
-#endif /* ENABLE_THREADS */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _THREAD_H */
-
-
-/*
- * 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
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/threads/thread.hpp b/src/threads/thread.hpp
new file mode 100644 (file)
index 0000000..da58205
--- /dev/null
@@ -0,0 +1,381 @@
+/* src/threads/thread.hpp - machine independent thread functions
+
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _THREAD_HPP
+#define _THREAD_HPP
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vmcore/system.h"
+
+#include "threads/mutex.hpp"
+
+#if defined(ENABLE_THREADS)
+# include "threads/posix/thread-posix.hpp"
+#else
+# include "threads/none/thread-none.h"
+#endif
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "native/jni.h"
+#include "native/llni.h"
+
+#include "vmcore/utf8.h"
+
+
+/* only define the following stuff with thread enabled ************************/
+
+#if defined(ENABLE_THREADS)
+
+/* thread states **************************************************************/
+
+#define THREAD_STATE_NEW              0
+#define THREAD_STATE_RUNNABLE         1
+#define THREAD_STATE_BLOCKED          2
+#define THREAD_STATE_WAITING          3
+#define THREAD_STATE_TIMED_WAITING    4
+#define THREAD_STATE_TERMINATED       5
+
+
+/* thread priorities **********************************************************/
+
+#define MIN_PRIORITY     1
+#define NORM_PRIORITY    5
+#define MAX_PRIORITY     10
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define DEBUGTHREADS(message, thread) \
+       do { \
+               if (opt_DebugThreads) { \
+                       printf("[Thread %-16s: ", message); \
+                       thread_print_info(thread); \
+                       printf("]\n"); \
+               } \
+       } while (0)
+#else
+# define DEBUGTHREADS(message, thread)
+#endif
+
+
+/* global variables ***********************************************************/
+
+#if defined(__LINUX__)
+/* XXX Remove for exact-GC. */
+extern bool threads_pthreads_implementation_nptl;
+#endif
+
+
+/* inline functions ***********************************************************/
+
+/* thread_get_object ***********************************************************
+
+   Return the Java for the given thread.
+
+   ARGUMENTS:
+       t ... thread
+
+   RETURN:
+       the Java object
+
+*******************************************************************************/
+
+inline static java_handle_t *thread_get_object(threadobject *t)
+{
+       return LLNI_WRAP(t->object);
+}
+
+
+/* threads_thread_set_object ***************************************************
+
+   Set the Java object for the given thread.
+
+   ARGUMENTS:
+       t ... thread
+          o ... Java object
+
+*******************************************************************************/
+
+inline static void thread_set_object(threadobject *t, java_handle_t *o)
+{
+       t->object = LLNI_DIRECT(o);
+}
+
+
+/* thread_get_current_object **************************************************
+
+   Return the Java object of the current thread.
+   
+   RETURN VALUE:
+       the Java object
+
+*******************************************************************************/
+
+inline static java_handle_t *thread_get_current_object(void)
+{
+       threadobject  *t;
+       java_handle_t *o;
+
+       t = THREADOBJECT;
+       o = thread_get_object(t);
+
+       return o;
+}
+
+
+/* cacaothread_get_state *******************************************************
+
+   Returns the current state of the given thread.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN:
+       thread state
+
+*******************************************************************************/
+
+inline static int cacaothread_get_state(threadobject *t)
+{
+       return t->state;
+}
+
+
+/* thread_is_attached **********************************************************
+
+   Returns if the given thread is attached to the VM.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN:
+       true .... the thread is attached to the VM
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_is_attached(threadobject *t)
+{
+       java_handle_t *o;
+
+       o = thread_get_object(t);
+
+       if (o != NULL)
+               return true;
+       else
+               return false;
+}
+
+
+/* thread_is_interrupted *******************************************************
+
+   Check if the given thread has been interrupted.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN VALUE:
+      true, if the given thread had been interrupted
+
+*******************************************************************************/
+
+inline static bool thread_is_interrupted(threadobject *t)
+{
+       bool interrupted;
+
+       /* We need the mutex because classpath will call this function when
+          a blocking system call is interrupted. The mutex ensures that it will
+          see the correct value for the interrupted flag. */
+
+#ifdef __cplusplus
+       t->waitmutex->lock();
+       interrupted = t->interrupted;
+       t->waitmutex->unlock();
+#else
+       Mutex_lock(t->waitmutex);
+       interrupted = t->interrupted;
+       Mutex_unlock(t->waitmutex);
+#endif
+
+       return interrupted;
+}
+
+
+/* thread_set_interrupted ******************************************************
+
+   Set the interrupted flag to the given value.
+
+   ARGUMENTS:
+       interrupted ... value to set
+
+*******************************************************************************/
+
+inline static void thread_set_interrupted(threadobject *t, bool interrupted)
+{
+#ifdef __cplusplus
+       t->waitmutex->lock();
+       t->interrupted = interrupted;
+       t->waitmutex->unlock();
+#else
+       Mutex_lock(t->waitmutex);
+       t->interrupted = interrupted;
+       Mutex_unlock(t->waitmutex);
+#endif
+}
+
+
+/* thread_is_daemon ************************************************************
+
+   Returns if the given thread is a daemon thread.
+
+   ARGUMENTS:
+       t ... the thread to check
+
+   RETURN:
+       true .... the thread is a daemon thread
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_is_daemon(threadobject *t)
+{
+       if (t->flags & THREAD_FLAG_DAEMON)
+               return true;
+       else
+               return false;
+}
+
+
+/* thread_current_is_attached **************************************************
+
+   Returns if the current thread is attached to the VM.
+
+   RETURN:
+       true .... the thread is attached to the VM
+       false ... the thread is not
+
+*******************************************************************************/
+
+inline static bool thread_current_is_attached(void)
+{
+       threadobject  *t;
+       bool           result;
+
+       t = thread_get_current();
+
+       if (t == NULL)
+               return false;
+
+       result = thread_is_attached(t);
+
+       return result;
+}
+
+
+/* function prototypes ********************************************************/
+
+void          threads_preinit(void);
+void          threads_init(void);
+
+void          thread_free(threadobject *t);
+
+bool          threads_thread_start_internal(utf *name, functionptr f);
+void          threads_thread_start(java_handle_t *object);
+
+bool          thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool          thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
+bool          thread_detach_current_thread(void);
+
+bool          thread_detach_current_external_thread(void);
+
+void          thread_fprint_name(threadobject *t, FILE *stream);
+void          thread_print_info(threadobject *t);
+
+intptr_t      threads_get_current_tid(void);
+
+void          thread_set_state_runnable(threadobject *t);
+void          thread_set_state_waiting(threadobject *t);
+void          thread_set_state_timed_waiting(threadobject *t);
+void          thread_set_state_terminated(threadobject *t);
+
+threadobject *thread_get_thread(java_handle_t *h);
+
+bool          threads_thread_is_alive(threadobject *t);
+
+void          threads_dump(void);
+
+
+/* implementation specific functions */
+
+void          threads_impl_preinit(void);
+void          threads_impl_init(void);
+
+#if defined(ENABLE_GC_CACAO)
+void          threads_mutex_gc_lock(void);
+void          threads_mutex_gc_unlock(void);
+#endif
+
+void          threads_mutex_join_lock(void);
+void          threads_mutex_join_unlock(void);
+
+void          threads_impl_thread_init(threadobject *t);
+void          threads_impl_thread_clear(threadobject *t);
+void          threads_impl_thread_reuse(threadobject *t);
+void          threads_impl_thread_free(threadobject *t);
+void          threads_impl_thread_start(threadobject *thread, functionptr f);
+
+void          threads_yield(void);
+
+#endif /* ENABLE_THREADS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _THREAD_HPP
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index 29f192afd5997644fe46f770eaa3f450b6e04914..ccb71e7eeb08fc6c7b8ebfbce566fa7d06a33e84 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "threads/mutex.hpp"
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/list.h"
 
index a72ca178013646dd36aa182953ed1b1bb447bc73..6f2ae0adefa29d277fc7fbc64829fa3a82df3dc1 100644 (file)
@@ -34,7 +34,7 @@
 extern "C" {
 #endif
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 
 /* function prototypes ********************************************************/
index c9fea656a0933c2942b683ff8ddd6640008f5f6d..6bba493a7757db115e78695d52d1776b5f45f735 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
index cf1cc0fe7e43bfacab82c8d03a344d3b0970503e..5c50d4620e24f78a74353b695441810e666b8b0f 100644 (file)
@@ -54,7 +54,7 @@
 #include "native/llni.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
index 7de6e3b52bcefe02bd1135b005035597810dd8e3..51e713681ee7509ad98db021240084b55ed09a26 100644 (file)
@@ -46,7 +46,7 @@
 #include "native/include/java_lang_Throwable.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/util.h"
 
index d6576eb32fddf721947738d3ddc84a5b222c3156..7bc81abb6868245afd13bb1cb67d607a35b063ac 100644 (file)
@@ -32,7 +32,7 @@
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index fb1b41005943ff079f0c48388106f144a89bd934..57e4f4b1c828ea03348980e8828179c00ae8f82f 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/alpha/md.h"
 #include "vm/jit/alpha/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
index 9775b3f11f255e798cbe497b0b55216f92ff8f36..6881697368e078231db566b10341b48d884facc1 100644 (file)
@@ -49,7 +49,7 @@ typedef struct ucontext {
 
 #define scontext_t struct sigcontext
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
index 25219932000538ed1196f6639ffa312788c6aeae..59eda45b7aff8aef12c6597687e0310c4552f054 100644 (file)
@@ -75,7 +75,7 @@
 
 #include "native/include/java_lang_Class.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index 708a2ddab8a2be4977e1690ca0e0006f081d2645..3af43dbb4163e0a1d7d7724561c1c456917f48db 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/global.h"
index e5f6d8f37429c4d2f66154d06f9e5c8aad09cfc7..99204eae081fefd4607573db44669aea5d5ebf11 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
index ee78ecc48d4b15411828f645050d2894db94e99e..b279afa4cc06af74d01fe910f7d1c0735581240b 100644 (file)
@@ -33,7 +33,7 @@
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
index 210d9459903b1882db1b688cbb2ddf7b7a845ddb..0724b86fdeb091d500874998221c9ec32d21f831 100644 (file)
@@ -35,7 +35,7 @@
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index 6bba262c8a44dad463058bf077ab57534ee1ce34..467605806be2df9fadd9b23244d7bb5864882534 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "arch.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index 324073eacffb3080ced6210e5e58efbb3a3216dc..67511e1bf764ed2ae8b5bf544251c96262dc3b0a 100644 (file)
@@ -39,7 +39,7 @@
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index 262804ecb52002501a11a405510061e29fd867c4..0cb513794b8f5998e0979b414544f812b6356bea 100644 (file)
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
-
 #include "toolbox/avl.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodtree.h"
+#include "vm/jit/stacktrace.hpp"
 
 
 /* methodtree_element *********************************************************/
index 319b2289a7fe41f03d8b9a561b1e641c10740c58..7923f9e95724cc8d16a95376b502f3690c70da1a 100644 (file)
@@ -33,7 +33,7 @@
 #include "mm/memory.h"
 
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/stringlocal.h"
index aa61989136de157bb5bf04a944fa5e4389a78fff..9ef7970a3e4c6f0eaa89e2b865109d140d8d4d87 100644 (file)
@@ -33,7 +33,7 @@
 #include "mm/memory.h"
 
 #include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/list.h"
 
index a4f16f77579b375fe6fc63a9b9bd19a36fa7ddf7..d7b8e3cabe29771aea5a841cdc481d2cddbca196 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/powerpc/codegen.h"
 #include "vm/jit/powerpc/darwin/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index af37cd4d38ea16bb9a34e1fed9d425dec7c177c9..191e2d2db93922cf283a44f827c54702af11ea6e 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/powerpc/md.h"
 #include "vm/jit/powerpc/linux/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index 3ffba6f22e542362acb4d9d6474cfb445fc8cec1..ab2a1c485a3aac2e357836e34570b5da1634561b 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/powerpc64/md.h"
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
index 0c1b15072bd6d45171a9f9625272de96c4551d79..913e18a78dc1992c5d2868a15d677612f4a839a8 100644 (file)
@@ -38,7 +38,7 @@
 
 #include "mm/memory.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index 3b6249907a84e01ae32c76ddd7386f4d29918300..40dd9c2744c814ef100f26e38e53a727c4d65cd5 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "vm/jit/s390/md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
index d126c9df0fd797978c0b4dd54dee744768ea7604..6cd12f0f7c2e7365c9f58598ce388020d5f50894 100644 (file)
@@ -51,7 +51,7 @@
 #if defined(ENABLE_DEBUG_FILTER)
 # include <sys/types.h>
 # include <regex.h>
-# include "threads/thread.h"
+# include "threads/thread.hpp"
 #endif
 
 
index bd4174f0156a2181de979a238a80ee021029fa4a..79fc691c4f96407faba75db0879388dc1eeef108 100644 (file)
@@ -51,7 +51,7 @@
 # include "native/include/java_lang_VMThrowable.h"
 #endif
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index f233ecffae65b25392df9dee05c37f46a2d7f8e7..6b6de10d40f70467f2974ff851c8d24d228fd8a7 100644 (file)
@@ -45,7 +45,7 @@ typedef struct stacktrace_t       stacktrace_t;
 
 #include "md-abi.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/global.h"
 
index 164732485ebc88818ea48663281215afd8e2fe1e..79faed007bdb20a6f0dd8562f3be5501e119445c 100644 (file)
@@ -41,7 +41,7 @@ extern "C" {
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"
 
index 7850ea9d81cccc6d7026c4b6ebc862d65bc3094b..4b683342a409e8298af3c8e412e57cb0b6db21e5 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdlib.h>
 #include <ucontext.h>
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/signallocal.h"
 
index ce372761badd3d09c6fd7fe26d792e9533ce49b3..38d1306e6c953e700a2850379f96c728b9421cb2 100644 (file)
@@ -37,7 +37,7 @@
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
index a8f6a5990b6a1b9ecb56221e25cf93a4a9e1b2c1..5619c9b04087be24fc6b891aa3a27512ba3052b1 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/md.h"
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/builtin.h"
 #include "vm/signallocal.h"
index a07fed5b1fc1789ba41cddfa945e11dab483aa31..95956fe94317164e7176e0376d1152ca2c5214ef 100644 (file)
@@ -43,7 +43,7 @@
 # include "mm/memory.h"
 #endif
 
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "vm/exceptions.h"
 #include "vm/signallocal.h"
index 2e03a1e8780db221bff394eec9ce0a798372346b..3ff11acfe99ab9b49a265a117d5922d10bbabf5b 100644 (file)
@@ -63,7 +63,7 @@
 
 #include "threads/lock-common.h"
 #include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
 
 #include "toolbox/logging.h"