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 /* Store the internal thread data-structure in the TSD. */
761 thread_set_current(t);
763 /* The thread is flagged and (non-)daemon thread, we can leave the
766 threads_mutex_join_unlock();
768 DEBUGTHREADS("attaching", t);
770 /* Get the thread name. */
772 if (vm_aargs != NULL) {
773 u = utf_new_char(vm_aargs->name);
779 name = javastring_new(u);
781 #if defined(ENABLE_JAVASE)
782 /* Get the threadgroup. */
784 if (vm_aargs != NULL)
785 group = (java_handle_t *) vm_aargs->group;
789 /* If no threadgroup was given, use the main threadgroup. */
792 group = threadgroup_main;
795 #if defined(ENABLE_INTRP)
796 /* create interpreter stack */
799 MSET(intrp_main_stack, 0, u1, opt_stacksize);
800 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
804 /* Create the Java thread object. */
806 if (!thread_create_object(t, name, group))
809 /* The thread is completely initialized. */
811 thread_set_state_runnable(t);
817 /* thread_fprint_name **********************************************************
819 Print the name of the given thread to the given stream.
822 t ........ thread data-structure
823 stream ... stream to print to
825 *******************************************************************************/
827 void thread_fprint_name(threadobject *t, FILE *stream)
829 java_lang_Thread *to;
831 #if defined(WITH_CLASSPATH_GNU)
832 java_lang_String *name;
833 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
834 java_chararray_t *name;
837 to = (java_lang_Thread *) thread_get_object(t);
842 LLNI_field_get_ref(to, name, name);
844 #if defined(WITH_CLASSPATH_GNU)
846 javastring_fprint((java_handle_t *) name, stream);
848 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
850 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
851 /* FIXME This prints to stdout. */
852 utf_display_printable_ascii(utf_null);
855 # error unknown classpath configuration
860 /* thread_print_info ***********************************************************
862 Print information of the passed thread.
865 t ... thread data-structure.
867 *******************************************************************************/
869 void thread_print_info(threadobject *t)
871 java_lang_Thread *to;
874 /* If the thread is currently in initalization, don't print it. */
876 to = (java_lang_Thread *) thread_get_object(t);
878 /* Print as much as we can when we are in state NEW. */
881 /* Print thread name. */
884 thread_fprint_name(t, stdout);
890 if (thread_is_daemon(t))
894 printf(" prio=%d", LLNI_field_direct(to, priority));
897 #if SIZEOF_VOID_P == 8
898 printf(" t=0x%016lx tid=0x%016lx (%ld)",
899 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
901 printf(" t=0x%08x tid=0x%08x (%d)",
902 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
905 printf(" index=%d", t->index);
907 /* Print thread state. */
909 state = cacaothread_get_state(t);
912 case THREAD_STATE_NEW:
915 case THREAD_STATE_RUNNABLE:
918 case THREAD_STATE_BLOCKED:
921 case THREAD_STATE_WAITING:
924 case THREAD_STATE_TIMED_WAITING:
925 printf(" waiting on condition");
927 case THREAD_STATE_TERMINATED:
928 printf(" terminated");
931 vm_abort("thread_print_info: unknown thread state %d", state);
936 /* threads_get_current_tid *****************************************************
938 Return the tid of the current thread.
943 *******************************************************************************/
945 intptr_t threads_get_current_tid(void)
947 threadobject *thread;
949 thread = THREADOBJECT;
951 /* this may happen during bootstrap */
956 return (intptr_t) thread->tid;
960 /* thread_set_state_runnable ***************************************************
962 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
964 NOTE: If the thread has already terminated, don't set the state.
965 This is important for threads_detach_thread.
967 *******************************************************************************/
969 void thread_set_state_runnable(threadobject *t)
971 /* Set the state inside a lock. */
975 if (t->state != THREAD_STATE_TERMINATED) {
976 t->state = THREAD_STATE_RUNNABLE;
978 DEBUGTHREADS("is RUNNABLE", t);
985 /* thread_set_state_waiting ****************************************************
987 Set the current state of the given thread to THREAD_STATE_WAITING.
989 NOTE: If the thread has already terminated, don't set the state.
990 This is important for threads_detach_thread.
992 *******************************************************************************/
994 void thread_set_state_waiting(threadobject *t)
996 /* Set the state inside a lock. */
1000 if (t->state != THREAD_STATE_TERMINATED) {
1001 t->state = THREAD_STATE_WAITING;
1003 DEBUGTHREADS("is WAITING", t);
1006 threadlist_unlock();
1010 /* thread_set_state_timed_waiting **********************************************
1012 Set the current state of the given thread to
1013 THREAD_STATE_TIMED_WAITING.
1015 NOTE: If the thread has already terminated, don't set the state.
1016 This is important for threads_detach_thread.
1018 *******************************************************************************/
1020 void thread_set_state_timed_waiting(threadobject *t)
1022 /* Set the state inside a lock. */
1026 if (t->state != THREAD_STATE_TERMINATED) {
1027 t->state = THREAD_STATE_TIMED_WAITING;
1029 DEBUGTHREADS("is TIMED_WAITING", t);
1032 threadlist_unlock();
1036 /* thread_set_state_terminated *************************************************
1038 Set the current state of the given thread to
1039 THREAD_STATE_TERMINATED.
1041 *******************************************************************************/
1043 void thread_set_state_terminated(threadobject *t)
1045 /* Set the state inside a lock. */
1049 t->state = THREAD_STATE_TERMINATED;
1051 DEBUGTHREADS("is TERMINATED", t);
1053 threadlist_unlock();
1057 /* thread_get_thread **********************************************************
1059 Return the thread data structure of the given Java thread object.
1062 h ... java.lang.{VM}Thread object
1067 *******************************************************************************/
1069 threadobject *thread_get_thread(java_handle_t *h)
1072 #if defined(WITH_CLASSPATH_GNU)
1073 java_lang_VMThread *vmto;
1074 java_lang_Object *to;
1076 #if defined(WITH_CLASSPATH_SUN)
1080 #if defined(WITH_CLASSPATH_GNU)
1082 vmto = (java_lang_VMThread *) h;
1084 LLNI_field_get_val(vmto, vmdata, to);
1086 t = (threadobject *) to;
1088 #elif defined(WITH_CLASSPATH_SUN)
1090 /* XXX This is just a quick hack. */
1094 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1095 LLNI_equals(t->object, h, equal);
1101 threadlist_unlock();
1103 #elif defined(WITH_CLASSPATH_CLDC1_1)
1105 log_println("threads_get_thread: IMPLEMENT ME!");
1108 # error unknown classpath configuration
1115 /* threads_thread_is_alive *****************************************************
1117 Returns if the give thread is alive.
1119 *******************************************************************************/
1121 bool threads_thread_is_alive(threadobject *t)
1125 state = cacaothread_get_state(t);
1128 case THREAD_STATE_NEW:
1129 case THREAD_STATE_TERMINATED:
1132 case THREAD_STATE_RUNNABLE:
1133 case THREAD_STATE_BLOCKED:
1134 case THREAD_STATE_WAITING:
1135 case THREAD_STATE_TIMED_WAITING:
1139 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1142 /* keep compiler happy */
1148 /* threads_dump ****************************************************************
1150 Dumps info for all threads running in the JVM. This function is
1151 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1153 *******************************************************************************/
1155 void threads_dump(void)
1159 /* XXX we should stop the world here */
1161 /* Lock the thread lists. */
1165 printf("Full thread dump CACAO "VERSION":\n");
1167 /* iterate over all started threads */
1169 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1170 /* ignore threads which are in state NEW */
1171 if (t->state == THREAD_STATE_NEW)
1174 #if defined(ENABLE_GC_CACAO)
1175 /* Suspend the thread. */
1176 /* XXX Is the suspend reason correct? */
1178 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1179 vm_abort("threads_dump: threads_suspend_thread failed");
1182 /* Print thread info. */
1185 thread_print_info(t);
1188 /* Print trace of thread. */
1190 stacktrace_print_of_thread(t);
1192 #if defined(ENABLE_GC_CACAO)
1193 /* Resume the thread. */
1195 if (threads_resume_thread(t) == false)
1196 vm_abort("threads_dump: threads_resume_thread failed");
1200 /* Unlock the thread lists. */
1202 threadlist_unlock();
1207 * These are local overrides for various environment variables in Emacs.
1208 * Please do not remove this and leave it at the end of the file, where
1209 * Emacs will automagically detect them.
1210 * ---------------------------------------------------------------------
1213 * indent-tabs-mode: t
1217 * vim:noexpandtab:sw=4:ts=4: