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 "threads/lock-common.h"
47 #include "threads/threadlist.h"
48 #include "threads/thread.hpp"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.hpp"
52 #include "vm/string.hpp"
55 #include "vm/jit/stacktrace.hpp"
57 #include "vmcore/class.h"
58 #include "vmcore/globals.hpp"
59 #include "vmcore/javaobjects.hpp"
60 #include "vmcore/method.h"
61 #include "vmcore/options.h"
63 #if defined(ENABLE_STATISTICS)
64 # include "vmcore/statistics.h"
67 #include "vmcore/utf8.h"
73 /* global variables ***********************************************************/
75 static methodinfo *thread_method_init;
76 static java_handle_t *threadgroup_system;
77 static java_handle_t *threadgroup_main;
79 #if defined(__LINUX__)
80 /* XXX Remove for exact-GC. */
81 bool threads_pthreads_implementation_nptl;
85 /* static functions ***********************************************************/
87 static void thread_create_initial_threadgroups(void);
88 static void thread_create_initial_thread(void);
89 static threadobject *thread_new(void);
92 /* threads_preinit *************************************************************
94 Do some early initialization of stuff required.
96 *******************************************************************************/
98 void threads_preinit(void)
100 threadobject *mainthread;
101 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
106 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
108 #if defined(__LINUX__)
109 /* XXX Remove for exact-GC. */
111 /* On Linux we need to check the pthread implementation. */
113 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
114 /* If the glibc is a pre-2.3.2 version, we fall back to
117 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
118 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
120 /* Some systems return as length 0 (maybe cross-compilation
121 related). In this case we also fall back to linuxthreads. */
124 pathbuf = MNEW(char, len);
126 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
128 if (strstr(pathbuf, "NPTL") != NULL)
129 threads_pthreads_implementation_nptl = true;
131 threads_pthreads_implementation_nptl = false;
134 threads_pthreads_implementation_nptl = false;
136 threads_pthreads_implementation_nptl = false;
140 /* Initialize the threads implementation (sets the thinlock on the
143 threads_impl_preinit();
145 /* Create internal thread data-structure for the main thread. */
147 mainthread = thread_new();
149 /* The main thread should always have index 1. */
151 if (mainthread->index != 1)
152 vm_abort("threads_preinit: main thread index not 1: %d != 1",
155 /* thread is a Java thread and running */
157 mainthread->flags |= THREAD_FLAG_JAVA;
158 mainthread->state = THREAD_STATE_RUNNABLE;
160 /* Store the internal thread data-structure in the TSD. */
162 thread_set_current(mainthread);
166 /* threads_init ****************************************************************
168 Initialize the main thread.
170 *******************************************************************************/
172 void threads_init(void)
174 TRACESUBSYSTEMINITIALIZATION("threads_init");
176 /* Create the system and main thread groups. */
178 thread_create_initial_threadgroups();
180 /* Cache the java.lang.Thread initialization method. */
182 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
185 class_resolveclassmethod(class_java_lang_Thread,
187 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
188 class_java_lang_Thread,
191 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
194 class_resolveclassmethod(class_java_lang_Thread,
196 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
197 class_java_lang_Thread,
200 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
203 class_resolveclassmethod(class_java_lang_Thread,
205 utf_java_lang_String__void,
206 class_java_lang_Thread,
210 # error unknown classpath configuration
213 if (thread_method_init == NULL)
214 vm_abort("threads_init: failed to resolve thread init method");
216 thread_create_initial_thread();
220 /* thread_create_object ********************************************************
222 Create a Java thread object for the given thread data-structure,
223 initializes it and adds the thread to the threadgroup.
228 name .... thread name
229 group ... threadgroup
233 *******************************************************************************/
235 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
237 /* Create a java.lang.Thread Java object. */
239 java_handle_t* h = builtin_new(class_java_lang_Thread);
244 java_lang_Thread jlt(h);
246 // Set the Java object in the thread data-structure. This
247 // indicates that the thread is attached to the VM.
248 thread_set_object(t, jlt.get_handle());
250 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
252 h = builtin_new(class_java_lang_VMThread);
257 // Create and initialize a java.lang.VMThread object.
258 java_lang_VMThread jlvmt(h, jlt.get_handle(), t);
261 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
263 bool isdaemon = thread_is_daemon(t);
265 (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(),
266 name, NORM_PRIORITY, isdaemon);
268 if (exceptions_get_exception())
271 // Set the ThreadGroup in the Java thread object.
272 jlt.set_group(group);
274 /* Add thread to the threadgroup. */
277 LLNI_class_get(group, c);
279 methodinfo* m = class_resolveclassmethod(c,
281 utf_java_lang_Thread__V,
282 class_java_lang_ThreadGroup,
288 (void) vm_call_method(m, group, jlt.get_handle());
290 if (exceptions_get_exception())
293 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
295 /* OpenJDK's java.lang.Thread does not have a VMThread field in
296 the class. Nothing to do here. */
298 /* Set the priority. java.lang.Thread.<init> requires it because
299 it sets the priority of the current thread to the parent's one
300 (which is the current thread in this case). */
302 LLNI_field_set_val(to, priority, NORM_PRIORITY);
305 java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
307 (void) vm_call_method(thread_method_init, o, group, name);
309 if (exceptions_get_exception())
312 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
314 /* Set the thread data-structure in the Java thread object. */
316 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
318 /* Call: public Thread(Ljava/lang/String;)V */
320 (void) vm_call_method(thread_method_init, o, name);
322 if (exceptions_get_exception())
326 # error unknown classpath configuration
333 /* thread_create_initial_threadgroups ******************************************
335 Create the initial threadgroups.
338 Create the main threadgroup only and set the system
339 threadgroup to the main threadgroup.
342 Create the system and main threadgroup.
345 This function is a no-op.
347 *******************************************************************************/
349 static void thread_create_initial_threadgroups(void)
351 #if defined(ENABLE_JAVASE)
352 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
354 /* Allocate and initialize the main thread group. */
356 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
358 if (threadgroup_main == NULL)
359 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
361 /* Use the same threadgroup for system as for main. */
363 threadgroup_system = threadgroup_main;
365 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
370 /* Allocate and initialize the system thread group. */
372 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
374 if (threadgroup_system == NULL)
375 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
377 /* Allocate and initialize the main thread group. */
379 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
381 if (threadgroup_main == NULL)
382 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
384 name = javastring_new(utf_main);
386 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
388 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
389 class_java_lang_ThreadGroup,
393 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
395 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
397 if (exceptions_get_exception())
398 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
401 # error unknown classpath configuration
407 /* thread_create_initial_thread ***********************************************
409 Create the initial thread: main
411 *******************************************************************************/
413 static void thread_create_initial_thread(void)
418 /* Get the main-thread (NOTE: The main thread is always the first
419 thread in the list). */
421 t = threadlist_first();
423 /* The thread name. */
425 name = javastring_new(utf_main);
427 #if defined(ENABLE_INTRP)
428 /* create interpreter stack */
431 MSET(intrp_main_stack, 0, u1, opt_stacksize);
432 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
436 /* Create the Java thread object. */
438 if (!thread_create_object(t, name, threadgroup_main))
439 vm_abort("thread_create_initial_thread: failed to create Java object");
441 /* Initialize the implementation specific bits. */
445 DEBUGTHREADS("starting (main)", t);
449 /* thread_new ******************************************************************
451 Allocates and initializes an internal thread data-structure and
452 adds it to the threads list.
454 *******************************************************************************/
456 static threadobject *thread_new(void)
461 /* Lock the thread lists */
465 index = threadlist_get_free_index();
467 /* Allocate a thread data structure. */
469 /* First, try to get one from the free-list. */
471 t = threadlist_free_first();
474 /* Remove from free list. */
476 threadlist_free_remove(t);
478 /* Equivalent of MZERO on the else path */
480 threads_impl_thread_clear(t);
483 #if defined(ENABLE_GC_BOEHM)
484 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
486 t = NEW(threadobject);
489 #if defined(ENABLE_STATISTICS)
491 size_threadobject += sizeof(threadobject);
496 MZERO(t, threadobject, 1);
498 #if defined(ENABLE_GC_CACAO)
499 /* Register reference to java.lang.Thread with the GC. */
500 /* FIXME is it ok to do this only once? */
502 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
503 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
506 /* Initialize the implementation-specific bits. */
508 threads_impl_thread_init(t);
511 /* Pre-compute the thinlock-word. */
516 t->thinlock = lock_pre_compute_thinlock(t->index);
518 t->state = THREAD_STATE_NEW;
520 #if defined(ENABLE_GC_CACAO)
521 t->flags |= THREAD_FLAG_IN_NATIVE;
524 /* Initialize the implementation-specific bits. */
526 threads_impl_thread_reuse(t);
528 /* Add the thread to the thread list. */
532 /* Unlock the thread lists. */
540 /* thread_free *****************************************************************
542 Remove the thread from the threads-list and free the internal
543 thread data structure. The thread index is added to the
544 thread-index free-list.
547 t ... thread data structure
549 *******************************************************************************/
551 void thread_free(threadobject *t)
553 /* Lock the thread lists. */
557 /* Remove the thread from the thread-list. */
559 threadlist_remove(t);
561 /* Add the thread index to the free list. */
563 threadlist_index_add(t->index);
565 /* Set the reference to the Java object to NULL. */
567 thread_set_object(t, NULL);
569 /* Add the thread data structure to the free list. */
571 threadlist_free_add(t);
573 /* Unlock the thread lists. */
579 /* threads_thread_start_internal ***********************************************
581 Start an internal thread in the JVM. No Java thread objects exists
585 name.......UTF-8 name of the thread
586 f..........function pointer to C function to start
588 *******************************************************************************/
590 bool threads_thread_start_internal(utf *name, functionptr f)
594 /* Enter the join-mutex, so if the main-thread is currently
595 waiting to join all threads, the number of non-daemon threads
598 threads_mutex_join_lock();
600 /* Create internal thread data-structure. */
604 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
606 /* The thread is flagged as (non-)daemon thread, we can leave the
609 threads_mutex_join_unlock();
611 /* Create the Java thread object. */
613 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
616 /* Start the thread. */
618 threads_impl_thread_start(t, f);
620 /* everything's ok */
626 /* threads_thread_start ********************************************************
628 Start a Java thread in the JVM. Only the java thread object exists
632 object.....the java thread object java.lang.Thread
634 *******************************************************************************/
636 void threads_thread_start(java_handle_t *object)
638 java_lang_Thread jlt(object);
640 /* Enter the join-mutex, so if the main-thread is currently
641 waiting to join all threads, the number of non-daemon threads
644 threads_mutex_join_lock();
646 /* Create internal thread data-structure. */
648 threadobject* t = thread_new();
650 /* this is a normal Java thread */
652 t->flags |= THREAD_FLAG_JAVA;
654 #if defined(ENABLE_JAVASE)
655 /* Is this a daemon thread? */
657 if (jlt.get_daemon() == true)
658 t->flags |= THREAD_FLAG_DAEMON;
661 /* The thread is flagged and (non-)daemon thread, we can leave the
664 threads_mutex_join_unlock();
666 /* Link the two objects together. */
668 thread_set_object(t, object);
670 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
672 /* Get the java.lang.VMThread object and do some sanity checks. */
673 java_lang_VMThread jlvmt(jlt.get_vmThread());
675 assert(jlvmt.get_handle() != NULL);
676 assert(jlvmt.get_vmdata() == NULL);
680 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
684 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
686 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
689 # error unknown classpath configuration
692 /* Start the thread. Don't pass a function pointer (NULL) since
693 we want Thread.run()V here. */
695 threads_impl_thread_start(t, NULL);
700 * Attaches the current thread to the VM.
702 * @param vm_aargs Attach arguments.
703 * @param isdaemon true if the attached thread should be a daemon
706 * @return true on success, false otherwise.
708 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
714 java_handle_t *group;
716 /* If the current thread has already been attached, this operation
719 result = thread_current_is_attached();
724 /* Enter the join-mutex, so if the main-thread is currently
725 waiting to join all threads, the number of non-daemon threads
728 threads_mutex_join_lock();
730 /* Create internal thread data structure. */
734 /* Thread is a Java thread and running. */
736 t->flags = THREAD_FLAG_JAVA;
739 t->flags |= THREAD_FLAG_DAEMON;
741 /* Store the internal thread data-structure in the TSD. */
743 thread_set_current(t);
745 /* The thread is flagged and (non-)daemon thread, we can leave the
748 threads_mutex_join_unlock();
750 DEBUGTHREADS("attaching", t);
752 /* Get the thread name. */
754 if (vm_aargs != NULL) {
755 u = utf_new_char(vm_aargs->name);
761 name = javastring_new(u);
763 #if defined(ENABLE_JAVASE)
764 /* Get the threadgroup. */
766 if (vm_aargs != NULL)
767 group = (java_handle_t *) vm_aargs->group;
771 /* If no threadgroup was given, use the main threadgroup. */
774 group = threadgroup_main;
777 #if defined(ENABLE_INTRP)
778 /* create interpreter stack */
781 MSET(intrp_main_stack, 0, u1, opt_stacksize);
782 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
786 /* Create the Java thread object. */
788 if (!thread_create_object(t, name, group))
791 /* The thread is completely initialized. */
793 thread_set_state_runnable(t);
800 * Attaches the current external thread to the VM. This function is
801 * called by JNI's AttachCurrentThread.
803 * @param vm_aargs Attach arguments.
804 * @param isdaemon true if the attached thread should be a daemon
807 * @return true on success, false otherwise.
809 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
813 #if defined(ENABLE_GC_BOEHM)
814 struct GC_stack_base sb;
817 #if defined(ENABLE_GC_BOEHM)
818 /* Register the thread with Boehm-GC. This must happen before the
819 thread allocates any memory from the GC heap.*/
821 result = GC_get_stack_base(&sb);
823 if (result != GC_SUCCESS)
824 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
826 GC_register_my_thread(&sb);
829 result = thread_attach_current_thread(vm_aargs, isdaemon);
831 if (result == false) {
832 #if defined(ENABLE_GC_BOEHM)
833 /* Unregister the thread. */
835 GC_unregister_my_thread();
846 * Detaches the current external thread from the VM. This function is
847 * called by JNI's DetachCurrentThread.
849 * @return true on success, false otherwise.
851 bool thread_detach_current_external_thread(void)
855 result = thread_detach_current_thread();
860 #if defined(ENABLE_GC_BOEHM)
861 /* Unregister the thread with Boehm-GC. This must happen after
862 the thread allocates any memory from the GC heap. */
864 /* Don't detach the main thread. This is a workaround for
865 OpenJDK's java binary. */
866 if (thread_get_current()->index != 1)
867 GC_unregister_my_thread();
874 /* thread_fprint_name **********************************************************
876 Print the name of the given thread to the given stream.
879 t ........ thread data-structure
880 stream ... stream to print to
882 *******************************************************************************/
884 void thread_fprint_name(threadobject *t, FILE *stream)
886 if (thread_get_object(t) == NULL)
889 java_lang_Thread jlt(thread_get_object(t));
891 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
893 java_handle_t* name = jlt.get_name();
894 javastring_fprint(name, stream);
896 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
898 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
899 java_chararray_t *name;
901 /* FIXME This prints to stdout. */
902 utf_display_printable_ascii(utf_null);
905 # error unknown classpath configuration
910 /* thread_print_info ***********************************************************
912 Print information of the passed thread.
915 t ... thread data-structure.
917 *******************************************************************************/
919 void thread_print_info(threadobject *t)
921 java_lang_Thread jlt(thread_get_object(t));
923 /* Print as much as we can when we are in state NEW. */
925 if (jlt.get_handle() != NULL) {
926 /* Print thread name. */
929 thread_fprint_name(t, stdout);
935 if (thread_is_daemon(t))
938 if (jlt.get_handle() != NULL) {
939 printf(" prio=%d", jlt.get_priority());
942 #if SIZEOF_VOID_P == 8
943 printf(" t=0x%016lx tid=0x%016lx (%ld)",
944 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
946 printf(" t=0x%08x tid=0x%08x (%d)",
947 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
950 printf(" index=%d", t->index);
952 /* Print thread state. */
954 int state = cacaothread_get_state(t);
957 case THREAD_STATE_NEW:
960 case THREAD_STATE_RUNNABLE:
963 case THREAD_STATE_BLOCKED:
966 case THREAD_STATE_WAITING:
969 case THREAD_STATE_TIMED_WAITING:
970 printf(" waiting on condition");
972 case THREAD_STATE_TERMINATED:
973 printf(" terminated");
976 vm_abort("thread_print_info: unknown thread state %d", state);
981 /* threads_get_current_tid *****************************************************
983 Return the tid of the current thread.
988 *******************************************************************************/
990 intptr_t threads_get_current_tid(void)
992 threadobject *thread;
994 thread = THREADOBJECT;
996 /* this may happen during bootstrap */
1001 return (intptr_t) thread->tid;
1005 /* thread_set_state_runnable ***************************************************
1007 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1009 NOTE: If the thread has already terminated, don't set the state.
1010 This is important for threads_detach_thread.
1012 *******************************************************************************/
1014 void thread_set_state_runnable(threadobject *t)
1016 /* Set the state inside a lock. */
1020 if (t->state != THREAD_STATE_TERMINATED) {
1021 t->state = THREAD_STATE_RUNNABLE;
1023 DEBUGTHREADS("is RUNNABLE", t);
1026 threadlist_unlock();
1030 /* thread_set_state_waiting ****************************************************
1032 Set the current state of the given thread to THREAD_STATE_WAITING.
1034 NOTE: If the thread has already terminated, don't set the state.
1035 This is important for threads_detach_thread.
1037 *******************************************************************************/
1039 void thread_set_state_waiting(threadobject *t)
1041 /* Set the state inside a lock. */
1045 if (t->state != THREAD_STATE_TERMINATED) {
1046 t->state = THREAD_STATE_WAITING;
1048 DEBUGTHREADS("is WAITING", t);
1051 threadlist_unlock();
1055 /* thread_set_state_timed_waiting **********************************************
1057 Set the current state of the given thread to
1058 THREAD_STATE_TIMED_WAITING.
1060 NOTE: If the thread has already terminated, don't set the state.
1061 This is important for threads_detach_thread.
1063 *******************************************************************************/
1065 void thread_set_state_timed_waiting(threadobject *t)
1067 /* Set the state inside a lock. */
1071 if (t->state != THREAD_STATE_TERMINATED) {
1072 t->state = THREAD_STATE_TIMED_WAITING;
1074 DEBUGTHREADS("is TIMED_WAITING", t);
1077 threadlist_unlock();
1081 /* thread_set_state_terminated *************************************************
1083 Set the current state of the given thread to
1084 THREAD_STATE_TERMINATED.
1086 *******************************************************************************/
1088 void thread_set_state_terminated(threadobject *t)
1090 /* Set the state inside a lock. */
1094 t->state = THREAD_STATE_TERMINATED;
1096 DEBUGTHREADS("is TERMINATED", t);
1098 threadlist_unlock();
1102 /* thread_get_thread **********************************************************
1104 Return the thread data structure of the given Java thread object.
1107 h ... java.lang.{VM}Thread object
1112 *******************************************************************************/
1114 threadobject *thread_get_thread(java_handle_t *h)
1116 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1118 java_lang_VMThread jlvmt(h);
1119 threadobject* t = jlvmt.get_vmdata();
1121 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1123 /* 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_JAVA_RUNTIME_LIBRARY_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)
1160 state = cacaothread_get_state(t);
1163 case THREAD_STATE_NEW:
1164 case THREAD_STATE_TERMINATED:
1167 case THREAD_STATE_RUNNABLE:
1168 case THREAD_STATE_BLOCKED:
1169 case THREAD_STATE_WAITING:
1170 case THREAD_STATE_TIMED_WAITING:
1174 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1177 /* keep compiler happy */
1183 /* threads_dump ****************************************************************
1185 Dumps info for all threads running in the JVM. This function is
1186 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1188 *******************************************************************************/
1190 void threads_dump(void)
1194 /* XXX we should stop the world here */
1196 /* Lock the thread lists. */
1200 printf("Full thread dump CACAO "VERSION":\n");
1202 /* iterate over all started threads */
1204 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1205 /* ignore threads which are in state NEW */
1206 if (t->state == THREAD_STATE_NEW)
1209 #if defined(ENABLE_GC_CACAO)
1210 /* Suspend the thread. */
1211 /* XXX Is the suspend reason correct? */
1213 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1214 vm_abort("threads_dump: threads_suspend_thread failed");
1217 /* Print thread info. */
1220 thread_print_info(t);
1223 /* Print trace of thread. */
1225 stacktrace_print_of_thread(t);
1227 #if defined(ENABLE_GC_CACAO)
1228 /* Resume the thread. */
1230 if (threads_resume_thread(t) == false)
1231 vm_abort("threads_dump: threads_resume_thread failed");
1235 /* Unlock the thread lists. */
1237 threadlist_unlock();
1244 * These are local overrides for various environment variables in Emacs.
1245 * Please do not remove this and leave it at the end of the file, where
1246 * Emacs will automagically detect them.
1247 * ---------------------------------------------------------------------
1250 * indent-tabs-mode: t
1254 * vim:noexpandtab:sw=4:ts=4: