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"
52 #include "vm/exceptions.hpp"
53 #include "vm/globals.hpp"
54 #include "vm/javaobjects.hpp"
55 #include "vm/method.h"
56 #include "vm/options.h"
57 #include "vm/string.hpp"
61 #if defined(ENABLE_STATISTICS)
62 # include "vm/statistics.h"
65 #include "vm/jit/stacktrace.hpp"
71 /* global variables ***********************************************************/
73 static methodinfo *thread_method_init;
74 static java_handle_t *threadgroup_system;
75 static java_handle_t *threadgroup_main;
77 #if defined(__LINUX__)
78 /* XXX Remove for exact-GC. */
79 bool threads_pthreads_implementation_nptl;
83 /* static functions ***********************************************************/
85 static void thread_create_initial_threadgroups(void);
86 static void thread_create_initial_thread(void);
87 static threadobject *thread_new(void);
90 /* threads_preinit *************************************************************
92 Do some early initialization of stuff required.
94 *******************************************************************************/
96 void threads_preinit(void)
98 threadobject *mainthread;
99 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
104 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
106 #if defined(__LINUX__)
107 /* XXX Remove for exact-GC. */
109 /* On Linux we need to check the pthread implementation. */
111 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
112 /* If the glibc is a pre-2.3.2 version, we fall back to
115 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
116 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
118 /* Some systems return as length 0 (maybe cross-compilation
119 related). In this case we also fall back to linuxthreads. */
122 pathbuf = MNEW(char, len);
124 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
126 if (strstr(pathbuf, "NPTL") != NULL)
127 threads_pthreads_implementation_nptl = true;
129 threads_pthreads_implementation_nptl = false;
132 threads_pthreads_implementation_nptl = false;
134 threads_pthreads_implementation_nptl = false;
138 /* Initialize the threads implementation (sets the thinlock on the
141 threads_impl_preinit();
143 /* Create internal thread data-structure for the main thread. */
145 mainthread = thread_new();
147 /* The main thread should always have index 1. */
149 if (mainthread->index != 1)
150 vm_abort("threads_preinit: main thread index not 1: %d != 1",
153 /* thread is a Java thread and running */
155 mainthread->flags |= THREAD_FLAG_JAVA;
156 mainthread->state = THREAD_STATE_RUNNABLE;
158 /* Store the internal thread data-structure in the TSD. */
160 thread_set_current(mainthread);
164 /* threads_init ****************************************************************
166 Initialize the main thread.
168 *******************************************************************************/
170 void threads_init(void)
172 TRACESUBSYSTEMINITIALIZATION("threads_init");
174 /* Create the system and main thread groups. */
176 thread_create_initial_threadgroups();
178 /* Cache the java.lang.Thread initialization method. */
180 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
183 class_resolveclassmethod(class_java_lang_Thread,
185 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
186 class_java_lang_Thread,
189 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
192 class_resolveclassmethod(class_java_lang_Thread,
194 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
195 class_java_lang_Thread,
198 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
201 class_resolveclassmethod(class_java_lang_Thread,
203 utf_java_lang_String__void,
204 class_java_lang_Thread,
208 # error unknown classpath configuration
211 if (thread_method_init == NULL)
212 vm_abort("threads_init: failed to resolve thread init method");
214 thread_create_initial_thread();
218 /* thread_create_object ********************************************************
220 Create a Java thread object for the given thread data-structure,
221 initializes it and adds the thread to the threadgroup.
226 name .... thread name
227 group ... threadgroup
231 *******************************************************************************/
233 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
235 /* Create a java.lang.Thread Java object. */
237 java_handle_t* h = builtin_new(class_java_lang_Thread);
242 java_lang_Thread jlt(h);
244 // Set the Java object in the thread data-structure. This
245 // indicates that the thread is attached to the VM.
246 thread_set_object(t, jlt.get_handle());
248 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
250 h = builtin_new(class_java_lang_VMThread);
255 // Create and initialize a java.lang.VMThread object.
256 java_lang_VMThread jlvmt(h, jlt.get_handle(), t);
259 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
261 bool isdaemon = thread_is_daemon(t);
263 (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(),
264 name, NORM_PRIORITY, isdaemon);
266 if (exceptions_get_exception())
269 // Set the ThreadGroup in the Java thread object.
270 jlt.set_group(group);
272 /* Add thread to the threadgroup. */
275 LLNI_class_get(group, c);
277 methodinfo* m = class_resolveclassmethod(c,
279 utf_java_lang_Thread__V,
280 class_java_lang_ThreadGroup,
286 (void) vm_call_method(m, group, jlt.get_handle());
288 if (exceptions_get_exception())
291 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
293 /* Set the priority. java.lang.Thread.<init> requires it because
294 it sets the priority of the current thread to the parent's one
295 (which is the current thread in this case). */
296 jlt.set_priority(NORM_PRIORITY);
298 // Call: java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V
300 (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name);
302 if (exceptions_get_exception())
305 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
307 // Set the thread data-structure in the Java thread object.
308 jlt.set_vm_thread(t);
310 // Call: public Thread(Ljava/lang/String;)V
311 (void) vm_call_method(thread_method_init, jlt.get_handle(), name);
313 if (exceptions_get_exception())
317 # error unknown classpath configuration
324 /* thread_create_initial_threadgroups ******************************************
326 Create the initial threadgroups.
329 Create the main threadgroup only and set the system
330 threadgroup to the main threadgroup.
333 Create the system and main threadgroup.
336 This function is a no-op.
338 *******************************************************************************/
340 static void thread_create_initial_threadgroups(void)
342 #if defined(ENABLE_JAVASE)
343 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
345 /* Allocate and initialize the main thread group. */
347 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
349 if (threadgroup_main == NULL)
350 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
352 /* Use the same threadgroup for system as for main. */
354 threadgroup_system = threadgroup_main;
356 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
361 /* Allocate and initialize the system thread group. */
363 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
365 if (threadgroup_system == NULL)
366 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
368 /* Allocate and initialize the main thread group. */
370 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
372 if (threadgroup_main == NULL)
373 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
375 name = javastring_new(utf_main);
377 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
379 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
380 class_java_lang_ThreadGroup,
384 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
386 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
388 if (exceptions_get_exception())
389 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
392 # error unknown classpath configuration
398 /* thread_create_initial_thread ***********************************************
400 Create the initial thread: main
402 *******************************************************************************/
404 static void thread_create_initial_thread(void)
409 /* Get the main-thread (NOTE: The main thread is always the first
410 thread in the list). */
412 t = threadlist_first();
414 /* The thread name. */
416 name = javastring_new(utf_main);
418 #if defined(ENABLE_INTRP)
419 /* create interpreter stack */
422 MSET(intrp_main_stack, 0, u1, opt_stacksize);
423 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
427 /* Create the Java thread object. */
429 if (!thread_create_object(t, name, threadgroup_main))
430 vm_abort("thread_create_initial_thread: failed to create Java object");
432 /* Initialize the implementation specific bits. */
436 DEBUGTHREADS("starting (main)", t);
440 /* thread_new ******************************************************************
442 Allocates and initializes an internal thread data-structure and
443 adds it to the threads list.
445 *******************************************************************************/
447 static threadobject *thread_new(void)
452 /* Lock the thread lists */
456 index = threadlist_get_free_index();
458 /* Allocate a thread data structure. */
460 /* First, try to get one from the free-list. */
462 t = threadlist_free_first();
465 /* Remove from free list. */
467 threadlist_free_remove(t);
469 /* Equivalent of MZERO on the else path */
471 threads_impl_thread_clear(t);
474 #if defined(ENABLE_GC_BOEHM)
475 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
477 t = NEW(threadobject);
480 #if defined(ENABLE_STATISTICS)
482 size_threadobject += sizeof(threadobject);
487 MZERO(t, threadobject, 1);
489 #if defined(ENABLE_GC_CACAO)
490 /* Register reference to java.lang.Thread with the GC. */
491 /* FIXME is it ok to do this only once? */
493 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
494 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
497 /* Initialize the implementation-specific bits. */
499 threads_impl_thread_init(t);
502 /* Pre-compute the thinlock-word. */
507 t->thinlock = lock_pre_compute_thinlock(t->index);
509 t->state = THREAD_STATE_NEW;
511 #if defined(ENABLE_GC_CACAO)
512 t->flags |= THREAD_FLAG_IN_NATIVE;
515 /* Initialize the implementation-specific bits. */
517 threads_impl_thread_reuse(t);
519 /* Add the thread to the thread list. */
523 /* Unlock the thread lists. */
531 /* thread_free *****************************************************************
533 Remove the thread from the threads-list and free the internal
534 thread data structure. The thread index is added to the
535 thread-index free-list.
538 t ... thread data structure
540 *******************************************************************************/
542 void thread_free(threadobject *t)
544 /* Lock the thread lists. */
548 /* Remove the thread from the thread-list. */
550 threadlist_remove(t);
552 /* Add the thread index to the free list. */
554 threadlist_index_add(t->index);
556 /* Set the reference to the Java object to NULL. */
558 thread_set_object(t, NULL);
560 /* Add the thread data structure to the free list. */
562 threadlist_free_add(t);
564 /* Unlock the thread lists. */
570 /* threads_thread_start_internal ***********************************************
572 Start an internal thread in the JVM. No Java thread objects exists
576 name.......UTF-8 name of the thread
577 f..........function pointer to C function to start
579 *******************************************************************************/
581 bool threads_thread_start_internal(utf *name, functionptr f)
585 /* Enter the join-mutex, so if the main-thread is currently
586 waiting to join all threads, the number of non-daemon threads
589 threads_mutex_join_lock();
591 /* Create internal thread data-structure. */
595 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
597 /* The thread is flagged as (non-)daemon thread, we can leave the
600 threads_mutex_join_unlock();
602 /* Create the Java thread object. */
604 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
607 /* Start the thread. */
609 threads_impl_thread_start(t, f);
611 /* everything's ok */
617 /* threads_thread_start ********************************************************
619 Start a Java thread in the JVM. Only the java thread object exists
623 object.....the java thread object java.lang.Thread
625 *******************************************************************************/
627 void threads_thread_start(java_handle_t *object)
629 java_lang_Thread jlt(object);
631 /* Enter the join-mutex, so if the main-thread is currently
632 waiting to join all threads, the number of non-daemon threads
635 threads_mutex_join_lock();
637 /* Create internal thread data-structure. */
639 threadobject* t = thread_new();
641 /* this is a normal Java thread */
643 t->flags |= THREAD_FLAG_JAVA;
645 #if defined(ENABLE_JAVASE)
646 /* Is this a daemon thread? */
648 if (jlt.get_daemon() == true)
649 t->flags |= THREAD_FLAG_DAEMON;
652 /* The thread is flagged and (non-)daemon thread, we can leave the
655 threads_mutex_join_unlock();
657 /* Link the two objects together. */
659 thread_set_object(t, object);
661 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
663 /* Get the java.lang.VMThread object and do some sanity checks. */
664 java_lang_VMThread jlvmt(jlt.get_vmThread());
666 assert(jlvmt.get_handle() != NULL);
667 assert(jlvmt.get_vmdata() == NULL);
671 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
675 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
677 jlt.set_vm_thread(t);
680 # error unknown classpath configuration
683 /* Start the thread. Don't pass a function pointer (NULL) since
684 we want Thread.run()V here. */
686 threads_impl_thread_start(t, NULL);
691 * Attaches the current thread to the VM.
693 * @param vm_aargs Attach arguments.
694 * @param isdaemon true if the attached thread should be a daemon
697 * @return true on success, false otherwise.
699 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
705 java_handle_t *group;
707 /* If the current thread has already been attached, this operation
710 result = thread_current_is_attached();
715 /* Enter the join-mutex, so if the main-thread is currently
716 waiting to join all threads, the number of non-daemon threads
719 threads_mutex_join_lock();
721 /* Create internal thread data structure. */
725 /* Thread is a Java thread and running. */
727 t->flags = THREAD_FLAG_JAVA;
730 t->flags |= THREAD_FLAG_DAEMON;
732 /* Store the internal thread data-structure in the TSD. */
734 thread_set_current(t);
736 /* The thread is flagged and (non-)daemon thread, we can leave the
739 threads_mutex_join_unlock();
741 DEBUGTHREADS("attaching", t);
743 /* Get the thread name. */
745 if (vm_aargs != NULL) {
746 u = utf_new_char(vm_aargs->name);
752 name = javastring_new(u);
754 #if defined(ENABLE_JAVASE)
755 /* Get the threadgroup. */
757 if (vm_aargs != NULL)
758 group = (java_handle_t *) vm_aargs->group;
762 /* If no threadgroup was given, use the main threadgroup. */
765 group = threadgroup_main;
768 #if defined(ENABLE_INTRP)
769 /* create interpreter stack */
772 MSET(intrp_main_stack, 0, u1, opt_stacksize);
773 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
777 /* Create the Java thread object. */
779 if (!thread_create_object(t, name, group))
782 /* The thread is completely initialized. */
784 thread_set_state_runnable(t);
791 * Attaches the current external thread to the VM. This function is
792 * called by JNI's AttachCurrentThread.
794 * @param vm_aargs Attach arguments.
795 * @param isdaemon true if the attached thread should be a daemon
798 * @return true on success, false otherwise.
800 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
804 #if defined(ENABLE_GC_BOEHM)
805 struct GC_stack_base sb;
808 #if defined(ENABLE_GC_BOEHM)
809 /* Register the thread with Boehm-GC. This must happen before the
810 thread allocates any memory from the GC heap.*/
812 result = GC_get_stack_base(&sb);
814 if (result != GC_SUCCESS)
815 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
817 GC_register_my_thread(&sb);
820 result = thread_attach_current_thread(vm_aargs, isdaemon);
822 if (result == false) {
823 #if defined(ENABLE_GC_BOEHM)
824 /* Unregister the thread. */
826 GC_unregister_my_thread();
837 * Detaches the current external thread from the VM. This function is
838 * called by JNI's DetachCurrentThread.
840 * @return true on success, false otherwise.
842 bool thread_detach_current_external_thread(void)
846 result = thread_detach_current_thread();
851 #if defined(ENABLE_GC_BOEHM)
852 /* Unregister the thread with Boehm-GC. This must happen after
853 the thread allocates any memory from the GC heap. */
855 /* Don't detach the main thread. This is a workaround for
856 OpenJDK's java binary. */
857 if (thread_get_current()->index != 1)
858 GC_unregister_my_thread();
865 /* thread_fprint_name **********************************************************
867 Print the name of the given thread to the given stream.
870 t ........ thread data-structure
871 stream ... stream to print to
873 *******************************************************************************/
875 void thread_fprint_name(threadobject *t, FILE *stream)
877 if (thread_get_object(t) == NULL)
880 java_lang_Thread jlt(thread_get_object(t));
882 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
884 java_handle_t* name = jlt.get_name();
885 javastring_fprint(name, stream);
887 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
889 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
890 java_chararray_t *name;
892 /* FIXME This prints to stdout. */
893 utf_display_printable_ascii(utf_null);
896 # error unknown classpath configuration
901 /* thread_print_info ***********************************************************
903 Print information of the passed thread.
906 t ... thread data-structure.
908 *******************************************************************************/
910 void thread_print_info(threadobject *t)
912 java_lang_Thread jlt(thread_get_object(t));
914 /* Print as much as we can when we are in state NEW. */
916 if (jlt.get_handle() != NULL) {
917 /* Print thread name. */
920 thread_fprint_name(t, stdout);
926 if (thread_is_daemon(t))
929 if (jlt.get_handle() != NULL) {
930 printf(" prio=%d", jlt.get_priority());
933 #if SIZEOF_VOID_P == 8
934 printf(" t=0x%016lx tid=0x%016lx (%ld)",
935 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
937 printf(" t=0x%08x tid=0x%08x (%d)",
938 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
941 printf(" index=%d", t->index);
943 /* Print thread state. */
945 int state = cacaothread_get_state(t);
948 case THREAD_STATE_NEW:
951 case THREAD_STATE_RUNNABLE:
954 case THREAD_STATE_BLOCKED:
957 case THREAD_STATE_WAITING:
960 case THREAD_STATE_TIMED_WAITING:
961 printf(" waiting on condition");
963 case THREAD_STATE_TERMINATED:
964 printf(" terminated");
967 vm_abort("thread_print_info: unknown thread state %d", state);
972 /* threads_get_current_tid *****************************************************
974 Return the tid of the current thread.
979 *******************************************************************************/
981 intptr_t threads_get_current_tid(void)
983 threadobject *thread;
985 thread = THREADOBJECT;
987 /* this may happen during bootstrap */
992 return (intptr_t) thread->tid;
996 /* thread_set_state_runnable ***************************************************
998 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1000 NOTE: If the thread has already terminated, don't set the state.
1001 This is important for threads_detach_thread.
1003 *******************************************************************************/
1005 void thread_set_state_runnable(threadobject *t)
1007 /* Set the state inside a lock. */
1011 if (t->state != THREAD_STATE_TERMINATED) {
1012 t->state = THREAD_STATE_RUNNABLE;
1014 DEBUGTHREADS("is RUNNABLE", t);
1017 threadlist_unlock();
1021 /* thread_set_state_waiting ****************************************************
1023 Set the current state of the given thread to THREAD_STATE_WAITING.
1025 NOTE: If the thread has already terminated, don't set the state.
1026 This is important for threads_detach_thread.
1028 *******************************************************************************/
1030 void thread_set_state_waiting(threadobject *t)
1032 /* Set the state inside a lock. */
1036 if (t->state != THREAD_STATE_TERMINATED) {
1037 t->state = THREAD_STATE_WAITING;
1039 DEBUGTHREADS("is WAITING", t);
1042 threadlist_unlock();
1046 /* thread_set_state_timed_waiting **********************************************
1048 Set the current state of the given thread to
1049 THREAD_STATE_TIMED_WAITING.
1051 NOTE: If the thread has already terminated, don't set the state.
1052 This is important for threads_detach_thread.
1054 *******************************************************************************/
1056 void thread_set_state_timed_waiting(threadobject *t)
1058 /* Set the state inside a lock. */
1062 if (t->state != THREAD_STATE_TERMINATED) {
1063 t->state = THREAD_STATE_TIMED_WAITING;
1065 DEBUGTHREADS("is TIMED_WAITING", t);
1068 threadlist_unlock();
1072 /* thread_set_state_terminated *************************************************
1074 Set the current state of the given thread to
1075 THREAD_STATE_TERMINATED.
1077 *******************************************************************************/
1079 void thread_set_state_terminated(threadobject *t)
1081 /* Set the state inside a lock. */
1085 t->state = THREAD_STATE_TERMINATED;
1087 DEBUGTHREADS("is TERMINATED", t);
1089 threadlist_unlock();
1093 /* thread_get_thread **********************************************************
1095 Return the thread data structure of the given Java thread object.
1098 h ... java.lang.{VM}Thread object
1103 *******************************************************************************/
1105 threadobject *thread_get_thread(java_handle_t *h)
1107 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1109 java_lang_VMThread jlvmt(h);
1110 threadobject* t = jlvmt.get_vmdata();
1112 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1114 /* XXX This is just a quick hack. */
1120 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1121 LLNI_equals(t->object, h, equal);
1127 threadlist_unlock();
1129 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1131 log_println("threads_get_thread: IMPLEMENT ME!");
1132 threadobject* t = NULL;
1135 # error unknown classpath configuration
1142 /* threads_thread_is_alive *****************************************************
1144 Returns if the give thread is alive.
1146 *******************************************************************************/
1148 bool threads_thread_is_alive(threadobject *t)
1152 state = cacaothread_get_state(t);
1155 case THREAD_STATE_NEW:
1156 case THREAD_STATE_TERMINATED:
1159 case THREAD_STATE_RUNNABLE:
1160 case THREAD_STATE_BLOCKED:
1161 case THREAD_STATE_WAITING:
1162 case THREAD_STATE_TIMED_WAITING:
1166 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1169 /* keep compiler happy */
1175 /* threads_dump ****************************************************************
1177 Dumps info for all threads running in the JVM. This function is
1178 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1180 *******************************************************************************/
1182 void threads_dump(void)
1186 /* XXX we should stop the world here */
1188 /* Lock the thread lists. */
1192 printf("Full thread dump CACAO "VERSION":\n");
1194 /* iterate over all started threads */
1196 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1197 /* ignore threads which are in state NEW */
1198 if (t->state == THREAD_STATE_NEW)
1201 #if defined(ENABLE_GC_CACAO)
1202 /* Suspend the thread. */
1203 /* XXX Is the suspend reason correct? */
1205 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1206 vm_abort("threads_dump: threads_suspend_thread failed");
1209 /* Print thread info. */
1212 thread_print_info(t);
1215 /* Print trace of thread. */
1217 stacktrace_print_of_thread(t);
1219 #if defined(ENABLE_GC_CACAO)
1220 /* Resume the thread. */
1222 if (threads_resume_thread(t) == false)
1223 vm_abort("threads_dump: threads_resume_thread failed");
1227 /* Unlock the thread lists. */
1229 threadlist_unlock();
1236 * These are local overrides for various environment variables in Emacs.
1237 * Please do not remove this and leave it at the end of the file, where
1238 * Emacs will automagically detect them.
1239 * ---------------------------------------------------------------------
1242 * indent-tabs-mode: t
1246 * vim:noexpandtab:sw=4:ts=4: