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.
315 jlt.set_vm_thread(t);
317 // Call: public Thread(Ljava/lang/String;)V
318 (void) vm_call_method(thread_method_init, jlt.get_handle(), name);
320 if (exceptions_get_exception())
324 # error unknown classpath configuration
331 /* thread_create_initial_threadgroups ******************************************
333 Create the initial threadgroups.
336 Create the main threadgroup only and set the system
337 threadgroup to the main threadgroup.
340 Create the system and main threadgroup.
343 This function is a no-op.
345 *******************************************************************************/
347 static void thread_create_initial_threadgroups(void)
349 #if defined(ENABLE_JAVASE)
350 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
352 /* Allocate and initialize the main thread group. */
354 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
356 if (threadgroup_main == NULL)
357 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
359 /* Use the same threadgroup for system as for main. */
361 threadgroup_system = threadgroup_main;
363 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
368 /* Allocate and initialize the system thread group. */
370 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
372 if (threadgroup_system == NULL)
373 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
375 /* Allocate and initialize the main thread group. */
377 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
379 if (threadgroup_main == NULL)
380 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
382 name = javastring_new(utf_main);
384 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
386 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
387 class_java_lang_ThreadGroup,
391 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
393 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
395 if (exceptions_get_exception())
396 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
399 # error unknown classpath configuration
405 /* thread_create_initial_thread ***********************************************
407 Create the initial thread: main
409 *******************************************************************************/
411 static void thread_create_initial_thread(void)
416 /* Get the main-thread (NOTE: The main thread is always the first
417 thread in the list). */
419 t = threadlist_first();
421 /* The thread name. */
423 name = javastring_new(utf_main);
425 #if defined(ENABLE_INTRP)
426 /* create interpreter stack */
429 MSET(intrp_main_stack, 0, u1, opt_stacksize);
430 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
434 /* Create the Java thread object. */
436 if (!thread_create_object(t, name, threadgroup_main))
437 vm_abort("thread_create_initial_thread: failed to create Java object");
439 /* Initialize the implementation specific bits. */
443 DEBUGTHREADS("starting (main)", t);
447 /* thread_new ******************************************************************
449 Allocates and initializes an internal thread data-structure and
450 adds it to the threads list.
452 *******************************************************************************/
454 static threadobject *thread_new(void)
459 /* Lock the thread lists */
463 index = threadlist_get_free_index();
465 /* Allocate a thread data structure. */
467 /* First, try to get one from the free-list. */
469 t = threadlist_free_first();
472 /* Remove from free list. */
474 threadlist_free_remove(t);
476 /* Equivalent of MZERO on the else path */
478 threads_impl_thread_clear(t);
481 #if defined(ENABLE_GC_BOEHM)
482 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
484 t = NEW(threadobject);
487 #if defined(ENABLE_STATISTICS)
489 size_threadobject += sizeof(threadobject);
494 MZERO(t, threadobject, 1);
496 #if defined(ENABLE_GC_CACAO)
497 /* Register reference to java.lang.Thread with the GC. */
498 /* FIXME is it ok to do this only once? */
500 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
501 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
504 /* Initialize the implementation-specific bits. */
506 threads_impl_thread_init(t);
509 /* Pre-compute the thinlock-word. */
514 t->thinlock = lock_pre_compute_thinlock(t->index);
516 t->state = THREAD_STATE_NEW;
518 #if defined(ENABLE_GC_CACAO)
519 t->flags |= THREAD_FLAG_IN_NATIVE;
522 /* Initialize the implementation-specific bits. */
524 threads_impl_thread_reuse(t);
526 /* Add the thread to the thread list. */
530 /* Unlock the thread lists. */
538 /* thread_free *****************************************************************
540 Remove the thread from the threads-list and free the internal
541 thread data structure. The thread index is added to the
542 thread-index free-list.
545 t ... thread data structure
547 *******************************************************************************/
549 void thread_free(threadobject *t)
551 /* Lock the thread lists. */
555 /* Remove the thread from the thread-list. */
557 threadlist_remove(t);
559 /* Add the thread index to the free list. */
561 threadlist_index_add(t->index);
563 /* Set the reference to the Java object to NULL. */
565 thread_set_object(t, NULL);
567 /* Add the thread data structure to the free list. */
569 threadlist_free_add(t);
571 /* Unlock the thread lists. */
577 /* threads_thread_start_internal ***********************************************
579 Start an internal thread in the JVM. No Java thread objects exists
583 name.......UTF-8 name of the thread
584 f..........function pointer to C function to start
586 *******************************************************************************/
588 bool threads_thread_start_internal(utf *name, functionptr f)
592 /* Enter the join-mutex, so if the main-thread is currently
593 waiting to join all threads, the number of non-daemon threads
596 threads_mutex_join_lock();
598 /* Create internal thread data-structure. */
602 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
604 /* The thread is flagged as (non-)daemon thread, we can leave the
607 threads_mutex_join_unlock();
609 /* Create the Java thread object. */
611 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
614 /* Start the thread. */
616 threads_impl_thread_start(t, f);
618 /* everything's ok */
624 /* threads_thread_start ********************************************************
626 Start a Java thread in the JVM. Only the java thread object exists
630 object.....the java thread object java.lang.Thread
632 *******************************************************************************/
634 void threads_thread_start(java_handle_t *object)
636 java_lang_Thread jlt(object);
638 /* Enter the join-mutex, so if the main-thread is currently
639 waiting to join all threads, the number of non-daemon threads
642 threads_mutex_join_lock();
644 /* Create internal thread data-structure. */
646 threadobject* t = thread_new();
648 /* this is a normal Java thread */
650 t->flags |= THREAD_FLAG_JAVA;
652 #if defined(ENABLE_JAVASE)
653 /* Is this a daemon thread? */
655 if (jlt.get_daemon() == true)
656 t->flags |= THREAD_FLAG_DAEMON;
659 /* The thread is flagged and (non-)daemon thread, we can leave the
662 threads_mutex_join_unlock();
664 /* Link the two objects together. */
666 thread_set_object(t, object);
668 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
670 /* Get the java.lang.VMThread object and do some sanity checks. */
671 java_lang_VMThread jlvmt(jlt.get_vmThread());
673 assert(jlvmt.get_handle() != NULL);
674 assert(jlvmt.get_vmdata() == NULL);
678 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
682 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
684 jlt.set_vm_thread(t);
687 # error unknown classpath configuration
690 /* Start the thread. Don't pass a function pointer (NULL) since
691 we want Thread.run()V here. */
693 threads_impl_thread_start(t, NULL);
698 * Attaches the current thread to the VM.
700 * @param vm_aargs Attach arguments.
701 * @param isdaemon true if the attached thread should be a daemon
704 * @return true on success, false otherwise.
706 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
712 java_handle_t *group;
714 /* If the current thread has already been attached, this operation
717 result = thread_current_is_attached();
722 /* Enter the join-mutex, so if the main-thread is currently
723 waiting to join all threads, the number of non-daemon threads
726 threads_mutex_join_lock();
728 /* Create internal thread data structure. */
732 /* Thread is a Java thread and running. */
734 t->flags = THREAD_FLAG_JAVA;
737 t->flags |= THREAD_FLAG_DAEMON;
739 /* Store the internal thread data-structure in the TSD. */
741 thread_set_current(t);
743 /* The thread is flagged and (non-)daemon thread, we can leave the
746 threads_mutex_join_unlock();
748 DEBUGTHREADS("attaching", t);
750 /* Get the thread name. */
752 if (vm_aargs != NULL) {
753 u = utf_new_char(vm_aargs->name);
759 name = javastring_new(u);
761 #if defined(ENABLE_JAVASE)
762 /* Get the threadgroup. */
764 if (vm_aargs != NULL)
765 group = (java_handle_t *) vm_aargs->group;
769 /* If no threadgroup was given, use the main threadgroup. */
772 group = threadgroup_main;
775 #if defined(ENABLE_INTRP)
776 /* create interpreter stack */
779 MSET(intrp_main_stack, 0, u1, opt_stacksize);
780 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
784 /* Create the Java thread object. */
786 if (!thread_create_object(t, name, group))
789 /* The thread is completely initialized. */
791 thread_set_state_runnable(t);
798 * Attaches the current external thread to the VM. This function is
799 * called by JNI's AttachCurrentThread.
801 * @param vm_aargs Attach arguments.
802 * @param isdaemon true if the attached thread should be a daemon
805 * @return true on success, false otherwise.
807 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
811 #if defined(ENABLE_GC_BOEHM)
812 struct GC_stack_base sb;
815 #if defined(ENABLE_GC_BOEHM)
816 /* Register the thread with Boehm-GC. This must happen before the
817 thread allocates any memory from the GC heap.*/
819 result = GC_get_stack_base(&sb);
821 if (result != GC_SUCCESS)
822 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
824 GC_register_my_thread(&sb);
827 result = thread_attach_current_thread(vm_aargs, isdaemon);
829 if (result == false) {
830 #if defined(ENABLE_GC_BOEHM)
831 /* Unregister the thread. */
833 GC_unregister_my_thread();
844 * Detaches the current external thread from the VM. This function is
845 * called by JNI's DetachCurrentThread.
847 * @return true on success, false otherwise.
849 bool thread_detach_current_external_thread(void)
853 result = thread_detach_current_thread();
858 #if defined(ENABLE_GC_BOEHM)
859 /* Unregister the thread with Boehm-GC. This must happen after
860 the thread allocates any memory from the GC heap. */
862 /* Don't detach the main thread. This is a workaround for
863 OpenJDK's java binary. */
864 if (thread_get_current()->index != 1)
865 GC_unregister_my_thread();
872 /* thread_fprint_name **********************************************************
874 Print the name of the given thread to the given stream.
877 t ........ thread data-structure
878 stream ... stream to print to
880 *******************************************************************************/
882 void thread_fprint_name(threadobject *t, FILE *stream)
884 if (thread_get_object(t) == NULL)
887 java_lang_Thread jlt(thread_get_object(t));
889 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
891 java_handle_t* name = jlt.get_name();
892 javastring_fprint(name, stream);
894 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
896 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
897 java_chararray_t *name;
899 /* FIXME This prints to stdout. */
900 utf_display_printable_ascii(utf_null);
903 # error unknown classpath configuration
908 /* thread_print_info ***********************************************************
910 Print information of the passed thread.
913 t ... thread data-structure.
915 *******************************************************************************/
917 void thread_print_info(threadobject *t)
919 java_lang_Thread jlt(thread_get_object(t));
921 /* Print as much as we can when we are in state NEW. */
923 if (jlt.get_handle() != NULL) {
924 /* Print thread name. */
927 thread_fprint_name(t, stdout);
933 if (thread_is_daemon(t))
936 if (jlt.get_handle() != NULL) {
937 printf(" prio=%d", jlt.get_priority());
940 #if SIZEOF_VOID_P == 8
941 printf(" t=0x%016lx tid=0x%016lx (%ld)",
942 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
944 printf(" t=0x%08x tid=0x%08x (%d)",
945 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
948 printf(" index=%d", t->index);
950 /* Print thread state. */
952 int state = cacaothread_get_state(t);
955 case THREAD_STATE_NEW:
958 case THREAD_STATE_RUNNABLE:
961 case THREAD_STATE_BLOCKED:
964 case THREAD_STATE_WAITING:
967 case THREAD_STATE_TIMED_WAITING:
968 printf(" waiting on condition");
970 case THREAD_STATE_TERMINATED:
971 printf(" terminated");
974 vm_abort("thread_print_info: unknown thread state %d", state);
979 /* threads_get_current_tid *****************************************************
981 Return the tid of the current thread.
986 *******************************************************************************/
988 intptr_t threads_get_current_tid(void)
990 threadobject *thread;
992 thread = THREADOBJECT;
994 /* this may happen during bootstrap */
999 return (intptr_t) thread->tid;
1003 /* thread_set_state_runnable ***************************************************
1005 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1007 NOTE: If the thread has already terminated, don't set the state.
1008 This is important for threads_detach_thread.
1010 *******************************************************************************/
1012 void thread_set_state_runnable(threadobject *t)
1014 /* Set the state inside a lock. */
1018 if (t->state != THREAD_STATE_TERMINATED) {
1019 t->state = THREAD_STATE_RUNNABLE;
1021 DEBUGTHREADS("is RUNNABLE", t);
1024 threadlist_unlock();
1028 /* thread_set_state_waiting ****************************************************
1030 Set the current state of the given thread to THREAD_STATE_WAITING.
1032 NOTE: If the thread has already terminated, don't set the state.
1033 This is important for threads_detach_thread.
1035 *******************************************************************************/
1037 void thread_set_state_waiting(threadobject *t)
1039 /* Set the state inside a lock. */
1043 if (t->state != THREAD_STATE_TERMINATED) {
1044 t->state = THREAD_STATE_WAITING;
1046 DEBUGTHREADS("is WAITING", t);
1049 threadlist_unlock();
1053 /* thread_set_state_timed_waiting **********************************************
1055 Set the current state of the given thread to
1056 THREAD_STATE_TIMED_WAITING.
1058 NOTE: If the thread has already terminated, don't set the state.
1059 This is important for threads_detach_thread.
1061 *******************************************************************************/
1063 void thread_set_state_timed_waiting(threadobject *t)
1065 /* Set the state inside a lock. */
1069 if (t->state != THREAD_STATE_TERMINATED) {
1070 t->state = THREAD_STATE_TIMED_WAITING;
1072 DEBUGTHREADS("is TIMED_WAITING", t);
1075 threadlist_unlock();
1079 /* thread_set_state_terminated *************************************************
1081 Set the current state of the given thread to
1082 THREAD_STATE_TERMINATED.
1084 *******************************************************************************/
1086 void thread_set_state_terminated(threadobject *t)
1088 /* Set the state inside a lock. */
1092 t->state = THREAD_STATE_TERMINATED;
1094 DEBUGTHREADS("is TERMINATED", t);
1096 threadlist_unlock();
1100 /* thread_get_thread **********************************************************
1102 Return the thread data structure of the given Java thread object.
1105 h ... java.lang.{VM}Thread object
1110 *******************************************************************************/
1112 threadobject *thread_get_thread(java_handle_t *h)
1114 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1116 java_lang_VMThread jlvmt(h);
1117 threadobject* t = jlvmt.get_vmdata();
1119 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1121 /* XXX This is just a quick hack. */
1127 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1128 LLNI_equals(t->object, h, equal);
1134 threadlist_unlock();
1136 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1138 log_println("threads_get_thread: IMPLEMENT ME!");
1139 threadobject* t = NULL;
1142 # error unknown classpath configuration
1149 /* threads_thread_is_alive *****************************************************
1151 Returns if the give thread is alive.
1153 *******************************************************************************/
1155 bool threads_thread_is_alive(threadobject *t)
1159 state = cacaothread_get_state(t);
1162 case THREAD_STATE_NEW:
1163 case THREAD_STATE_TERMINATED:
1166 case THREAD_STATE_RUNNABLE:
1167 case THREAD_STATE_BLOCKED:
1168 case THREAD_STATE_WAITING:
1169 case THREAD_STATE_TIMED_WAITING:
1173 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1176 /* keep compiler happy */
1182 /* threads_dump ****************************************************************
1184 Dumps info for all threads running in the JVM. This function is
1185 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1187 *******************************************************************************/
1189 void threads_dump(void)
1193 /* XXX we should stop the world here */
1195 /* Lock the thread lists. */
1199 printf("Full thread dump CACAO "VERSION":\n");
1201 /* iterate over all started threads */
1203 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1204 /* ignore threads which are in state NEW */
1205 if (t->state == THREAD_STATE_NEW)
1208 #if defined(ENABLE_GC_CACAO)
1209 /* Suspend the thread. */
1210 /* XXX Is the suspend reason correct? */
1212 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1213 vm_abort("threads_dump: threads_suspend_thread failed");
1216 /* Print thread info. */
1219 thread_print_info(t);
1222 /* Print trace of thread. */
1224 stacktrace_print_of_thread(t);
1226 #if defined(ENABLE_GC_CACAO)
1227 /* Resume the thread. */
1229 if (threads_resume_thread(t) == false)
1230 vm_abort("threads_dump: threads_resume_thread failed");
1234 /* Unlock the thread lists. */
1236 threadlist_unlock();
1243 * These are local overrides for various environment variables in Emacs.
1244 * Please do not remove this and leave it at the end of the file, where
1245 * Emacs will automagically detect them.
1246 * ---------------------------------------------------------------------
1249 * indent-tabs-mode: t
1253 * vim:noexpandtab:sw=4:ts=4: