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 threads_thread_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;
873 /* If the thread is currently in initalization, don't print it. */
875 to = (java_lang_Thread *) thread_get_object(t);
877 /* Print as much as we can when we are in state NEW. */
880 /* Print thread name. */
883 thread_fprint_name(t, stdout);
889 if (thread_is_daemon(t))
893 printf(" prio=%d", LLNI_field_direct(to, priority));
896 #if SIZEOF_VOID_P == 8
897 printf(" t=0x%016lx tid=0x%016lx (%ld)",
898 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
900 printf(" t=0x%08x tid=0x%08x (%d)",
901 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
904 printf(" index=%d", t->index);
906 /* Print thread state. */
909 case THREAD_STATE_NEW:
912 case THREAD_STATE_RUNNABLE:
915 case THREAD_STATE_BLOCKED:
918 case THREAD_STATE_WAITING:
921 case THREAD_STATE_TIMED_WAITING:
922 printf(" waiting on condition");
924 case THREAD_STATE_TERMINATED:
925 printf(" terminated");
928 vm_abort("thread_print_info: unknown thread state %d", t->state);
933 /* threads_get_current_tid *****************************************************
935 Return the tid of the current thread.
940 *******************************************************************************/
942 intptr_t threads_get_current_tid(void)
944 threadobject *thread;
946 thread = THREADOBJECT;
948 /* this may happen during bootstrap */
953 return (intptr_t) thread->tid;
957 /* threads_thread_state_runnable ***********************************************
959 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
961 NOTE: If the thread has already terminated, don't set the state.
962 This is important for threads_detach_thread.
964 *******************************************************************************/
966 void threads_thread_state_runnable(threadobject *t)
968 /* Set the state inside a lock. */
972 if (t->state != THREAD_STATE_TERMINATED)
973 t->state = THREAD_STATE_RUNNABLE;
975 DEBUGTHREADS("is RUNNABLE", t);
981 /* threads_thread_state_waiting ************************************************
983 Set the current state of the given thread to THREAD_STATE_WAITING.
985 NOTE: If the thread has already terminated, don't set the state.
986 This is important for threads_detach_thread.
988 *******************************************************************************/
990 void threads_thread_state_waiting(threadobject *t)
992 /* Set the state inside a lock. */
996 if (t->state != THREAD_STATE_TERMINATED)
997 t->state = THREAD_STATE_WAITING;
999 DEBUGTHREADS("is WAITING", t);
1001 threadlist_unlock();
1005 /* threads_thread_state_timed_waiting ******************************************
1007 Set the current state of the given thread to
1008 THREAD_STATE_TIMED_WAITING.
1010 NOTE: If the thread has already terminated, don't set the state.
1011 This is important for threads_detach_thread.
1013 *******************************************************************************/
1015 void threads_thread_state_timed_waiting(threadobject *t)
1017 /* Set the state inside a lock. */
1021 if (t->state != THREAD_STATE_TERMINATED)
1022 t->state = THREAD_STATE_TIMED_WAITING;
1024 DEBUGTHREADS("is TIMED_WAITING", t);
1026 threadlist_unlock();
1030 /* threads_thread_state_terminated *********************************************
1032 Set the current state of the given thread to
1033 THREAD_STATE_TERMINATED.
1035 *******************************************************************************/
1037 void threads_thread_state_terminated(threadobject *t)
1039 /* set the state in the lock */
1043 t->state = THREAD_STATE_TERMINATED;
1045 DEBUGTHREADS("is TERMINATED", t);
1047 threadlist_unlock();
1051 /* threads_thread_get_state ****************************************************
1053 Returns the current state of the given thread.
1055 *******************************************************************************/
1057 utf *threads_thread_get_state(threadobject *t)
1062 case THREAD_STATE_NEW:
1063 u = utf_new_char("NEW");
1065 case THREAD_STATE_RUNNABLE:
1066 u = utf_new_char("RUNNABLE");
1068 case THREAD_STATE_BLOCKED:
1069 u = utf_new_char("BLOCKED");
1071 case THREAD_STATE_WAITING:
1072 u = utf_new_char("WAITING");
1074 case THREAD_STATE_TIMED_WAITING:
1075 u = utf_new_char("TIMED_WAITING");
1077 case THREAD_STATE_TERMINATED:
1078 u = utf_new_char("TERMINATED");
1081 vm_abort("threads_get_state: unknown thread state %d", t->state);
1083 /* keep compiler happy */
1092 /* thread_get_thread **********************************************************
1094 Return the thread data structure of the given Java thread object.
1097 h ... java.lang.{VM}Thread object
1102 *******************************************************************************/
1104 threadobject *thread_get_thread(java_handle_t *h)
1107 #if defined(WITH_CLASSPATH_GNU)
1108 java_lang_VMThread *vmto;
1109 java_lang_Object *to;
1111 #if defined(WITH_CLASSPATH_SUN)
1115 #if defined(WITH_CLASSPATH_GNU)
1117 vmto = (java_lang_VMThread *) h;
1119 LLNI_field_get_val(vmto, vmdata, to);
1121 t = (threadobject *) to;
1123 #elif defined(WITH_CLASSPATH_SUN)
1125 /* XXX This is just a quick hack. */
1129 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1130 LLNI_equals(t->object, h, equal);
1136 threadlist_unlock();
1138 #elif defined(WITH_CLASSPATH_CLDC1_1)
1140 log_println("threads_get_thread: IMPLEMENT ME!");
1143 # error unknown classpath configuration
1150 /* threads_thread_is_alive *****************************************************
1152 Returns if the give thread is alive.
1154 *******************************************************************************/
1156 bool threads_thread_is_alive(threadobject *t)
1159 case THREAD_STATE_NEW:
1160 case THREAD_STATE_TERMINATED:
1163 case THREAD_STATE_RUNNABLE:
1164 case THREAD_STATE_BLOCKED:
1165 case THREAD_STATE_WAITING:
1166 case THREAD_STATE_TIMED_WAITING:
1170 vm_abort("threads_thread_is_alive: unknown thread state %d", t->state);
1173 /* keep compiler happy */
1179 /* threads_dump ****************************************************************
1181 Dumps info for all threads running in the JVM. This function is
1182 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1184 *******************************************************************************/
1186 void threads_dump(void)
1190 /* XXX we should stop the world here */
1192 /* Lock the thread lists. */
1196 printf("Full thread dump CACAO "VERSION":\n");
1198 /* iterate over all started threads */
1200 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1201 /* ignore threads which are in state NEW */
1202 if (t->state == THREAD_STATE_NEW)
1205 #if defined(ENABLE_GC_CACAO)
1206 /* Suspend the thread. */
1207 /* XXX Is the suspend reason correct? */
1209 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1210 vm_abort("threads_dump: threads_suspend_thread failed");
1213 /* Print thread info. */
1216 thread_print_info(t);
1219 /* Print trace of thread. */
1221 stacktrace_print_of_thread(t);
1223 #if defined(ENABLE_GC_CACAO)
1224 /* Resume the thread. */
1226 if (threads_resume_thread(t) == false)
1227 vm_abort("threads_dump: threads_resume_thread failed");
1231 /* Unlock the thread lists. */
1233 threadlist_unlock();
1238 * These are local overrides for various environment variables in Emacs.
1239 * Please do not remove this and leave it at the end of the file, where
1240 * Emacs will automagically detect them.
1241 * ---------------------------------------------------------------------
1244 * indent-tabs-mode: t
1248 * vim:noexpandtab:sw=4:ts=4: