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/builtin.h"
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 #if defined(ENABLE_GC_CACAO)
489 /* Register reference to java.lang.Thread with the GC. */
490 /* FIXME is it ok to do this only once? */
492 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
493 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
496 /* Initialize the implementation-specific bits. */
498 threads_impl_thread_init(t);
501 /* Pre-compute the thinlock-word. */
506 t->thinlock = lock_pre_compute_thinlock(t->index);
508 t->state = THREAD_STATE_NEW;
510 #if defined(ENABLE_GC_CACAO)
511 t->flags |= THREAD_FLAG_IN_NATIVE;
514 /* Initialize the implementation-specific bits. */
516 threads_impl_thread_reuse(t);
518 /* Add the thread to the thread list. */
522 /* Unlock the thread lists. */
530 /* thread_free *****************************************************************
532 Remove the thread from the threads-list and free the internal
533 thread data structure. The thread index is added to the
534 thread-index free-list.
537 t ... thread data structure
539 *******************************************************************************/
541 void thread_free(threadobject *t)
543 /* Lock the thread lists. */
547 /* Remove the thread from the thread-list. */
549 threadlist_remove(t);
551 /* Add the thread index to the free list. */
553 threadlist_index_add(t->index);
555 /* Set the reference to the Java object to NULL. */
557 thread_set_object(t, NULL);
559 /* Add the thread data structure to the free list. */
561 threadlist_free_add(t);
563 /* Unlock the thread lists. */
569 /* threads_thread_start_internal ***********************************************
571 Start an internal thread in the JVM. No Java thread objects exists
575 name.......UTF-8 name of the thread
576 f..........function pointer to C function to start
578 *******************************************************************************/
580 bool threads_thread_start_internal(utf *name, functionptr f)
584 /* Enter the join-mutex, so if the main-thread is currently
585 waiting to join all threads, the number of non-daemon threads
588 threads_mutex_join_lock();
590 /* Create internal thread data-structure. */
594 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
596 /* The thread is flagged as (non-)daemon thread, we can leave the
599 threads_mutex_join_unlock();
601 /* Create the Java thread object. */
603 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
606 /* Start the thread. */
608 threads_impl_thread_start(t, f);
610 /* everything's ok */
616 /* threads_thread_start ********************************************************
618 Start a Java thread in the JVM. Only the java thread object exists
622 object.....the java thread object java.lang.Thread
624 *******************************************************************************/
626 void threads_thread_start(java_handle_t *object)
628 java_lang_Thread jlt(object);
630 /* Enter the join-mutex, so if the main-thread is currently
631 waiting to join all threads, the number of non-daemon threads
634 threads_mutex_join_lock();
636 /* Create internal thread data-structure. */
638 threadobject* t = thread_new();
640 /* this is a normal Java thread */
642 t->flags |= THREAD_FLAG_JAVA;
644 #if defined(ENABLE_JAVASE)
645 /* Is this a daemon thread? */
647 if (jlt.get_daemon() == true)
648 t->flags |= THREAD_FLAG_DAEMON;
651 /* The thread is flagged and (non-)daemon thread, we can leave the
654 threads_mutex_join_unlock();
656 /* Link the two objects together. */
658 thread_set_object(t, object);
660 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
662 /* Get the java.lang.VMThread object and do some sanity checks. */
663 java_lang_VMThread jlvmt(jlt.get_vmThread());
665 assert(jlvmt.get_handle() != NULL);
666 assert(jlvmt.get_vmdata() == NULL);
670 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
674 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
676 jlt.set_vm_thread(t);
679 # error unknown classpath configuration
682 /* Start the thread. Don't pass a function pointer (NULL) since
683 we want Thread.run()V here. */
685 threads_impl_thread_start(t, NULL);
690 * Attaches the current thread to the VM.
692 * @param vm_aargs Attach arguments.
693 * @param isdaemon true if the attached thread should be a daemon
696 * @return true on success, false otherwise.
698 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
704 java_handle_t *group;
706 /* If the current thread has already been attached, this operation
709 result = thread_current_is_attached();
714 /* Enter the join-mutex, so if the main-thread is currently
715 waiting to join all threads, the number of non-daemon threads
718 threads_mutex_join_lock();
720 /* Create internal thread data structure. */
724 /* Thread is a Java thread and running. */
726 t->flags = THREAD_FLAG_JAVA;
729 t->flags |= THREAD_FLAG_DAEMON;
731 /* Store the internal thread data-structure in the TSD. */
733 thread_set_current(t);
735 /* The thread is flagged and (non-)daemon thread, we can leave the
738 threads_mutex_join_unlock();
740 DEBUGTHREADS("attaching", t);
742 /* Get the thread name. */
744 if (vm_aargs != NULL) {
745 u = utf_new_char(vm_aargs->name);
751 name = javastring_new(u);
753 #if defined(ENABLE_JAVASE)
754 /* Get the threadgroup. */
756 if (vm_aargs != NULL)
757 group = (java_handle_t *) vm_aargs->group;
761 /* If no threadgroup was given, use the main threadgroup. */
764 group = threadgroup_main;
767 #if defined(ENABLE_INTRP)
768 /* create interpreter stack */
771 MSET(intrp_main_stack, 0, u1, opt_stacksize);
772 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
776 /* Create the Java thread object. */
778 if (!thread_create_object(t, name, group))
781 /* The thread is completely initialized. */
783 thread_set_state_runnable(t);
790 * Attaches the current external thread to the VM. This function is
791 * called by JNI's AttachCurrentThread.
793 * @param vm_aargs Attach arguments.
794 * @param isdaemon true if the attached thread should be a daemon
797 * @return true on success, false otherwise.
799 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
803 #if defined(ENABLE_GC_BOEHM)
804 struct GC_stack_base sb;
807 #if defined(ENABLE_GC_BOEHM)
808 /* Register the thread with Boehm-GC. This must happen before the
809 thread allocates any memory from the GC heap.*/
811 result = GC_get_stack_base(&sb);
813 if (result != GC_SUCCESS)
814 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
816 GC_register_my_thread(&sb);
819 result = thread_attach_current_thread(vm_aargs, isdaemon);
821 if (result == false) {
822 #if defined(ENABLE_GC_BOEHM)
823 /* Unregister the thread. */
825 GC_unregister_my_thread();
836 * Detaches the current external thread from the VM. This function is
837 * called by JNI's DetachCurrentThread.
839 * @return true on success, false otherwise.
841 bool thread_detach_current_external_thread(void)
845 result = thread_detach_current_thread();
850 #if defined(ENABLE_GC_BOEHM)
851 /* Unregister the thread with Boehm-GC. This must happen after
852 the thread allocates any memory from the GC heap. */
854 /* Don't detach the main thread. This is a workaround for
855 OpenJDK's java binary. */
856 if (thread_get_current()->index != 1)
857 GC_unregister_my_thread();
864 /* thread_fprint_name **********************************************************
866 Print the name of the given thread to the given stream.
869 t ........ thread data-structure
870 stream ... stream to print to
872 *******************************************************************************/
874 void thread_fprint_name(threadobject *t, FILE *stream)
876 if (thread_get_object(t) == NULL)
879 java_lang_Thread jlt(thread_get_object(t));
881 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
883 java_handle_t* name = jlt.get_name();
884 javastring_fprint(name, stream);
886 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
888 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
889 java_chararray_t *name;
891 /* FIXME This prints to stdout. */
892 utf_display_printable_ascii(utf_null);
895 # error unknown classpath configuration
900 /* thread_print_info ***********************************************************
902 Print information of the passed thread.
905 t ... thread data-structure.
907 *******************************************************************************/
909 void thread_print_info(threadobject *t)
911 java_lang_Thread jlt(thread_get_object(t));
913 /* Print as much as we can when we are in state NEW. */
915 if (jlt.get_handle() != NULL) {
916 /* Print thread name. */
919 thread_fprint_name(t, stdout);
925 if (thread_is_daemon(t))
928 if (jlt.get_handle() != NULL) {
929 printf(" prio=%d", jlt.get_priority());
932 #if SIZEOF_VOID_P == 8
933 printf(" t=0x%016lx tid=0x%016lx (%ld)",
934 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
936 printf(" t=0x%08x tid=0x%08x (%d)",
937 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
940 printf(" index=%d", t->index);
942 /* Print thread state. */
944 int state = cacaothread_get_state(t);
947 case THREAD_STATE_NEW:
950 case THREAD_STATE_RUNNABLE:
953 case THREAD_STATE_BLOCKED:
956 case THREAD_STATE_WAITING:
959 case THREAD_STATE_TIMED_WAITING:
960 printf(" waiting on condition");
962 case THREAD_STATE_TERMINATED:
963 printf(" terminated");
966 vm_abort("thread_print_info: unknown thread state %d", state);
971 /* threads_get_current_tid *****************************************************
973 Return the tid of the current thread.
978 *******************************************************************************/
980 intptr_t threads_get_current_tid(void)
982 threadobject *thread;
984 thread = THREADOBJECT;
986 /* this may happen during bootstrap */
991 return (intptr_t) thread->tid;
995 /* thread_set_state_runnable ***************************************************
997 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
999 NOTE: If the thread has already terminated, don't set the state.
1000 This is important for threads_detach_thread.
1002 *******************************************************************************/
1004 void thread_set_state_runnable(threadobject *t)
1006 /* Set the state inside a lock. */
1010 if (t->state != THREAD_STATE_TERMINATED) {
1011 t->state = THREAD_STATE_RUNNABLE;
1013 DEBUGTHREADS("is RUNNABLE", t);
1016 threadlist_unlock();
1020 /* thread_set_state_waiting ****************************************************
1022 Set the current state of the given thread to THREAD_STATE_WAITING.
1024 NOTE: If the thread has already terminated, don't set the state.
1025 This is important for threads_detach_thread.
1027 *******************************************************************************/
1029 void thread_set_state_waiting(threadobject *t)
1031 /* Set the state inside a lock. */
1035 if (t->state != THREAD_STATE_TERMINATED) {
1036 t->state = THREAD_STATE_WAITING;
1038 DEBUGTHREADS("is WAITING", t);
1041 threadlist_unlock();
1045 /* thread_set_state_timed_waiting **********************************************
1047 Set the current state of the given thread to
1048 THREAD_STATE_TIMED_WAITING.
1050 NOTE: If the thread has already terminated, don't set the state.
1051 This is important for threads_detach_thread.
1053 *******************************************************************************/
1055 void thread_set_state_timed_waiting(threadobject *t)
1057 /* Set the state inside a lock. */
1061 if (t->state != THREAD_STATE_TERMINATED) {
1062 t->state = THREAD_STATE_TIMED_WAITING;
1064 DEBUGTHREADS("is TIMED_WAITING", t);
1067 threadlist_unlock();
1071 /* thread_set_state_terminated *************************************************
1073 Set the current state of the given thread to
1074 THREAD_STATE_TERMINATED.
1076 *******************************************************************************/
1078 void thread_set_state_terminated(threadobject *t)
1080 /* Set the state inside a lock. */
1084 t->state = THREAD_STATE_TERMINATED;
1086 DEBUGTHREADS("is TERMINATED", t);
1088 threadlist_unlock();
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)
1106 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1108 java_lang_VMThread jlvmt(h);
1109 threadobject* t = jlvmt.get_vmdata();
1111 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1113 /* XXX This is just a quick hack. */
1119 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1120 LLNI_equals(t->object, h, equal);
1126 threadlist_unlock();
1128 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1130 log_println("threads_get_thread: IMPLEMENT ME!");
1131 threadobject* t = NULL;
1134 # error unknown classpath configuration
1141 /* threads_thread_is_alive *****************************************************
1143 Returns if the give thread is alive.
1145 *******************************************************************************/
1147 bool threads_thread_is_alive(threadobject *t)
1151 state = cacaothread_get_state(t);
1154 case THREAD_STATE_NEW:
1155 case THREAD_STATE_TERMINATED:
1158 case THREAD_STATE_RUNNABLE:
1159 case THREAD_STATE_BLOCKED:
1160 case THREAD_STATE_WAITING:
1161 case THREAD_STATE_TIMED_WAITING:
1165 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1168 /* keep compiler happy */
1174 /* threads_dump ****************************************************************
1176 Dumps info for all threads running in the JVM. This function is
1177 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1179 *******************************************************************************/
1181 void threads_dump(void)
1185 /* XXX we should stop the world here */
1187 /* Lock the thread lists. */
1191 printf("Full thread dump CACAO "VERSION":\n");
1193 /* iterate over all started threads */
1195 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1196 /* ignore threads which are in state NEW */
1197 if (t->state == THREAD_STATE_NEW)
1200 #if defined(ENABLE_GC_CACAO)
1201 /* Suspend the thread. */
1202 /* XXX Is the suspend reason correct? */
1204 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1205 vm_abort("threads_dump: threads_suspend_thread failed");
1208 /* Print thread info. */
1211 thread_print_info(t);
1214 /* Print trace of thread. */
1216 stacktrace_print_of_thread(t);
1218 #if defined(ENABLE_GC_CACAO)
1219 /* Resume the thread. */
1221 if (threads_resume_thread(t) == false)
1222 vm_abort("threads_dump: threads_resume_thread failed");
1226 /* Unlock the thread lists. */
1228 threadlist_unlock();
1235 * These are local overrides for various environment variables in Emacs.
1236 * Please do not remove this and leave it at the end of the file, where
1237 * Emacs will automagically detect them.
1238 * ---------------------------------------------------------------------
1241 * indent-tabs-mode: t
1245 * vim:noexpandtab:sw=4:ts=4: