X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fthreads%2Fthread.cpp;h=b111ca90f70bdaf74e9f073f93bf49e970ed65e0;hb=ac631c42adf26cee868135fc74401039099fe5ee;hp=8d06573aeb3eca8c511dcd4120f0febe92762886;hpb=791669a46573669e92bfa7d6eb4ce97836d84a50;p=cacao.git diff --git a/src/threads/thread.cpp b/src/threads/thread.cpp index 8d06573ae..b111ca90f 100644 --- a/src/threads/thread.cpp +++ b/src/threads/thread.cpp @@ -1,6 +1,6 @@ /* src/threads/thread.cpp - machine independent thread functions - Copyright (C) 2007, 2008 + Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -31,7 +31,7 @@ #include "vm/types.h" -#include "mm/memory.h" +#include "mm/memory.hpp" #if defined(ENABLE_GC_BOEHM) /* We need to include Boehm's gc.h here for GC_register_my_thread and @@ -39,36 +39,31 @@ # include "mm/boehm-gc/include/gc.h" #endif -#include "native/jni.h" #include "native/llni.h" -#include "native/native.h" +#include "native/native.hpp" -#include "threads/lock-common.h" -#include "threads/threadlist.h" +#include "threads/lock.hpp" +#include "threads/threadlist.hpp" #include "threads/thread.hpp" -#include "vm/builtin.h" +#include "vm/jit/builtin.hpp" +#include "vm/class.hpp" #include "vm/exceptions.hpp" +#include "vm/finalizer.hpp" +#include "vm/globals.hpp" +#include "vm/javaobjects.hpp" +#include "vm/method.hpp" +#include "vm/options.h" #include "vm/string.hpp" +#include "vm/utf8.h" #include "vm/vm.hpp" -#include "vm/jit/stacktrace.hpp" - -#include "vmcore/class.h" -#include "vmcore/globals.hpp" -#include "vmcore/javaobjects.hpp" -#include "vmcore/method.h" -#include "vmcore/options.h" - #if defined(ENABLE_STATISTICS) -# include "vmcore/statistics.h" +# include "vm/statistics.h" #endif -#include "vmcore/utf8.h" - +#include "vm/jit/stacktrace.hpp" -// FIXME -extern "C" { /* global variables ***********************************************************/ @@ -84,9 +79,8 @@ bool threads_pthreads_implementation_nptl; /* static functions ***********************************************************/ -static void thread_create_initial_threadgroups(void); static void thread_create_initial_thread(void); -static threadobject *thread_new(void); +static threadobject *thread_new(int32_t flags); /* threads_preinit ************************************************************* @@ -144,7 +138,11 @@ void threads_preinit(void) /* Create internal thread data-structure for the main thread. */ - mainthread = thread_new(); + mainthread = thread_new(THREAD_FLAG_JAVA); + + /* Add the thread to the thread list. */ + + ThreadList::add_to_active_thread_list(mainthread); /* The main thread should always have index 1. */ @@ -152,9 +150,8 @@ void threads_preinit(void) vm_abort("threads_preinit: main thread index not 1: %d != 1", mainthread->index); - /* thread is a Java thread and running */ + /* Thread is already running. */ - mainthread->flags |= THREAD_FLAG_JAVA; mainthread->state = THREAD_STATE_RUNNABLE; /* Store the internal thread data-structure in the TSD. */ @@ -175,40 +172,11 @@ void threads_init(void) /* Create the system and main thread groups. */ - thread_create_initial_threadgroups(); + ThreadRuntime::thread_create_initial_threadgroups(&threadgroup_main, &threadgroup_system); /* 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 + thread_method_init = ThreadRuntime::get_thread_init_method(); if (thread_method_init == NULL) vm_abort("threads_init: failed to resolve thread init method"); @@ -245,160 +213,9 @@ static bool thread_create_object(threadobject *t, java_handle_t *name, java_hand // Set the Java object in the thread data-structure. This // indicates that the thread is attached to the VM. - thread_set_object(t, jlt.get_handle()); - -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - h = builtin_new(class_java_lang_VMThread); - - if (h == NULL) - return false; - - // Create and initialize a java.lang.VMThread object. - java_lang_VMThread jlvmt(h, jlt.get_handle(), t); - - /* Call: - java.lang.Thread.(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */ - - bool isdaemon = thread_is_daemon(t); - - (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(), - name, NORM_PRIORITY, isdaemon); - - if (exceptions_get_exception()) - return false; - - // Set the ThreadGroup in the Java thread object. - jlt.set_group(group); - - /* Add thread to the threadgroup. */ - - classinfo* c; - LLNI_class_get(group, c); - - methodinfo* 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, jlt.get_handle()); - - 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. 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.(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. - jlt.set_vm_thread(t); - - // Call: public Thread(Ljava/lang/String;)V - (void) vm_call_method(thread_method_init, jlt.get_handle(), name); - - if (exceptions_get_exception()) - return false; - -#else -# error unknown classpath configuration -#endif + t->object = LLNI_DIRECT(jlt.get_handle()); - 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 + return ThreadRuntime::invoke_thread_initializer(jlt, t, thread_method_init, name, group); } @@ -416,7 +233,7 @@ static void thread_create_initial_thread(void) /* Get the main-thread (NOTE: The main thread is always the first thread in the list). */ - t = threadlist_first(); + t = ThreadList::get_main_thread(); /* The thread name. */ @@ -451,28 +268,28 @@ static void thread_create_initial_thread(void) *******************************************************************************/ -static threadobject *thread_new(void) +static threadobject *thread_new(int32_t flags) { int32_t index; threadobject *t; /* Lock the thread lists */ - threadlist_lock(); + ThreadList::lock(); - index = threadlist_get_free_index(); + index = ThreadList::get_free_thread_index(); /* Allocate a thread data structure. */ /* First, try to get one from the free-list. */ - t = threadlist_free_first(); + t = ThreadList::get_free_thread(); - if (t != NULL) { - /* Remove from free list. */ + /* Unlock the thread lists. */ - threadlist_free_remove(t); + ThreadList::unlock(); + if (t != NULL) { /* Equivalent of MZERO on the else path */ threads_impl_thread_clear(t); @@ -493,6 +310,20 @@ static threadobject *thread_new(void) MZERO(t, threadobject, 1); + // Initialize the mutex and the condition. + t->flc_lock = new Mutex(); + t->flc_cond = new Condition(); + + t->waitmutex = new Mutex(); + t->waitcond = new Condition(); + + t->suspendmutex = new Mutex(); + t->suspendcond = new Condition(); + +#if defined(ENABLE_TLH) + tlh_init(&(t->tlh)); +#endif + #if defined(ENABLE_GC_CACAO) /* Register reference to java.lang.Thread with the GC. */ /* FIXME is it ok to do this only once? */ @@ -501,9 +332,7 @@ static threadobject *thread_new(void) gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT); #endif - /* Initialize the implementation-specific bits. */ - - threads_impl_thread_init(t); + t->_dumpmemory = new DumpMemory(); } /* Pre-compute the thinlock-word. */ @@ -511,8 +340,8 @@ static threadobject *thread_new(void) assert(index != 0); t->index = index; - t->thinlock = lock_pre_compute_thinlock(t->index); - t->flags = 0; + t->thinlock = Lockword::pre_compute_thinlock(t->index); + t->flags = flags; t->state = THREAD_STATE_NEW; #if defined(ENABLE_GC_CACAO) @@ -523,14 +352,6 @@ static threadobject *thread_new(void) threads_impl_thread_reuse(t); - /* Add the thread to the thread list. */ - - threadlist_add(t); - - /* Unlock the thread lists. */ - - threadlist_unlock(); - return t; } @@ -548,29 +369,15 @@ static threadobject *thread_new(void) 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); + java_handle_t *h = LLNI_WRAP(t->object); + java_lang_Thread jlt(h); + ThreadRuntime::clear_heap_reference(jlt); /* 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); + t->object = 0; - /* Unlock the thread lists. */ - - threadlist_unlock(); + ThreadList::deactivate_thread(t); } @@ -585,31 +392,32 @@ void thread_free(threadobject *t) *******************************************************************************/ +static void thread_cleanup_finalizer(java_handle_t *h, void *data) +{ + threadobject *t = reinterpret_cast(data); + ThreadList::release_thread(t, false); +} + 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; + t = thread_new(THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON); - /* The thread is flagged as (non-)daemon thread, we can leave the - mutex. */ + /* Add the thread to the thread list. */ - threads_mutex_join_unlock(); + ThreadList::add_to_active_thread_list(t); /* Create the Java thread object. */ - if (!thread_create_object(t, javastring_new(name), threadgroup_system)) + if (!thread_create_object(t, javastring_new(name), threadgroup_system)) { + ThreadList::release_thread(t, true); return false; + } + + Finalizer::attach_custom_finalizer(LLNI_WRAP(t->object), thread_cleanup_finalizer, t); /* Start the thread. */ @@ -635,57 +443,31 @@ void threads_thread_start(java_handle_t *object) { java_lang_Thread jlt(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. */ - threadobject* t = thread_new(); - - /* this is a normal Java thread */ - - t->flags |= THREAD_FLAG_JAVA; - + u4 flags = THREAD_FLAG_JAVA; #if defined(ENABLE_JAVASE) /* Is this a daemon thread? */ - if (jlt.get_daemon() == true) - t->flags |= THREAD_FLAG_DAEMON; + if (jlt.get_daemon()) + flags |= THREAD_FLAG_DAEMON; #endif - /* The thread is flagged and (non-)daemon thread, we can leave the - mutex. */ - - threads_mutex_join_unlock(); + threadobject* t = thread_new(flags); /* 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. */ - java_lang_VMThread jlvmt(jlt.get_vmThread()); - - assert(jlvmt.get_handle() != NULL); - assert(jlvmt.get_vmdata() == NULL); + t->object = LLNI_DIRECT(object); - jlvmt.set_vmdata(t); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) + /* Add the thread to the thread list. */ - // Nothing to do. + ThreadList::add_to_active_thread_list(t); -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1) + Atomic::write_memory_barrier(); - jlt.set_vm_thread(t); + ThreadRuntime::setup_thread_vmdata(jlt, t); -#else -# error unknown classpath configuration -#endif + Finalizer::attach_custom_finalizer(LLNI_WRAP(t->object), thread_cleanup_finalizer, t); /* Start the thread. Don't pass a function pointer (NULL) since we want Thread.run()V here. */ @@ -719,22 +501,13 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon) 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; - + u4 flags = THREAD_FLAG_JAVA; if (isdaemon) - t->flags |= THREAD_FLAG_DAEMON; + flags |= THREAD_FLAG_DAEMON; + + t = thread_new(flags); /* Store the internal thread data-structure in the TSD. */ @@ -743,7 +516,9 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon) /* The thread is flagged and (non-)daemon thread, we can leave the mutex. */ - threads_mutex_join_unlock(); + /* Add the thread to the thread list. */ + + ThreadList::add_to_active_thread_list(t); DEBUGTHREADS("attaching", t); @@ -783,8 +558,10 @@ bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon) /* Create the Java thread object. */ - if (!thread_create_object(t, name, group)) + if (!thread_create_object(t, name, group)) { + ThreadList::release_thread(t, true); return false; + } /* The thread is completely initialized. */ @@ -810,9 +587,7 @@ bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isda #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.*/ @@ -860,7 +635,7 @@ bool thread_detach_current_external_thread(void) the thread allocates any memory from the GC heap. */ /* Don't detach the main thread. This is a workaround for - OpenJDK's java binary. */ + OpenJDK's java launcher. */ if (thread_get_current()->index != 1) GC_unregister_my_thread(); #endif @@ -881,27 +656,12 @@ bool thread_detach_current_external_thread(void) void thread_fprint_name(threadobject *t, FILE *stream) { - if (thread_get_object(t) == NULL) + if (LLNI_WRAP(t->object) == NULL) vm_abort(""); - java_lang_Thread jlt(thread_get_object(t)); - -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) + java_lang_Thread jlt(LLNI_WRAP(t->object)); - java_handle_t* name = jlt.get_name(); - javastring_fprint(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[]. */ - java_chararray_t *name; - - /* FIXME This prints to stdout. */ - utf_display_printable_ascii(utf_null); - -#else -# error unknown classpath configuration -#endif + ThreadRuntime::print_thread_name(jlt, stream); } @@ -916,7 +676,7 @@ void thread_fprint_name(threadobject *t, FILE *stream) void thread_print_info(threadobject *t) { - java_lang_Thread jlt(thread_get_object(t)); + java_lang_Thread jlt(LLNI_WRAP(t->object)); /* Print as much as we can when we are in state NEW. */ @@ -967,6 +727,12 @@ void thread_print_info(threadobject *t) case THREAD_STATE_TIMED_WAITING: printf(" waiting on condition"); break; + case THREAD_STATE_PARKED: + printf(" parked"); + break; + case THREAD_STATE_TIMED_PARKED: + printf(" timed parked"); + break; case THREAD_STATE_TERMINATED: printf(" terminated"); break; @@ -1000,6 +766,21 @@ intptr_t threads_get_current_tid(void) } +/** + * Set the current state of the given thread. This method should only + * be called while holding the threadlist-lock and after checking that + * the new state is valid. It is best to not call this method directly + * but call the specific setter methods below. + */ +static inline void thread_set_state(threadobject *t, int state) +{ + // Set the state of our internal threadobject. + t->state = state; + + ThreadRuntime::set_javathread_state(t, state); +} + + /* thread_set_state_runnable *************************************************** Set the current state of the given thread to THREAD_STATE_RUNNABLE. @@ -1011,17 +792,11 @@ intptr_t threads_get_current_tid(void) 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; + thread_set_state(t, THREAD_STATE_RUNNABLE); DEBUGTHREADS("is RUNNABLE", t); } - - threadlist_unlock(); } @@ -1036,17 +811,11 @@ void thread_set_state_runnable(threadobject *t) 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; + thread_set_state(t, THREAD_STATE_WAITING); DEBUGTHREADS("is WAITING", t); } - - threadlist_unlock(); } @@ -1062,17 +831,49 @@ void thread_set_state_waiting(threadobject *t) void thread_set_state_timed_waiting(threadobject *t) { - /* Set the state inside a lock. */ + if (t->state != THREAD_STATE_TERMINATED) { + thread_set_state(t, THREAD_STATE_TIMED_WAITING); + + DEBUGTHREADS("is TIMED_WAITING", t); + } +} + - threadlist_lock(); +/* thread_set_state_parked ***************************************************** + Set the current state of the given thread to THREAD_STATE_PARKED. + + NOTE: If the thread has already terminated, don't set the state. + This is important for threads_detach_thread. + +*******************************************************************************/ + +void thread_set_state_parked(threadobject *t) +{ if (t->state != THREAD_STATE_TERMINATED) { - t->state = THREAD_STATE_TIMED_WAITING; + thread_set_state(t, THREAD_STATE_PARKED); - DEBUGTHREADS("is TIMED_WAITING", t); + DEBUGTHREADS("is PARKED", t); } +} - threadlist_unlock(); + +/* thread_set_state_timed_parked *********************************************** + + Set the current state of the given thread to THREAD_STATE_TIMED_PARKED. + + NOTE: If the thread has already terminated, don't set the state. + This is important for threads_detach_thread. + +*******************************************************************************/ + +void thread_set_state_timed_parked(threadobject *t) +{ + if (t->state != THREAD_STATE_TERMINATED) { + thread_set_state(t, THREAD_STATE_TIMED_PARKED); + + DEBUGTHREADS("is TIMED_PARKED", t); + } } @@ -1087,13 +888,9 @@ void thread_set_state_terminated(threadobject *t) { /* Set the state inside a lock. */ - threadlist_lock(); - - t->state = THREAD_STATE_TERMINATED; + thread_set_state(t, THREAD_STATE_TERMINATED); DEBUGTHREADS("is TERMINATED", t); - - threadlist_unlock(); } @@ -1107,42 +904,15 @@ void thread_set_state_terminated(threadobject *t) RETURN VALUE: the thread object + NOTE: + Usage of this function without the thread list lock held is + almost certainly a bug. + *******************************************************************************/ threadobject *thread_get_thread(java_handle_t *h) { -#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) - - java_lang_VMThread jlvmt(h); - threadobject* t = jlvmt.get_vmdata(); - -#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) - - /* XXX This is just a quick hack. */ - threadobject* t; - bool equal; - - 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!"); - threadobject* t = NULL; - -#else -# error unknown classpath configuration -#endif - - return t; + return ThreadRuntime::get_threadobject_from_thread(h); } @@ -1167,6 +937,8 @@ bool threads_thread_is_alive(threadobject *t) case THREAD_STATE_BLOCKED: case THREAD_STATE_WAITING: case THREAD_STATE_TIMED_WAITING: + case THREAD_STATE_PARKED: + case THREAD_STATE_TIMED_PARKED: return true; default: @@ -1178,65 +950,109 @@ bool threads_thread_is_alive(threadobject *t) return false; } +/* thread_is_interrupted ******************************************************* -/* threads_dump **************************************************************** + Check if the given thread has been interrupted. - Dumps info for all threads running in the JVM. This function is - called when SIGQUIT (-\) is sent to CACAO. + ARGUMENTS: + t ... the thread to check + + RETURN VALUE: + true, if the given thread had been interrupted *******************************************************************************/ -void threads_dump(void) +bool thread_is_interrupted(threadobject *t) { - threadobject *t; + /* 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. */ - /* XXX we should stop the world here */ + t->waitmutex->lock(); + bool interrupted = t->interrupted; + t->waitmutex->unlock(); - /* Lock the thread lists. */ + return interrupted; +} - threadlist_lock(); - printf("Full thread dump CACAO "VERSION":\n"); +/* thread_set_interrupted ****************************************************** - /* iterate over all started threads */ + Set the interrupted flag to the given value. - for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) { - /* ignore threads which are in state NEW */ - if (t->state == THREAD_STATE_NEW) - continue; + ARGUMENTS: + interrupted ... value to set -#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 +void thread_set_interrupted(threadobject *t, bool interrupted) +{ + t->waitmutex->lock(); + t->interrupted = interrupted; + t->waitmutex->unlock(); +} - /* Print thread info. */ +/* thread_handle_set_priority ************************************************** - printf("\n"); - thread_print_info(t); - printf("\n"); + Calls threads_set_thread_priority for the threadobject associated + with the thread indicated by handle th, while holding the thread + list lock. - /* Print trace of thread. */ +*******************************************************************************/ - stacktrace_print_of_thread(t); +void thread_handle_set_priority(java_handle_t *th, int priority) +{ + threadobject *t = thread_get_thread(th); + /* For GNU classpath, this should not happen, because both + setPriority() and start() are synchronized. */ + assert(t != 0); + threads_set_thread_priority(t->tid, priority); +} -#if defined(ENABLE_GC_CACAO) - /* Resume the thread. */ +/* thread_handle_is_interrupted ************************************************ - if (threads_resume_thread(t) == false) - vm_abort("threads_dump: threads_resume_thread failed"); -#endif - } + Calls thread_is_interrupted for the threadobject associated with + the thread indicated by handle th, while holding the thread list + lock. - /* Unlock the thread lists. */ +*******************************************************************************/ - threadlist_unlock(); +bool thread_handle_is_interrupted(java_handle_t *th) +{ + threadobject *t = thread_get_thread(th); + return t ? thread_is_interrupted(t) : false; } -} // extern "C" +/* thread_handle_interrupt ***************************************************** + + Calls threads_thread_interrupt for the threadobject associated with + the thread indicated by handle th, while holding the thread list + lock. + +*******************************************************************************/ + +void thread_handle_interrupt(java_handle_t *th) +{ + threadobject *t = thread_get_thread(th); + /* For GNU classpath, this should not happen, because both + interrupt() and start() are synchronized. */ + assert(t != 0); + threads_thread_interrupt(t); +} + +/* thread_handle_get_state ***************************************************** + + Calls cacaothread_get_state for the threadobject associated with + the thread indicated by handle th, while holding the thread list + lock. + +*******************************************************************************/ + +int thread_handle_get_state(java_handle_t *th) +{ + threadobject *t = thread_get_thread(th); + return t ? cacaothread_get_state(t) : THREAD_STATE_NEW; +} /*