1 /* src/threads/thread.cpp - machine independent thread functions
3 Copyright (C) 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/memory.h"
36 #if defined(ENABLE_GC_BOEHM)
37 /* We need to include Boehm's gc.h here for GC_register_my_thread and
39 # include "mm/boehm-gc/include/gc.h"
42 #include "native/jni.h"
43 #include "native/llni.h"
44 #include "native/native.h"
46 #include "native/include/java_lang_Object.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Thread.h"
50 #if defined(ENABLE_JAVASE)
51 # include "native/include/java_lang_ThreadGroup.h"
54 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
55 # include "native/include/java_lang_VMThread.h"
58 #include "threads/lock-common.h"
59 #include "threads/threadlist.h"
60 #include "threads/thread.hpp"
62 #include "vm/builtin.h"
63 #include "vm/exceptions.hpp"
64 #include "vm/string.hpp"
67 #include "vm/jit/stacktrace.hpp"
69 #include "vmcore/class.h"
70 #include "vmcore/globals.hpp"
71 #include "vmcore/method.h"
72 #include "vmcore/options.h"
74 #if defined(ENABLE_STATISTICS)
75 # include "vmcore/statistics.h"
78 #include "vmcore/utf8.h"
84 /* global variables ***********************************************************/
86 static methodinfo *thread_method_init;
87 static java_handle_t *threadgroup_system;
88 static java_handle_t *threadgroup_main;
90 #if defined(__LINUX__)
91 /* XXX Remove for exact-GC. */
92 bool threads_pthreads_implementation_nptl;
96 /* static functions ***********************************************************/
98 static void thread_create_initial_threadgroups(void);
99 static void thread_create_initial_thread(void);
100 static threadobject *thread_new(void);
103 /* threads_preinit *************************************************************
105 Do some early initialization of stuff required.
107 *******************************************************************************/
109 void threads_preinit(void)
111 threadobject *mainthread;
112 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
117 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
119 #if defined(__LINUX__)
120 /* XXX Remove for exact-GC. */
122 /* On Linux we need to check the pthread implementation. */
124 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
125 /* If the glibc is a pre-2.3.2 version, we fall back to
128 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
129 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
131 /* Some systems return as length 0 (maybe cross-compilation
132 related). In this case we also fall back to linuxthreads. */
135 pathbuf = MNEW(char, len);
137 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
139 if (strstr(pathbuf, "NPTL") != NULL)
140 threads_pthreads_implementation_nptl = true;
142 threads_pthreads_implementation_nptl = false;
145 threads_pthreads_implementation_nptl = false;
147 threads_pthreads_implementation_nptl = false;
151 /* Initialize the threads implementation (sets the thinlock on the
154 threads_impl_preinit();
156 /* Create internal thread data-structure for the main thread. */
158 mainthread = thread_new();
160 /* The main thread should always have index 1. */
162 if (mainthread->index != 1)
163 vm_abort("threads_preinit: main thread index not 1: %d != 1",
166 /* thread is a Java thread and running */
168 mainthread->flags |= THREAD_FLAG_JAVA;
169 mainthread->state = THREAD_STATE_RUNNABLE;
171 /* Store the internal thread data-structure in the TSD. */
173 thread_set_current(mainthread);
177 /* threads_init ****************************************************************
179 Initialize the main thread.
181 *******************************************************************************/
183 void threads_init(void)
185 TRACESUBSYSTEMINITIALIZATION("threads_init");
187 /* Create the system and main thread groups. */
189 thread_create_initial_threadgroups();
191 /* Cache the java.lang.Thread initialization method. */
193 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
196 class_resolveclassmethod(class_java_lang_Thread,
198 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
199 class_java_lang_Thread,
202 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
205 class_resolveclassmethod(class_java_lang_Thread,
207 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
208 class_java_lang_Thread,
211 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
214 class_resolveclassmethod(class_java_lang_Thread,
216 utf_java_lang_String__void,
217 class_java_lang_Thread,
221 # error unknown classpath configuration
224 if (thread_method_init == NULL)
225 vm_abort("threads_init: failed to resolve thread init method");
227 thread_create_initial_thread();
231 /* thread_create_object ********************************************************
233 Create a Java thread object for the given thread data-structure,
234 initializes it and adds the thread to the threadgroup.
239 name .... thread name
240 group ... threadgroup
244 *******************************************************************************/
246 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
249 java_lang_Thread *to;
251 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
252 java_lang_VMThread *vmto;
258 /* Create a java.lang.Thread Java object. */
260 o = builtin_new(class_java_lang_Thread);
265 to = (java_lang_Thread *) o;
267 /* Set the Java object in the thread data-structure. This
268 indicates that the thread is attached to the VM. */
270 thread_set_object(t, (java_handle_t *) to);
272 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
274 /* Create a java.lang.VMThread Java object. */
276 vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
281 /* Set the Java thread object in the Java VM-thread object. */
283 LLNI_field_set_ref(vmto, thread, to);
285 /* Set the thread data-structure in the Java VM-thread object. */
287 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
290 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
292 isdaemon = thread_is_daemon(t);
294 (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
297 if (exceptions_get_exception())
300 /* Set the threadgroup in the Java thread object. */
302 LLNI_field_set_ref(to, group, (java_lang_ThreadGroup *) group);
304 /* Add thread to the threadgroup. */
306 LLNI_class_get(group, c);
308 m = class_resolveclassmethod(c,
310 utf_java_lang_Thread__V,
311 class_java_lang_ThreadGroup,
317 (void) vm_call_method(m, group, to);
319 if (exceptions_get_exception())
322 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
324 /* OpenJDK's java.lang.Thread does not have a VMThread field in
325 the class. Nothing to do here. */
327 /* Set the priority. java.lang.Thread.<init> requires it because
328 it sets the priority of the current thread to the parent's one
329 (which is the current thread in this case). */
331 LLNI_field_set_val(to, priority, NORM_PRIORITY);
334 java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
336 (void) vm_call_method(thread_method_init, o, group, name);
338 if (exceptions_get_exception())
341 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
343 /* Set the thread data-structure in the Java thread object. */
345 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
347 /* Call: public Thread(Ljava/lang/String;)V */
349 (void) vm_call_method(thread_method_init, o, name);
351 if (exceptions_get_exception())
355 # error unknown classpath configuration
362 /* thread_create_initial_threadgroups ******************************************
364 Create the initial threadgroups.
367 Create the main threadgroup only and set the system
368 threadgroup to the main threadgroup.
371 Create the system and main threadgroup.
374 This function is a no-op.
376 *******************************************************************************/
378 static void thread_create_initial_threadgroups(void)
380 #if defined(ENABLE_JAVASE)
381 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
383 /* Allocate and initialize the main thread group. */
385 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
387 if (threadgroup_main == NULL)
388 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
390 /* Use the same threadgroup for system as for main. */
392 threadgroup_system = threadgroup_main;
394 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
399 /* Allocate and initialize the system thread group. */
401 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
403 if (threadgroup_system == NULL)
404 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
406 /* Allocate and initialize the main thread group. */
408 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
410 if (threadgroup_main == NULL)
411 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
413 name = javastring_new(utf_main);
415 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
417 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
418 class_java_lang_ThreadGroup,
422 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
424 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
426 if (exceptions_get_exception())
427 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
430 # error unknown classpath configuration
436 /* thread_create_initial_thread ***********************************************
438 Create the initial thread: main
440 *******************************************************************************/
442 static void thread_create_initial_thread(void)
447 /* Get the main-thread (NOTE: The main thread is always the first
448 thread in the list). */
450 t = threadlist_first();
452 /* The thread name. */
454 name = javastring_new(utf_main);
456 #if defined(ENABLE_INTRP)
457 /* create interpreter stack */
460 MSET(intrp_main_stack, 0, u1, opt_stacksize);
461 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
465 /* Create the Java thread object. */
467 if (!thread_create_object(t, name, threadgroup_main))
468 vm_abort("thread_create_initial_thread: failed to create Java object");
470 /* Initialize the implementation specific bits. */
474 DEBUGTHREADS("starting (main)", t);
478 /* thread_new ******************************************************************
480 Allocates and initializes an internal thread data-structure and
481 adds it to the threads list.
483 *******************************************************************************/
485 static threadobject *thread_new(void)
490 /* Lock the thread lists */
494 index = threadlist_get_free_index();
496 /* Allocate a thread data structure. */
498 /* First, try to get one from the free-list. */
500 t = threadlist_free_first();
503 /* Remove from free list. */
505 threadlist_free_remove(t);
507 /* Equivalent of MZERO on the else path */
509 threads_impl_thread_clear(t);
512 #if defined(ENABLE_GC_BOEHM)
513 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
515 t = NEW(threadobject);
518 #if defined(ENABLE_STATISTICS)
520 size_threadobject += sizeof(threadobject);
525 MZERO(t, threadobject, 1);
527 #if defined(ENABLE_GC_CACAO)
528 /* Register reference to java.lang.Thread with the GC. */
529 /* FIXME is it ok to do this only once? */
531 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
532 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
535 /* Initialize the implementation-specific bits. */
537 threads_impl_thread_init(t);
540 /* Pre-compute the thinlock-word. */
545 t->thinlock = lock_pre_compute_thinlock(t->index);
547 t->state = THREAD_STATE_NEW;
549 #if defined(ENABLE_GC_CACAO)
550 t->flags |= THREAD_FLAG_IN_NATIVE;
553 /* Initialize the implementation-specific bits. */
555 threads_impl_thread_reuse(t);
557 /* Add the thread to the thread list. */
561 /* Unlock the thread lists. */
569 /* thread_free *****************************************************************
571 Remove the thread from the threads-list and free the internal
572 thread data structure. The thread index is added to the
573 thread-index free-list.
576 t ... thread data structure
578 *******************************************************************************/
580 void thread_free(threadobject *t)
582 /* Lock the thread lists. */
586 /* Remove the thread from the thread-list. */
588 threadlist_remove(t);
590 /* Add the thread index to the free list. */
592 threadlist_index_add(t->index);
594 /* Set the reference to the Java object to NULL. */
596 thread_set_object(t, NULL);
598 /* Add the thread data structure to the free list. */
600 threadlist_free_add(t);
602 /* Unlock the thread lists. */
608 /* threads_thread_start_internal ***********************************************
610 Start an internal thread in the JVM. No Java thread objects exists
614 name.......UTF-8 name of the thread
615 f..........function pointer to C function to start
617 *******************************************************************************/
619 bool threads_thread_start_internal(utf *name, functionptr f)
623 /* Enter the join-mutex, so if the main-thread is currently
624 waiting to join all threads, the number of non-daemon threads
627 threads_mutex_join_lock();
629 /* Create internal thread data-structure. */
633 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
635 /* The thread is flagged as (non-)daemon thread, we can leave the
638 threads_mutex_join_unlock();
640 /* Create the Java thread object. */
642 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
645 /* Start the thread. */
647 threads_impl_thread_start(t, f);
649 /* everything's ok */
655 /* threads_thread_start ********************************************************
657 Start a Java thread in the JVM. Only the java thread object exists
661 object.....the java thread object java.lang.Thread
663 *******************************************************************************/
665 void threads_thread_start(java_handle_t *object)
667 java_lang_Thread *to;
669 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
670 java_lang_VMThread *vmto;
673 to = (java_lang_Thread *) object;
675 /* Enter the join-mutex, so if the main-thread is currently
676 waiting to join all threads, the number of non-daemon threads
679 threads_mutex_join_lock();
681 /* Create internal thread data-structure. */
685 /* this is a normal Java thread */
687 t->flags |= THREAD_FLAG_JAVA;
689 #if defined(ENABLE_JAVASE)
690 /* Is this a daemon thread? */
692 if (LLNI_field_direct(to, daemon) == true)
693 t->flags |= THREAD_FLAG_DAEMON;
696 /* The thread is flagged and (non-)daemon thread, we can leave the
699 threads_mutex_join_unlock();
701 /* Link the two objects together. */
703 thread_set_object(t, object);
705 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
707 /* Get the java.lang.VMThread object and do some sanity checks. */
709 LLNI_field_get_ref(to, vmThread, vmto);
712 assert(LLNI_field_direct(vmto, vmdata) == NULL);
714 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
716 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
720 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
722 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
725 # error unknown classpath configuration
728 /* Start the thread. Don't pass a function pointer (NULL) since
729 we want Thread.run()V here. */
731 threads_impl_thread_start(t, NULL);
736 * Attaches the current thread to the VM.
738 * @param vm_aargs Attach arguments.
739 * @param isdaemon true if the attached thread should be a daemon
742 * @return true on success, false otherwise.
744 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
750 java_handle_t *group;
752 /* If the current thread has already been attached, this operation
755 result = thread_current_is_attached();
760 /* Enter the join-mutex, so if the main-thread is currently
761 waiting to join all threads, the number of non-daemon threads
764 threads_mutex_join_lock();
766 /* Create internal thread data structure. */
770 /* Thread is a Java thread and running. */
772 t->flags = THREAD_FLAG_JAVA;
775 t->flags |= THREAD_FLAG_DAEMON;
777 /* Store the internal thread data-structure in the TSD. */
779 thread_set_current(t);
781 /* The thread is flagged and (non-)daemon thread, we can leave the
784 threads_mutex_join_unlock();
786 DEBUGTHREADS("attaching", t);
788 /* Get the thread name. */
790 if (vm_aargs != NULL) {
791 u = utf_new_char(vm_aargs->name);
797 name = javastring_new(u);
799 #if defined(ENABLE_JAVASE)
800 /* Get the threadgroup. */
802 if (vm_aargs != NULL)
803 group = (java_handle_t *) vm_aargs->group;
807 /* If no threadgroup was given, use the main threadgroup. */
810 group = threadgroup_main;
813 #if defined(ENABLE_INTRP)
814 /* create interpreter stack */
817 MSET(intrp_main_stack, 0, u1, opt_stacksize);
818 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
822 /* Create the Java thread object. */
824 if (!thread_create_object(t, name, group))
827 /* The thread is completely initialized. */
829 thread_set_state_runnable(t);
836 * Attaches the current external thread to the VM. This function is
837 * called by JNI's AttachCurrentThread.
839 * @param vm_aargs Attach arguments.
840 * @param isdaemon true if the attached thread should be a daemon
843 * @return true on success, false otherwise.
845 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
849 #if defined(ENABLE_GC_BOEHM)
850 struct GC_stack_base sb;
853 #if defined(ENABLE_GC_BOEHM)
854 /* Register the thread with Boehm-GC. This must happen before the
855 thread allocates any memory from the GC heap.*/
857 result = GC_get_stack_base(&sb);
859 if (result != GC_SUCCESS)
860 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
862 GC_register_my_thread(&sb);
865 result = thread_attach_current_thread(vm_aargs, isdaemon);
867 if (result == false) {
868 #if defined(ENABLE_GC_BOEHM)
869 /* Unregister the thread. */
871 GC_unregister_my_thread();
882 * Detaches the current external thread from the VM. This function is
883 * called by JNI's DetachCurrentThread.
885 * @return true on success, false otherwise.
887 bool thread_detach_current_external_thread(void)
891 result = thread_detach_current_thread();
896 #if defined(ENABLE_GC_BOEHM)
897 /* Unregister the thread with Boehm-GC. This must happen after
898 the thread allocates any memory from the GC heap. */
900 /* Don't detach the main thread. This is a workaround for
901 OpenJDK's java binary. */
902 if (thread_get_current()->index != 1)
903 GC_unregister_my_thread();
910 /* thread_fprint_name **********************************************************
912 Print the name of the given thread to the given stream.
915 t ........ thread data-structure
916 stream ... stream to print to
918 *******************************************************************************/
920 void thread_fprint_name(threadobject *t, FILE *stream)
922 java_lang_Thread *to;
924 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
925 java_lang_String *name;
926 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
927 java_chararray_t *name;
930 to = (java_lang_Thread *) thread_get_object(t);
935 LLNI_field_get_ref(to, name, name);
937 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
939 javastring_fprint((java_handle_t *) name, stream);
941 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
943 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
944 /* FIXME This prints to stdout. */
945 utf_display_printable_ascii(utf_null);
948 # error unknown classpath configuration
953 /* thread_print_info ***********************************************************
955 Print information of the passed thread.
958 t ... thread data-structure.
960 *******************************************************************************/
962 void thread_print_info(threadobject *t)
964 java_lang_Thread *to;
967 /* If the thread is currently in initalization, don't print it. */
969 to = (java_lang_Thread *) thread_get_object(t);
971 /* Print as much as we can when we are in state NEW. */
974 /* Print thread name. */
977 thread_fprint_name(t, stdout);
983 if (thread_is_daemon(t))
987 printf(" prio=%d", LLNI_field_direct(to, priority));
990 #if SIZEOF_VOID_P == 8
991 printf(" t=0x%016lx tid=0x%016lx (%ld)",
992 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
994 printf(" t=0x%08x tid=0x%08x (%d)",
995 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
998 printf(" index=%d", t->index);
1000 /* Print thread state. */
1002 state = cacaothread_get_state(t);
1005 case THREAD_STATE_NEW:
1008 case THREAD_STATE_RUNNABLE:
1009 printf(" runnable");
1011 case THREAD_STATE_BLOCKED:
1014 case THREAD_STATE_WAITING:
1017 case THREAD_STATE_TIMED_WAITING:
1018 printf(" waiting on condition");
1020 case THREAD_STATE_TERMINATED:
1021 printf(" terminated");
1024 vm_abort("thread_print_info: unknown thread state %d", state);
1029 /* threads_get_current_tid *****************************************************
1031 Return the tid of the current thread.
1036 *******************************************************************************/
1038 intptr_t threads_get_current_tid(void)
1040 threadobject *thread;
1042 thread = THREADOBJECT;
1044 /* this may happen during bootstrap */
1049 return (intptr_t) thread->tid;
1053 /* thread_set_state_runnable ***************************************************
1055 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1057 NOTE: If the thread has already terminated, don't set the state.
1058 This is important for threads_detach_thread.
1060 *******************************************************************************/
1062 void thread_set_state_runnable(threadobject *t)
1064 /* Set the state inside a lock. */
1068 if (t->state != THREAD_STATE_TERMINATED) {
1069 t->state = THREAD_STATE_RUNNABLE;
1071 DEBUGTHREADS("is RUNNABLE", t);
1074 threadlist_unlock();
1078 /* thread_set_state_waiting ****************************************************
1080 Set the current state of the given thread to THREAD_STATE_WAITING.
1082 NOTE: If the thread has already terminated, don't set the state.
1083 This is important for threads_detach_thread.
1085 *******************************************************************************/
1087 void thread_set_state_waiting(threadobject *t)
1089 /* Set the state inside a lock. */
1093 if (t->state != THREAD_STATE_TERMINATED) {
1094 t->state = THREAD_STATE_WAITING;
1096 DEBUGTHREADS("is WAITING", t);
1099 threadlist_unlock();
1103 /* thread_set_state_timed_waiting **********************************************
1105 Set the current state of the given thread to
1106 THREAD_STATE_TIMED_WAITING.
1108 NOTE: If the thread has already terminated, don't set the state.
1109 This is important for threads_detach_thread.
1111 *******************************************************************************/
1113 void thread_set_state_timed_waiting(threadobject *t)
1115 /* Set the state inside a lock. */
1119 if (t->state != THREAD_STATE_TERMINATED) {
1120 t->state = THREAD_STATE_TIMED_WAITING;
1122 DEBUGTHREADS("is TIMED_WAITING", t);
1125 threadlist_unlock();
1129 /* thread_set_state_terminated *************************************************
1131 Set the current state of the given thread to
1132 THREAD_STATE_TERMINATED.
1134 *******************************************************************************/
1136 void thread_set_state_terminated(threadobject *t)
1138 /* Set the state inside a lock. */
1142 t->state = THREAD_STATE_TERMINATED;
1144 DEBUGTHREADS("is TERMINATED", t);
1146 threadlist_unlock();
1150 /* thread_get_thread **********************************************************
1152 Return the thread data structure of the given Java thread object.
1155 h ... java.lang.{VM}Thread object
1160 *******************************************************************************/
1162 threadobject *thread_get_thread(java_handle_t *h)
1165 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1166 java_lang_VMThread *vmto;
1167 java_lang_Object *to;
1169 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1173 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1175 vmto = (java_lang_VMThread *) h;
1177 LLNI_field_get_val(vmto, vmdata, to);
1179 t = (threadobject *) to;
1181 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1183 /* XXX This is just a quick hack. */
1187 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1188 LLNI_equals(t->object, h, equal);
1194 threadlist_unlock();
1196 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1198 log_println("threads_get_thread: IMPLEMENT ME!");
1201 # error unknown classpath configuration
1208 /* threads_thread_is_alive *****************************************************
1210 Returns if the give thread is alive.
1212 *******************************************************************************/
1214 bool threads_thread_is_alive(threadobject *t)
1218 state = cacaothread_get_state(t);
1221 case THREAD_STATE_NEW:
1222 case THREAD_STATE_TERMINATED:
1225 case THREAD_STATE_RUNNABLE:
1226 case THREAD_STATE_BLOCKED:
1227 case THREAD_STATE_WAITING:
1228 case THREAD_STATE_TIMED_WAITING:
1232 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1235 /* keep compiler happy */
1241 /* threads_dump ****************************************************************
1243 Dumps info for all threads running in the JVM. This function is
1244 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1246 *******************************************************************************/
1248 void threads_dump(void)
1252 /* XXX we should stop the world here */
1254 /* Lock the thread lists. */
1258 printf("Full thread dump CACAO "VERSION":\n");
1260 /* iterate over all started threads */
1262 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1263 /* ignore threads which are in state NEW */
1264 if (t->state == THREAD_STATE_NEW)
1267 #if defined(ENABLE_GC_CACAO)
1268 /* Suspend the thread. */
1269 /* XXX Is the suspend reason correct? */
1271 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1272 vm_abort("threads_dump: threads_suspend_thread failed");
1275 /* Print thread info. */
1278 thread_print_info(t);
1281 /* Print trace of thread. */
1283 stacktrace_print_of_thread(t);
1285 #if defined(ENABLE_GC_CACAO)
1286 /* Resume the thread. */
1288 if (threads_resume_thread(t) == false)
1289 vm_abort("threads_dump: threads_resume_thread failed");
1293 /* Unlock the thread lists. */
1295 threadlist_unlock();
1302 * These are local overrides for various environment variables in Emacs.
1303 * Please do not remove this and leave it at the end of the file, where
1304 * Emacs will automagically detect them.
1305 * ---------------------------------------------------------------------
1308 * indent-tabs-mode: t
1312 * vim:noexpandtab:sw=4:ts=4: