* 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
#include "vm/types.h"
#include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "compact.h"
#include "copy.h"
#include "config.h"
#include "vm/types.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/list.h"
#include "vm/jit/replace.h"
#include "mm/memory.h"
#include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#include "config.h"
#include "vm/types.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/jit/replace.h"
#include "vmcore/method.h"
#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"
#include "mm/dumpmemory.h"
#include "mm/memory.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vmcore/options.h"
#include "native/native.h"
#include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#endif
#include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#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>
#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>
#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"
#include <assert.h>
-#include "threads/thread.h"
+#include "threads/thread.hpp"
/* LLNI critical sections ******************************************************
#include "native/localref.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
/* LLNI macros *****************************************************************
#include "native/localref.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#include "native/include/java_lang_Thread.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
-/* 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
#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"
#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"
mutex.hpp \
threadlist.c \
threadlist.h \
- thread.c \
- thread.h
+ thread.cpp \
+ thread.hpp
else
libthreads_la_SOURCES =
endif
#include <stdint.h>
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/jit/stacktrace.hpp"
#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"
#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"
+++ /dev/null
-/* 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:
- */
--- /dev/null
+/* 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:
+ */
+++ /dev/null
-/* 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:
- */
--- /dev/null
+/* 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:
+ */
#include "threads/mutex.hpp"
#include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/list.h"
extern "C" {
#endif
-#include "threads/thread.h"
+#include "threads/thread.hpp"
/* function prototypes ********************************************************/
#include "mm/memory.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#include "toolbox/util.h"
#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"
#include "native/include/java_lang_Throwable.h"
#include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/util.h"
#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"
#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"
#define scontext_t struct sigcontext
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/exceptions.h"
#include "vm/signallocal.h"
#include "native/include/java_lang_Class.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#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"
#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"
#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"
#include "mm/memory.h"
#include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#include "arch.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "mm/memory.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/builtin.h"
#include "vm/exceptions.h"
#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 *********************************************************/
#include "mm/memory.h"
#include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/builtin.h"
#include "vm/stringlocal.h"
#include "mm/memory.h"
#include "threads/lock-common.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/list.h"
#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"
#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"
#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"
#include "mm/memory.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#include "vm/jit/s390/md-abi.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/exceptions.h"
#include "vm/signallocal.h"
#if defined(ENABLE_DEBUG_FILTER)
# include <sys/types.h>
# include <regex.h>
-# include "threads/thread.h"
+# include "threads/thread.hpp"
#endif
# include "native/include/java_lang_VMThrowable.h"
#endif
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"
#include "md-abi.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/global.h"
#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"
#include <stdlib.h>
#include <ucontext.h>
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/signallocal.h"
#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"
#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"
# include "mm/memory.h"
#endif
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "vm/exceptions.h"
#include "vm/signallocal.h"
#include "threads/lock-common.h"
#include "threads/threadlist.h"
-#include "threads/thread.h"
+#include "threads/thread.hpp"
#include "toolbox/logging.h"