1 /* src/threads/thread.c - 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 #include "native/jni.h"
37 #include "native/llni.h"
38 #include "native/native.h"
40 #include "native/include/java_lang_Object.h"
41 #include "native/include/java_lang_String.h"
42 #include "native/include/java_lang_Thread.h"
44 #if defined(ENABLE_JAVASE)
45 # include "native/include/java_lang_ThreadGroup.h"
48 #if defined(WITH_CLASSPATH_GNU)
49 # include "native/include/java_lang_VMThread.h"
52 #include "threads/critical.h"
53 #include "threads/lock-common.h"
54 #include "threads/threadlist.h"
55 #include "threads/thread.h"
57 #include "vm/builtin.h"
58 #include "vm/exceptions.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/stacktrace.h"
64 #include "vmcore/class.h"
65 #include "vmcore/method.h"
66 #include "vmcore/options.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vmcore/statistics.h"
72 #include "vmcore/utf8.h"
75 /* global variables ***********************************************************/
77 static methodinfo *thread_method_init;
78 static java_handle_t *threadgroup_system;
79 static java_handle_t *threadgroup_main;
81 #if defined(__LINUX__)
82 /* XXX Remove for exact-GC. */
83 bool threads_pthreads_implementation_nptl;
87 /* static functions ***********************************************************/
89 static void thread_create_initial_threadgroups(void);
90 static void thread_create_initial_thread(void);
91 static threadobject *thread_new(void);
94 /* threads_preinit *************************************************************
96 Do some early initialization of stuff required.
98 *******************************************************************************/
100 void threads_preinit(void)
102 threadobject *mainthread;
103 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
108 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
110 #if defined(__LINUX__)
111 /* XXX Remove for exact-GC. */
113 /* On Linux we need to check the pthread implementation. */
115 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
116 /* If the glibc is a pre-2.3.2 version, we fall back to
119 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
120 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
122 /* Some systems return as length 0 (maybe cross-compilation
123 related). In this case we also fall back to linuxthreads. */
126 pathbuf = MNEW(char, len);
128 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
130 if (strstr(pathbuf, "NPTL") != NULL)
131 threads_pthreads_implementation_nptl = true;
133 threads_pthreads_implementation_nptl = false;
136 threads_pthreads_implementation_nptl = false;
138 threads_pthreads_implementation_nptl = false;
142 /* Initialize the threads implementation (sets the thinlock on the
145 threads_impl_preinit();
147 /* Create internal thread data-structure for the main thread. */
149 mainthread = thread_new();
151 /* thread is a Java thread and running */
153 mainthread->flags |= THREAD_FLAG_JAVA;
154 mainthread->state = THREAD_STATE_RUNNABLE;
156 /* Store the internal thread data-structure in the TSD. */
158 thread_set_current(mainthread);
162 /* threads_init ****************************************************************
164 Initialize the main thread.
166 *******************************************************************************/
168 void threads_init(void)
170 TRACESUBSYSTEMINITIALIZATION("threads_init");
172 /* Create the system and main thread groups. */
174 thread_create_initial_threadgroups();
176 /* Cache the java.lang.Thread initialization method. */
178 #if defined(WITH_CLASSPATH_GNU)
181 class_resolveclassmethod(class_java_lang_Thread,
183 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
184 class_java_lang_Thread,
187 #elif defined(WITH_CLASSPATH_SUN)
190 class_resolveclassmethod(class_java_lang_Thread,
192 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
193 class_java_lang_Thread,
196 #elif defined(WITH_CLASSPATH_CLDC1_1)
199 class_resolveclassmethod(class_java_lang_Thread,
201 utf_java_lang_String__void,
202 class_java_lang_Thread,
206 # error unknown classpath configuration
209 if (thread_method_init == NULL)
210 vm_abort("threads_init: failed to resolve thread init method");
212 thread_create_initial_thread();
216 /* thread_create_object ********************************************************
218 Create a Java thread object for the given thread data-structure,
219 initializes it and adds the thread to the threadgroup.
224 name .... thread name
225 group ... threadgroup
229 *******************************************************************************/
231 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
234 java_lang_Thread *to;
236 #if defined(WITH_CLASSPATH_GNU)
237 java_lang_VMThread *vmto;
243 /* Create a java.lang.Thread Java object. */
245 o = builtin_new(class_java_lang_Thread);
250 to = (java_lang_Thread *) o;
252 /* Set the Java object in the thread data-structure. This
253 indicates that the thread is attached to the VM. */
255 thread_set_object(t, (java_handle_t *) to);
257 #if defined(WITH_CLASSPATH_GNU)
259 /* Create a java.lang.VMThread Java object. */
261 vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
266 /* Set the Java thread object in the Java VM-thread object. */
268 LLNI_field_set_ref(vmto, thread, to);
270 /* Set the thread data-structure in the Java VM-thread object. */
272 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
275 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
277 isdaemon = thread_is_daemon(t);
279 (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
282 if (exceptions_get_exception())
285 /* Set the threadgroup in the Java thread object. */
287 LLNI_field_set_ref(to, group, (java_lang_ThreadGroup *) group);
289 /* Add thread to the threadgroup. */
291 LLNI_class_get(group, c);
293 m = class_resolveclassmethod(c,
295 utf_java_lang_Thread__V,
296 class_java_lang_ThreadGroup,
302 (void) vm_call_method(m, group, to);
304 if (exceptions_get_exception())
307 #elif defined(WITH_CLASSPATH_SUN)
309 /* OpenJDK's java.lang.Thread does not have a VMThread field in
310 the class. Nothing to do here. */
312 /* Set the priority. java.lang.Thread.<init> requires it because
313 it sets the priority of the current thread to the parent's one
314 (which is the current thread in this case). */
316 LLNI_field_set_val(to, priority, NORM_PRIORITY);
319 java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
321 (void) vm_call_method(thread_method_init, o, group, name);
323 if (exceptions_get_exception())
326 #elif defined(WITH_CLASSPATH_CLDC1_1)
328 /* Set the thread data-structure in the Java thread object. */
330 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
332 /* Call: public Thread(Ljava/lang/String;)V */
334 (void) vm_call_method(thread_method_init, o, name);
336 if (exceptions_get_exception())
340 # error unknown classpath configuration
347 /* thread_create_initial_threadgroups ******************************************
349 Create the initial threadgroups.
352 Create the main threadgroup only and set the system
353 threadgroup to the main threadgroup.
356 Create the system and main threadgroup.
359 This function is a no-op.
361 *******************************************************************************/
363 static void thread_create_initial_threadgroups(void)
365 #if defined(ENABLE_JAVASE)
366 # if defined(WITH_CLASSPATH_GNU)
368 /* Allocate and initialize the main thread group. */
370 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
372 if (threadgroup_main == NULL)
373 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
375 /* Use the same threadgroup for system as for main. */
377 threadgroup_system = threadgroup_main;
379 # elif defined(WITH_CLASSPATH_SUN)
384 /* Allocate and initialize the system thread group. */
386 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
388 if (threadgroup_system == NULL)
389 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
391 /* Allocate and initialize the main thread group. */
393 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
395 if (threadgroup_main == NULL)
396 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
398 name = javastring_new(utf_main);
400 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
402 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
403 class_java_lang_ThreadGroup,
407 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
409 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
411 if (exceptions_get_exception())
412 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
415 # error unknown classpath configuration
421 /* thread_create_initial_thread ***********************************************
423 Create the initial thread: main
425 *******************************************************************************/
427 static void thread_create_initial_thread(void)
432 /* Get the main-thread (NOTE: The main thread is always the first
433 thread in the list). */
435 t = threadlist_first();
437 /* The thread name. */
439 name = javastring_new(utf_main);
441 #if defined(ENABLE_INTRP)
442 /* create interpreter stack */
445 MSET(intrp_main_stack, 0, u1, opt_stacksize);
446 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
450 /* Create the Java thread object. */
452 if (!thread_create_object(t, name, threadgroup_main))
453 vm_abort("thread_create_initial_thread: failed to create Java object");
455 /* Initialize the implementation specific bits. */
459 DEBUGTHREADS("starting (main)", t);
463 /* thread_new ******************************************************************
465 Allocates and initializes an internal thread data-structure and
466 adds it to the threads list.
468 *******************************************************************************/
470 static threadobject *thread_new(void)
475 /* Lock the thread lists */
479 index = threadlist_get_free_index();
481 /* Allocate a thread data structure. */
483 /* First, try to get one from the free-list. */
485 t = threadlist_free_first();
488 /* Remove from free list. */
490 threadlist_free_remove(t);
492 /* Equivalent of MZERO on the else path */
494 threads_impl_thread_clear(t);
497 #if defined(ENABLE_GC_BOEHM)
498 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
500 t = NEW(threadobject);
503 #if defined(ENABLE_STATISTICS)
505 size_threadobject += sizeof(threadobject);
510 MZERO(t, threadobject, 1);
512 #if defined(ENABLE_GC_CACAO)
513 /* Register reference to java.lang.Thread with the GC. */
514 /* FIXME is it ok to do this only once? */
516 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
517 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
520 /* Initialize the implementation-specific bits. */
522 threads_impl_thread_init(t);
525 /* Pre-compute the thinlock-word. */
530 t->thinlock = lock_pre_compute_thinlock(t->index);
532 t->state = THREAD_STATE_NEW;
534 #if defined(ENABLE_GC_CACAO)
535 t->flags |= THREAD_FLAG_IN_NATIVE;
538 /* Initialize the implementation-specific bits. */
540 threads_impl_thread_reuse(t);
542 /* Add the thread to the thread list. */
546 /* Unlock the thread lists. */
554 /* thread_free *****************************************************************
556 Remove the thread from the threads-list and free the internal
557 thread data structure. The thread index is added to the
558 thread-index free-list.
561 t ... thread data structure
563 *******************************************************************************/
565 void thread_free(threadobject *t)
567 /* Lock the thread lists. */
571 /* Remove the thread from the thread-list. */
573 threadlist_remove(t);
575 /* Add the thread index to the free list. */
577 threadlist_index_add(t->index);
579 /* Set the reference to the Java object to NULL. */
581 thread_set_object(t, NULL);
583 /* Add the thread data structure to the free list. */
585 threadlist_free_add(t);
587 /* Unlock the thread lists. */
593 /* threads_thread_start_internal ***********************************************
595 Start an internal thread in the JVM. No Java thread objects exists
599 name.......UTF-8 name of the thread
600 f..........function pointer to C function to start
602 *******************************************************************************/
604 bool threads_thread_start_internal(utf *name, functionptr f)
608 /* Enter the join-mutex, so if the main-thread is currently
609 waiting to join all threads, the number of non-daemon threads
612 threads_mutex_join_lock();
614 /* Create internal thread data-structure. */
618 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
620 /* The thread is flagged as (non-)daemon thread, we can leave the
623 threads_mutex_join_unlock();
625 /* Create the Java thread object. */
627 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
630 /* Start the thread. */
632 threads_impl_thread_start(t, f);
634 /* everything's ok */
640 /* threads_thread_start ********************************************************
642 Start a Java thread in the JVM. Only the java thread object exists
646 object.....the java thread object java.lang.Thread
648 *******************************************************************************/
650 void threads_thread_start(java_handle_t *object)
652 java_lang_Thread *to;
654 #if defined(WITH_CLASSPATH_GNU)
655 java_lang_VMThread *vmto;
658 to = (java_lang_Thread *) object;
660 /* Enter the join-mutex, so if the main-thread is currently
661 waiting to join all threads, the number of non-daemon threads
664 threads_mutex_join_lock();
666 /* Create internal thread data-structure. */
670 /* this is a normal Java thread */
672 t->flags |= THREAD_FLAG_JAVA;
674 #if defined(ENABLE_JAVASE)
675 /* Is this a daemon thread? */
677 if (LLNI_field_direct(to, daemon) == true)
678 t->flags |= THREAD_FLAG_DAEMON;
681 /* The thread is flagged and (non-)daemon thread, we can leave the
684 threads_mutex_join_unlock();
686 /* Link the two objects together. */
688 thread_set_object(t, object);
690 #if defined(WITH_CLASSPATH_GNU)
692 /* Get the java.lang.VMThread object and do some sanity checks. */
694 LLNI_field_get_ref(to, vmThread, vmto);
697 assert(LLNI_field_direct(vmto, vmdata) == NULL);
699 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
701 #elif defined(WITH_CLASSPATH_SUN)
705 #elif defined(WITH_CLASSPATH_CLDC1_1)
707 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
710 # error unknown classpath configuration
713 /* Start the thread. Don't pass a function pointer (NULL) since
714 we want Thread.run()V here. */
716 threads_impl_thread_start(t, NULL);
720 /* threads_attach_current_thread ***********************************************
722 Attaches the current thread to the VM. Used in JNI.
724 *******************************************************************************/
726 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
732 java_handle_t *group;
734 /* If the current thread has already been attached, this operation
737 result = thread_current_is_attached();
742 /* Enter the join-mutex, so if the main-thread is currently
743 waiting to join all threads, the number of non-daemon threads
746 threads_mutex_join_lock();
748 /* Create internal thread data structure. */
752 /* Thread is a Java thread and running. */
754 t->flags = THREAD_FLAG_JAVA;
757 t->flags |= THREAD_FLAG_DAEMON;
759 /* The thread is flagged and (non-)daemon thread, we can leave the
762 threads_mutex_join_unlock();
764 DEBUGTHREADS("attaching", t);
766 /* Get the thread name. */
768 if (vm_aargs != NULL) {
769 u = utf_new_char(vm_aargs->name);
775 name = javastring_new(u);
777 #if defined(ENABLE_JAVASE)
778 /* Get the threadgroup. */
780 if (vm_aargs != NULL)
781 group = (java_handle_t *) vm_aargs->group;
783 /* If no threadgroup was given, use the main threadgroup. */
786 group = threadgroup_main;
789 #if defined(ENABLE_INTRP)
790 /* create interpreter stack */
793 MSET(intrp_main_stack, 0, u1, opt_stacksize);
794 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
798 /* Create the Java thread object. */
800 if (!thread_create_object(t, name, group))
803 /* The thread is completely initialized. */
805 threads_thread_state_runnable(t);
811 /* thread_fprint_name **********************************************************
813 Print the name of the given thread to the given stream.
816 t ........ thread data-structure
817 stream ... stream to print to
819 *******************************************************************************/
821 void thread_fprint_name(threadobject *t, FILE *stream)
823 java_lang_Thread *to;
825 #if defined(WITH_CLASSPATH_GNU)
826 java_lang_String *name;
827 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
828 java_chararray_t *name;
831 to = (java_lang_Thread *) thread_get_object(t);
836 LLNI_field_get_ref(to, name, name);
838 #if defined(WITH_CLASSPATH_GNU)
840 javastring_fprint((java_handle_t *) name, stream);
842 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
844 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
845 /* FIXME This prints to stdout. */
846 utf_display_printable_ascii(utf_null);
849 # error unknown classpath configuration
854 /* thread_print_info ***********************************************************
856 Print information of the passed thread.
859 t ... thread data-structure.
861 *******************************************************************************/
863 void thread_print_info(threadobject *t)
865 java_lang_Thread *to;
867 /* If the thread is currently in initalization, don't print it. */
869 to = (java_lang_Thread *) thread_get_object(t);
871 /* Print as much as we can when we are in state NEW. */
874 /* Print thread name. */
877 thread_fprint_name(t, stdout);
883 if (thread_is_daemon(t))
887 printf(" prio=%d", LLNI_field_direct(to, priority));
890 #if SIZEOF_VOID_P == 8
891 printf(" t=0x%016lx tid=0x%016lx (%ld)",
892 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
894 printf(" t=0x%08x tid=0x%08x (%d)",
895 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
898 printf(" index=%d", t->index);
900 /* Print thread state. */
903 case THREAD_STATE_NEW:
906 case THREAD_STATE_RUNNABLE:
909 case THREAD_STATE_BLOCKED:
912 case THREAD_STATE_WAITING:
915 case THREAD_STATE_TIMED_WAITING:
916 printf(" waiting on condition");
918 case THREAD_STATE_TERMINATED:
919 printf(" terminated");
922 vm_abort("thread_print_info: unknown thread state %d", t->state);
927 /* threads_get_current_tid *****************************************************
929 Return the tid of the current thread.
934 *******************************************************************************/
936 intptr_t threads_get_current_tid(void)
938 threadobject *thread;
940 thread = THREADOBJECT;
942 /* this may happen during bootstrap */
947 return (intptr_t) thread->tid;
951 /* threads_thread_state_runnable ***********************************************
953 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
955 NOTE: If the thread has already terminated, don't set the state.
956 This is important for threads_detach_thread.
958 *******************************************************************************/
960 void threads_thread_state_runnable(threadobject *t)
962 /* Set the state inside a lock. */
966 if (t->state != THREAD_STATE_TERMINATED)
967 t->state = THREAD_STATE_RUNNABLE;
969 DEBUGTHREADS("is RUNNABLE", t);
975 /* threads_thread_state_waiting ************************************************
977 Set the current state of the given thread to THREAD_STATE_WAITING.
979 NOTE: If the thread has already terminated, don't set the state.
980 This is important for threads_detach_thread.
982 *******************************************************************************/
984 void threads_thread_state_waiting(threadobject *t)
986 /* Set the state inside a lock. */
990 if (t->state != THREAD_STATE_TERMINATED)
991 t->state = THREAD_STATE_WAITING;
993 DEBUGTHREADS("is WAITING", t);
999 /* threads_thread_state_timed_waiting ******************************************
1001 Set the current state of the given thread to
1002 THREAD_STATE_TIMED_WAITING.
1004 NOTE: If the thread has already terminated, don't set the state.
1005 This is important for threads_detach_thread.
1007 *******************************************************************************/
1009 void threads_thread_state_timed_waiting(threadobject *t)
1011 /* Set the state inside a lock. */
1015 if (t->state != THREAD_STATE_TERMINATED)
1016 t->state = THREAD_STATE_TIMED_WAITING;
1018 DEBUGTHREADS("is TIMED_WAITING", t);
1020 threadlist_unlock();
1024 /* threads_thread_state_terminated *********************************************
1026 Set the current state of the given thread to
1027 THREAD_STATE_TERMINATED.
1029 *******************************************************************************/
1031 void threads_thread_state_terminated(threadobject *t)
1033 /* set the state in the lock */
1037 t->state = THREAD_STATE_TERMINATED;
1039 DEBUGTHREADS("is TERMINATED", t);
1041 threadlist_unlock();
1045 /* threads_thread_get_state ****************************************************
1047 Returns the current state of the given thread.
1049 *******************************************************************************/
1051 utf *threads_thread_get_state(threadobject *t)
1056 case THREAD_STATE_NEW:
1057 u = utf_new_char("NEW");
1059 case THREAD_STATE_RUNNABLE:
1060 u = utf_new_char("RUNNABLE");
1062 case THREAD_STATE_BLOCKED:
1063 u = utf_new_char("BLOCKED");
1065 case THREAD_STATE_WAITING:
1066 u = utf_new_char("WAITING");
1068 case THREAD_STATE_TIMED_WAITING:
1069 u = utf_new_char("TIMED_WAITING");
1071 case THREAD_STATE_TERMINATED:
1072 u = utf_new_char("TERMINATED");
1075 vm_abort("threads_get_state: unknown thread state %d", t->state);
1077 /* keep compiler happy */
1086 /* thread_get_thread **********************************************************
1088 Return the thread data structure of the given Java thread object.
1091 h ... java.lang.{VM}Thread object
1096 *******************************************************************************/
1098 threadobject *thread_get_thread(java_handle_t *h)
1101 #if defined(WITH_CLASSPATH_GNU)
1102 java_lang_VMThread *vmto;
1103 java_lang_Object *to;
1105 #if defined(WITH_CLASSPATH_SUN)
1109 #if defined(WITH_CLASSPATH_GNU)
1111 vmto = (java_lang_VMThread *) h;
1113 LLNI_field_get_val(vmto, vmdata, to);
1115 t = (threadobject *) to;
1117 #elif defined(WITH_CLASSPATH_SUN)
1119 /* XXX This is just a quick hack. */
1123 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1124 LLNI_equals(t->object, h, equal);
1130 threadlist_unlock();
1132 #elif defined(WITH_CLASSPATH_CLDC1_1)
1134 log_println("threads_get_thread: IMPLEMENT ME!");
1137 # error unknown classpath configuration
1144 /* threads_thread_is_alive *****************************************************
1146 Returns if the give thread is alive.
1148 *******************************************************************************/
1150 bool threads_thread_is_alive(threadobject *t)
1153 case THREAD_STATE_NEW:
1154 case THREAD_STATE_TERMINATED:
1157 case THREAD_STATE_RUNNABLE:
1158 case THREAD_STATE_BLOCKED:
1159 case THREAD_STATE_WAITING:
1160 case THREAD_STATE_TIMED_WAITING:
1164 vm_abort("threads_thread_is_alive: unknown thread state %d", t->state);
1167 /* keep compiler happy */
1173 /* threads_dump ****************************************************************
1175 Dumps info for all threads running in the JVM. This function is
1176 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1178 *******************************************************************************/
1180 void threads_dump(void)
1184 /* XXX we should stop the world here */
1186 /* Lock the thread lists. */
1190 printf("Full thread dump CACAO "VERSION":\n");
1192 /* iterate over all started threads */
1194 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1195 /* ignore threads which are in state NEW */
1196 if (t->state == THREAD_STATE_NEW)
1199 #if defined(ENABLE_GC_CACAO)
1200 /* Suspend the thread. */
1201 /* XXX Is the suspend reason correct? */
1203 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1204 vm_abort("threads_dump: threads_suspend_thread failed");
1207 /* Print thread info. */
1210 thread_print_info(t);
1213 /* Print trace of thread. */
1215 threads_thread_print_stacktrace(t);
1217 #if defined(ENABLE_GC_CACAO)
1218 /* Resume the thread. */
1220 if (threads_resume_thread(t) == false)
1221 vm_abort("threads_dump: threads_resume_thread failed");
1225 /* Unlock the thread lists. */
1227 threadlist_unlock();
1231 /* threads_thread_print_stacktrace *********************************************
1233 Print the current stacktrace of the given thread.
1235 *******************************************************************************/
1237 void threads_thread_print_stacktrace(threadobject *thread)
1239 stackframeinfo_t *sfi;
1240 java_handle_bytearray_t *ba;
1243 /* Build a stacktrace for the passed thread. */
1245 sfi = thread->_stackframeinfo;
1246 ba = stacktrace_get(sfi);
1249 /* We need a critical section here as we use the byte-array
1250 data pointer directly. */
1252 LLNI_CRITICAL_START;
1254 st = (stacktrace_t *) LLNI_array_data(ba);
1256 /* Print stacktrace. */
1258 stacktrace_print(st);
1263 puts("\t<<No stacktrace available>>");
1269 /* threads_print_stacktrace ****************************************************
1271 Print the current stacktrace of the current thread.
1273 *******************************************************************************/
1275 void threads_print_stacktrace(void)
1277 threadobject *thread;
1279 thread = THREADOBJECT;
1281 threads_thread_print_stacktrace(thread);
1286 * These are local overrides for various environment variables in Emacs.
1287 * Please do not remove this and leave it at the end of the file, where
1288 * Emacs will automagically detect them.
1289 * ---------------------------------------------------------------------
1292 * indent-tabs-mode: t
1296 * vim:noexpandtab:sw=4:ts=4: