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/llni.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
46 #include "threads/threadlist.h"
47 #include "threads/thread.hpp"
49 #include "vm/jit/builtin.hpp"
51 #include "vm/exceptions.hpp"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/method.h"
55 #include "vm/options.h"
56 #include "vm/string.hpp"
60 #if defined(ENABLE_STATISTICS)
61 # include "vm/statistics.h"
64 #include "vm/jit/stacktrace.hpp"
70 /* global variables ***********************************************************/
72 static methodinfo *thread_method_init;
73 static java_handle_t *threadgroup_system;
74 static java_handle_t *threadgroup_main;
76 #if defined(__LINUX__)
77 /* XXX Remove for exact-GC. */
78 bool threads_pthreads_implementation_nptl;
82 /* static functions ***********************************************************/
84 static void thread_create_initial_threadgroups(void);
85 static void thread_create_initial_thread(void);
86 static threadobject *thread_new(void);
89 /* threads_preinit *************************************************************
91 Do some early initialization of stuff required.
93 *******************************************************************************/
95 void threads_preinit(void)
97 threadobject *mainthread;
98 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
103 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
105 #if defined(__LINUX__)
106 /* XXX Remove for exact-GC. */
108 /* On Linux we need to check the pthread implementation. */
110 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
111 /* If the glibc is a pre-2.3.2 version, we fall back to
114 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
115 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
117 /* Some systems return as length 0 (maybe cross-compilation
118 related). In this case we also fall back to linuxthreads. */
121 pathbuf = MNEW(char, len);
123 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
125 if (strstr(pathbuf, "NPTL") != NULL)
126 threads_pthreads_implementation_nptl = true;
128 threads_pthreads_implementation_nptl = false;
131 threads_pthreads_implementation_nptl = false;
133 threads_pthreads_implementation_nptl = false;
137 /* Initialize the threads implementation (sets the thinlock on the
140 threads_impl_preinit();
142 /* Create internal thread data-structure for the main thread. */
144 mainthread = thread_new();
146 /* The main thread should always have index 1. */
148 if (mainthread->index != 1)
149 vm_abort("threads_preinit: main thread index not 1: %d != 1",
152 /* thread is a Java thread and running */
154 mainthread->flags |= THREAD_FLAG_JAVA;
155 mainthread->state = THREAD_STATE_RUNNABLE;
157 /* Store the internal thread data-structure in the TSD. */
159 thread_set_current(mainthread);
163 /* threads_init ****************************************************************
165 Initialize the main thread.
167 *******************************************************************************/
169 void threads_init(void)
171 TRACESUBSYSTEMINITIALIZATION("threads_init");
173 /* Create the system and main thread groups. */
175 thread_create_initial_threadgroups();
177 /* Cache the java.lang.Thread initialization method. */
179 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
182 class_resolveclassmethod(class_java_lang_Thread,
184 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
185 class_java_lang_Thread,
188 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
191 class_resolveclassmethod(class_java_lang_Thread,
193 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
194 class_java_lang_Thread,
197 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
200 class_resolveclassmethod(class_java_lang_Thread,
202 utf_java_lang_String__void,
203 class_java_lang_Thread,
207 # error unknown classpath configuration
210 if (thread_method_init == NULL)
211 vm_abort("threads_init: failed to resolve thread init method");
213 thread_create_initial_thread();
217 /* thread_create_object ********************************************************
219 Create a Java thread object for the given thread data-structure,
220 initializes it and adds the thread to the threadgroup.
225 name .... thread name
226 group ... threadgroup
230 *******************************************************************************/
232 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
234 /* Create a java.lang.Thread Java object. */
236 java_handle_t* h = builtin_new(class_java_lang_Thread);
241 java_lang_Thread jlt(h);
243 // Set the Java object in the thread data-structure. This
244 // indicates that the thread is attached to the VM.
245 thread_set_object(t, jlt.get_handle());
247 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
249 h = builtin_new(class_java_lang_VMThread);
254 // Create and initialize a java.lang.VMThread object.
255 java_lang_VMThread jlvmt(h, jlt.get_handle(), t);
258 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
260 bool isdaemon = thread_is_daemon(t);
262 (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(),
263 name, NORM_PRIORITY, isdaemon);
265 if (exceptions_get_exception())
268 // Set the ThreadGroup in the Java thread object.
269 jlt.set_group(group);
271 /* Add thread to the threadgroup. */
274 LLNI_class_get(group, c);
276 methodinfo* m = class_resolveclassmethod(c,
278 utf_java_lang_Thread__V,
279 class_java_lang_ThreadGroup,
285 (void) vm_call_method(m, group, jlt.get_handle());
287 if (exceptions_get_exception())
290 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
292 /* Set the priority. java.lang.Thread.<init> requires it because
293 it sets the priority of the current thread to the parent's one
294 (which is the current thread in this case). */
295 jlt.set_priority(NORM_PRIORITY);
297 // Call: java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V
299 (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name);
301 if (exceptions_get_exception())
304 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
306 // Set the thread data-structure in the Java thread object.
307 jlt.set_vm_thread(t);
309 // Call: public Thread(Ljava/lang/String;)V
310 (void) vm_call_method(thread_method_init, jlt.get_handle(), name);
312 if (exceptions_get_exception())
316 # error unknown classpath configuration
323 /* thread_create_initial_threadgroups ******************************************
325 Create the initial threadgroups.
328 Create the main threadgroup only and set the system
329 threadgroup to the main threadgroup.
332 Create the system and main threadgroup.
335 This function is a no-op.
337 *******************************************************************************/
339 static void thread_create_initial_threadgroups(void)
341 #if defined(ENABLE_JAVASE)
342 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
344 /* Allocate and initialize the main thread group. */
346 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
348 if (threadgroup_main == NULL)
349 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
351 /* Use the same threadgroup for system as for main. */
353 threadgroup_system = threadgroup_main;
355 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
360 /* Allocate and initialize the system thread group. */
362 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
364 if (threadgroup_system == NULL)
365 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
367 /* Allocate and initialize the main thread group. */
369 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
371 if (threadgroup_main == NULL)
372 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
374 name = javastring_new(utf_main);
376 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
378 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
379 class_java_lang_ThreadGroup,
383 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
385 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
387 if (exceptions_get_exception())
388 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
391 # error unknown classpath configuration
397 /* thread_create_initial_thread ***********************************************
399 Create the initial thread: main
401 *******************************************************************************/
403 static void thread_create_initial_thread(void)
408 /* Get the main-thread (NOTE: The main thread is always the first
409 thread in the list). */
411 t = threadlist_first();
413 /* The thread name. */
415 name = javastring_new(utf_main);
417 #if defined(ENABLE_INTRP)
418 /* create interpreter stack */
421 MSET(intrp_main_stack, 0, u1, opt_stacksize);
422 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
426 /* Create the Java thread object. */
428 if (!thread_create_object(t, name, threadgroup_main))
429 vm_abort("thread_create_initial_thread: failed to create Java object");
431 /* Initialize the implementation specific bits. */
435 DEBUGTHREADS("starting (main)", t);
439 /* thread_new ******************************************************************
441 Allocates and initializes an internal thread data-structure and
442 adds it to the threads list.
444 *******************************************************************************/
446 static threadobject *thread_new(void)
451 /* Lock the thread lists */
455 index = threadlist_get_free_index();
457 /* Allocate a thread data structure. */
459 /* First, try to get one from the free-list. */
461 t = threadlist_free_first();
464 /* Remove from free list. */
466 threadlist_free_remove(t);
468 /* Equivalent of MZERO on the else path */
470 threads_impl_thread_clear(t);
473 #if defined(ENABLE_GC_BOEHM)
474 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
476 t = NEW(threadobject);
479 #if defined(ENABLE_STATISTICS)
481 size_threadobject += sizeof(threadobject);
486 MZERO(t, threadobject, 1);
488 // Initialize the mutex and the condition.
489 t->flc_lock = new Mutex();
490 t->flc_cond = new Condition();
492 t->waitmutex = new Mutex();
493 t->waitcond = new Condition();
495 t->suspendmutex = new Mutex();
496 t->suspendcond = new Condition();
498 #if defined(ENABLE_TLH)
502 #if defined(ENABLE_GC_CACAO)
503 /* Register reference to java.lang.Thread with the GC. */
504 /* FIXME is it ok to do this only once? */
506 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
507 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
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 jlt.set_vm_thread(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!");
1141 threadobject* t = NULL;
1144 # error unknown classpath configuration
1151 /* threads_thread_is_alive *****************************************************
1153 Returns if the give thread is alive.
1155 *******************************************************************************/
1157 bool threads_thread_is_alive(threadobject *t)
1161 state = cacaothread_get_state(t);
1164 case THREAD_STATE_NEW:
1165 case THREAD_STATE_TERMINATED:
1168 case THREAD_STATE_RUNNABLE:
1169 case THREAD_STATE_BLOCKED:
1170 case THREAD_STATE_WAITING:
1171 case THREAD_STATE_TIMED_WAITING:
1175 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1178 /* keep compiler happy */
1184 /* threads_dump ****************************************************************
1186 Dumps info for all threads running in the JVM. This function is
1187 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1189 *******************************************************************************/
1191 void threads_dump(void)
1195 /* XXX we should stop the world here */
1197 /* Lock the thread lists. */
1201 printf("Full thread dump CACAO "VERSION":\n");
1203 /* iterate over all started threads */
1205 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1206 /* ignore threads which are in state NEW */
1207 if (t->state == THREAD_STATE_NEW)
1210 #if defined(ENABLE_GC_CACAO)
1211 /* Suspend the thread. */
1212 /* XXX Is the suspend reason correct? */
1214 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1215 vm_abort("threads_dump: threads_suspend_thread failed");
1218 /* Print thread info. */
1221 thread_print_info(t);
1224 /* Print trace of thread. */
1226 stacktrace_print_of_thread(t);
1228 #if defined(ENABLE_GC_CACAO)
1229 /* Resume the thread. */
1231 if (threads_resume_thread(t) == false)
1232 vm_abort("threads_dump: threads_resume_thread failed");
1236 /* Unlock the thread lists. */
1238 threadlist_unlock();
1245 * These are local overrides for various environment variables in Emacs.
1246 * Please do not remove this and leave it at the end of the file, where
1247 * Emacs will automagically detect them.
1248 * ---------------------------------------------------------------------
1251 * indent-tabs-mode: t
1255 * vim:noexpandtab:sw=4:ts=4: