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.hpp"
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"
67 /* global variables ***********************************************************/
69 static methodinfo *thread_method_init;
70 static java_handle_t *threadgroup_system;
71 static java_handle_t *threadgroup_main;
73 #if defined(__LINUX__)
74 /* XXX Remove for exact-GC. */
75 bool threads_pthreads_implementation_nptl;
79 /* static functions ***********************************************************/
81 static void thread_create_initial_threadgroups(void);
82 static void thread_create_initial_thread(void);
83 static threadobject *thread_new(void);
86 /* threads_preinit *************************************************************
88 Do some early initialization of stuff required.
90 *******************************************************************************/
92 void threads_preinit(void)
94 threadobject *mainthread;
95 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
100 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
102 #if defined(__LINUX__)
103 /* XXX Remove for exact-GC. */
105 /* On Linux we need to check the pthread implementation. */
107 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
108 /* If the glibc is a pre-2.3.2 version, we fall back to
111 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
112 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
114 /* Some systems return as length 0 (maybe cross-compilation
115 related). In this case we also fall back to linuxthreads. */
118 pathbuf = MNEW(char, len);
120 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
122 if (strstr(pathbuf, "NPTL") != NULL)
123 threads_pthreads_implementation_nptl = true;
125 threads_pthreads_implementation_nptl = false;
128 threads_pthreads_implementation_nptl = false;
130 threads_pthreads_implementation_nptl = false;
134 /* Initialize the threads implementation (sets the thinlock on the
137 threads_impl_preinit();
139 /* Create internal thread data-structure for the main thread. */
141 mainthread = thread_new();
143 /* The main thread should always have index 1. */
145 if (mainthread->index != 1)
146 vm_abort("threads_preinit: main thread index not 1: %d != 1",
149 /* thread is a Java thread and running */
151 mainthread->flags |= THREAD_FLAG_JAVA;
152 mainthread->state = THREAD_STATE_RUNNABLE;
154 /* Store the internal thread data-structure in the TSD. */
156 thread_set_current(mainthread);
160 /* threads_init ****************************************************************
162 Initialize the main thread.
164 *******************************************************************************/
166 void threads_init(void)
168 TRACESUBSYSTEMINITIALIZATION("threads_init");
170 /* Create the system and main thread groups. */
172 thread_create_initial_threadgroups();
174 /* Cache the java.lang.Thread initialization method. */
176 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
179 class_resolveclassmethod(class_java_lang_Thread,
181 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
182 class_java_lang_Thread,
185 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
188 class_resolveclassmethod(class_java_lang_Thread,
190 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
191 class_java_lang_Thread,
194 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
197 class_resolveclassmethod(class_java_lang_Thread,
199 utf_java_lang_String__void,
200 class_java_lang_Thread,
204 # error unknown classpath configuration
207 if (thread_method_init == NULL)
208 vm_abort("threads_init: failed to resolve thread init method");
210 thread_create_initial_thread();
214 /* thread_create_object ********************************************************
216 Create a Java thread object for the given thread data-structure,
217 initializes it and adds the thread to the threadgroup.
222 name .... thread name
223 group ... threadgroup
227 *******************************************************************************/
229 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
231 /* Create a java.lang.Thread Java object. */
233 java_handle_t* h = builtin_new(class_java_lang_Thread);
238 java_lang_Thread jlt(h);
240 // Set the Java object in the thread data-structure. This
241 // indicates that the thread is attached to the VM.
242 thread_set_object(t, jlt.get_handle());
244 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
246 h = builtin_new(class_java_lang_VMThread);
251 // Create and initialize a java.lang.VMThread object.
252 java_lang_VMThread jlvmt(h, jlt.get_handle(), t);
255 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
257 bool isdaemon = thread_is_daemon(t);
259 (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(),
260 name, NORM_PRIORITY, isdaemon);
262 if (exceptions_get_exception())
265 // Set the ThreadGroup in the Java thread object.
266 jlt.set_group(group);
268 /* Add thread to the threadgroup. */
271 LLNI_class_get(group, c);
273 methodinfo* m = class_resolveclassmethod(c,
275 utf_java_lang_Thread__V,
276 class_java_lang_ThreadGroup,
282 (void) vm_call_method(m, group, jlt.get_handle());
284 if (exceptions_get_exception())
287 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
289 /* Set the priority. java.lang.Thread.<init> requires it because
290 it sets the priority of the current thread to the parent's one
291 (which is the current thread in this case). */
292 jlt.set_priority(NORM_PRIORITY);
294 // Call: java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V
296 (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name);
298 if (exceptions_get_exception())
301 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
303 // Set the thread data-structure in the Java thread object.
304 jlt.set_vm_thread(t);
306 // Call: public Thread(Ljava/lang/String;)V
307 (void) vm_call_method(thread_method_init, jlt.get_handle(), name);
309 if (exceptions_get_exception())
313 # error unknown classpath configuration
320 /* thread_create_initial_threadgroups ******************************************
322 Create the initial threadgroups.
325 Create the main threadgroup only and set the system
326 threadgroup to the main threadgroup.
329 Create the system and main threadgroup.
332 This function is a no-op.
334 *******************************************************************************/
336 static void thread_create_initial_threadgroups(void)
338 #if defined(ENABLE_JAVASE)
339 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
341 /* Allocate and initialize the main thread group. */
343 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
345 if (threadgroup_main == NULL)
346 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
348 /* Use the same threadgroup for system as for main. */
350 threadgroup_system = threadgroup_main;
352 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
357 /* Allocate and initialize the system thread group. */
359 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
361 if (threadgroup_system == NULL)
362 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
364 /* Allocate and initialize the main thread group. */
366 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
368 if (threadgroup_main == NULL)
369 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
371 name = javastring_new(utf_main);
373 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
375 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
376 class_java_lang_ThreadGroup,
380 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
382 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
384 if (exceptions_get_exception())
385 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
388 # error unknown classpath configuration
394 /* thread_create_initial_thread ***********************************************
396 Create the initial thread: main
398 *******************************************************************************/
400 static void thread_create_initial_thread(void)
405 /* Get the main-thread (NOTE: The main thread is always the first
406 thread in the list). */
408 t = threadlist_first();
410 /* The thread name. */
412 name = javastring_new(utf_main);
414 #if defined(ENABLE_INTRP)
415 /* create interpreter stack */
418 MSET(intrp_main_stack, 0, u1, opt_stacksize);
419 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
423 /* Create the Java thread object. */
425 if (!thread_create_object(t, name, threadgroup_main))
426 vm_abort("thread_create_initial_thread: failed to create Java object");
428 /* Initialize the implementation specific bits. */
432 DEBUGTHREADS("starting (main)", t);
436 /* thread_new ******************************************************************
438 Allocates and initializes an internal thread data-structure and
439 adds it to the threads list.
441 *******************************************************************************/
443 static threadobject *thread_new(void)
448 /* Lock the thread lists */
452 index = threadlist_get_free_index();
454 /* Allocate a thread data structure. */
456 /* First, try to get one from the free-list. */
458 t = threadlist_free_first();
461 /* Remove from free list. */
463 threadlist_free_remove(t);
465 /* Equivalent of MZERO on the else path */
467 threads_impl_thread_clear(t);
470 #if defined(ENABLE_GC_BOEHM)
471 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
473 t = NEW(threadobject);
476 #if defined(ENABLE_STATISTICS)
478 size_threadobject += sizeof(threadobject);
483 MZERO(t, threadobject, 1);
485 // Initialize the mutex and the condition.
486 t->flc_lock = new Mutex();
487 t->flc_cond = new Condition();
489 t->waitmutex = new Mutex();
490 t->waitcond = new Condition();
492 t->suspendmutex = new Mutex();
493 t->suspendcond = new Condition();
495 #if defined(ENABLE_TLH)
499 #if defined(ENABLE_GC_CACAO)
500 /* Register reference to java.lang.Thread with the GC. */
501 /* FIXME is it ok to do this only once? */
503 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
504 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
507 t->_dumpmemory = new DumpMemory();
510 /* Pre-compute the thinlock-word. */
515 t->thinlock = lock_pre_compute_thinlock(t->index);
517 t->state = THREAD_STATE_NEW;
519 #if defined(ENABLE_GC_CACAO)
520 t->flags |= THREAD_FLAG_IN_NATIVE;
523 /* Initialize the implementation-specific bits. */
525 threads_impl_thread_reuse(t);
527 /* Add the thread to the thread list. */
531 /* Unlock the thread lists. */
539 /* thread_free *****************************************************************
541 Remove the thread from the threads-list and free the internal
542 thread data structure. The thread index is added to the
543 thread-index free-list.
546 t ... thread data structure
548 *******************************************************************************/
550 void thread_free(threadobject *t)
552 /* Lock the thread lists. */
556 /* Remove the thread from the thread-list. */
558 threadlist_remove(t);
560 /* Add the thread index to the free list. */
562 threadlist_index_add(t->index);
564 /* Set the reference to the Java object to NULL. */
566 thread_set_object(t, NULL);
568 /* Add the thread data structure to the free list. */
570 threadlist_free_add(t);
572 /* Unlock the thread lists. */
578 /* threads_thread_start_internal ***********************************************
580 Start an internal thread in the JVM. No Java thread objects exists
584 name.......UTF-8 name of the thread
585 f..........function pointer to C function to start
587 *******************************************************************************/
589 bool threads_thread_start_internal(utf *name, functionptr f)
593 /* Enter the join-mutex, so if the main-thread is currently
594 waiting to join all threads, the number of non-daemon threads
597 threads_mutex_join_lock();
599 /* Create internal thread data-structure. */
603 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
605 /* The thread is flagged as (non-)daemon thread, we can leave the
608 threads_mutex_join_unlock();
610 /* Create the Java thread object. */
612 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
615 /* Start the thread. */
617 threads_impl_thread_start(t, f);
619 /* everything's ok */
625 /* threads_thread_start ********************************************************
627 Start a Java thread in the JVM. Only the java thread object exists
631 object.....the java thread object java.lang.Thread
633 *******************************************************************************/
635 void threads_thread_start(java_handle_t *object)
637 java_lang_Thread jlt(object);
639 /* Enter the join-mutex, so if the main-thread is currently
640 waiting to join all threads, the number of non-daemon threads
643 threads_mutex_join_lock();
645 /* Create internal thread data-structure. */
647 threadobject* t = thread_new();
649 /* this is a normal Java thread */
651 t->flags |= THREAD_FLAG_JAVA;
653 #if defined(ENABLE_JAVASE)
654 /* Is this a daemon thread? */
656 if (jlt.get_daemon() == true)
657 t->flags |= THREAD_FLAG_DAEMON;
660 /* The thread is flagged and (non-)daemon thread, we can leave the
663 threads_mutex_join_unlock();
665 /* Link the two objects together. */
667 thread_set_object(t, object);
669 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
671 /* Get the java.lang.VMThread object and do some sanity checks. */
672 java_lang_VMThread jlvmt(jlt.get_vmThread());
674 assert(jlvmt.get_handle() != NULL);
675 assert(jlvmt.get_vmdata() == NULL);
679 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
683 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
685 jlt.set_vm_thread(t);
688 # error unknown classpath configuration
691 /* Start the thread. Don't pass a function pointer (NULL) since
692 we want Thread.run()V here. */
694 threads_impl_thread_start(t, NULL);
699 * Attaches the current thread to the VM.
701 * @param vm_aargs Attach arguments.
702 * @param isdaemon true if the attached thread should be a daemon
705 * @return true on success, false otherwise.
707 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
713 java_handle_t *group;
715 /* If the current thread has already been attached, this operation
718 result = thread_current_is_attached();
723 /* Enter the join-mutex, so if the main-thread is currently
724 waiting to join all threads, the number of non-daemon threads
727 threads_mutex_join_lock();
729 /* Create internal thread data structure. */
733 /* Thread is a Java thread and running. */
735 t->flags = THREAD_FLAG_JAVA;
738 t->flags |= THREAD_FLAG_DAEMON;
740 /* Store the internal thread data-structure in the TSD. */
742 thread_set_current(t);
744 /* The thread is flagged and (non-)daemon thread, we can leave the
747 threads_mutex_join_unlock();
749 DEBUGTHREADS("attaching", t);
751 /* Get the thread name. */
753 if (vm_aargs != NULL) {
754 u = utf_new_char(vm_aargs->name);
760 name = javastring_new(u);
762 #if defined(ENABLE_JAVASE)
763 /* Get the threadgroup. */
765 if (vm_aargs != NULL)
766 group = (java_handle_t *) vm_aargs->group;
770 /* If no threadgroup was given, use the main threadgroup. */
773 group = threadgroup_main;
776 #if defined(ENABLE_INTRP)
777 /* create interpreter stack */
780 MSET(intrp_main_stack, 0, u1, opt_stacksize);
781 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
785 /* Create the Java thread object. */
787 if (!thread_create_object(t, name, group))
790 /* The thread is completely initialized. */
792 thread_set_state_runnable(t);
799 * Attaches the current external thread to the VM. This function is
800 * called by JNI's AttachCurrentThread.
802 * @param vm_aargs Attach arguments.
803 * @param isdaemon true if the attached thread should be a daemon
806 * @return true on success, false otherwise.
808 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
812 #if defined(ENABLE_GC_BOEHM)
813 struct GC_stack_base sb;
816 #if defined(ENABLE_GC_BOEHM)
817 /* Register the thread with Boehm-GC. This must happen before the
818 thread allocates any memory from the GC heap.*/
820 result = GC_get_stack_base(&sb);
822 if (result != GC_SUCCESS)
823 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
825 GC_register_my_thread(&sb);
828 result = thread_attach_current_thread(vm_aargs, isdaemon);
830 if (result == false) {
831 #if defined(ENABLE_GC_BOEHM)
832 /* Unregister the thread. */
834 GC_unregister_my_thread();
845 * Detaches the current external thread from the VM. This function is
846 * called by JNI's DetachCurrentThread.
848 * @return true on success, false otherwise.
850 bool thread_detach_current_external_thread(void)
854 result = thread_detach_current_thread();
859 #if defined(ENABLE_GC_BOEHM)
860 /* Unregister the thread with Boehm-GC. This must happen after
861 the thread allocates any memory from the GC heap. */
863 /* Don't detach the main thread. This is a workaround for
864 OpenJDK's java binary. */
865 if (thread_get_current()->index != 1)
866 GC_unregister_my_thread();
873 /* thread_fprint_name **********************************************************
875 Print the name of the given thread to the given stream.
878 t ........ thread data-structure
879 stream ... stream to print to
881 *******************************************************************************/
883 void thread_fprint_name(threadobject *t, FILE *stream)
885 if (thread_get_object(t) == NULL)
888 java_lang_Thread jlt(thread_get_object(t));
890 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
892 java_handle_t* name = jlt.get_name();
893 javastring_fprint(name, stream);
895 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
897 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
898 java_chararray_t *name;
900 /* FIXME This prints to stdout. */
901 utf_display_printable_ascii(utf_null);
904 # error unknown classpath configuration
909 /* thread_print_info ***********************************************************
911 Print information of the passed thread.
914 t ... thread data-structure.
916 *******************************************************************************/
918 void thread_print_info(threadobject *t)
920 java_lang_Thread jlt(thread_get_object(t));
922 /* Print as much as we can when we are in state NEW. */
924 if (jlt.get_handle() != NULL) {
925 /* Print thread name. */
928 thread_fprint_name(t, stdout);
934 if (thread_is_daemon(t))
937 if (jlt.get_handle() != NULL) {
938 printf(" prio=%d", jlt.get_priority());
941 #if SIZEOF_VOID_P == 8
942 printf(" t=0x%016lx tid=0x%016lx (%ld)",
943 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
945 printf(" t=0x%08x tid=0x%08x (%d)",
946 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
949 printf(" index=%d", t->index);
951 /* Print thread state. */
953 int state = cacaothread_get_state(t);
956 case THREAD_STATE_NEW:
959 case THREAD_STATE_RUNNABLE:
962 case THREAD_STATE_BLOCKED:
965 case THREAD_STATE_WAITING:
968 case THREAD_STATE_TIMED_WAITING:
969 printf(" waiting on condition");
971 case THREAD_STATE_TERMINATED:
972 printf(" terminated");
975 vm_abort("thread_print_info: unknown thread state %d", state);
980 /* threads_get_current_tid *****************************************************
982 Return the tid of the current thread.
987 *******************************************************************************/
989 intptr_t threads_get_current_tid(void)
991 threadobject *thread;
993 thread = THREADOBJECT;
995 /* this may happen during bootstrap */
1000 return (intptr_t) thread->tid;
1004 /* thread_set_state_runnable ***************************************************
1006 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1008 NOTE: If the thread has already terminated, don't set the state.
1009 This is important for threads_detach_thread.
1011 *******************************************************************************/
1013 void thread_set_state_runnable(threadobject *t)
1015 /* Set the state inside a lock. */
1019 if (t->state != THREAD_STATE_TERMINATED) {
1020 t->state = THREAD_STATE_RUNNABLE;
1022 DEBUGTHREADS("is RUNNABLE", t);
1025 threadlist_unlock();
1029 /* thread_set_state_waiting ****************************************************
1031 Set the current state of the given thread to THREAD_STATE_WAITING.
1033 NOTE: If the thread has already terminated, don't set the state.
1034 This is important for threads_detach_thread.
1036 *******************************************************************************/
1038 void thread_set_state_waiting(threadobject *t)
1040 /* Set the state inside a lock. */
1044 if (t->state != THREAD_STATE_TERMINATED) {
1045 t->state = THREAD_STATE_WAITING;
1047 DEBUGTHREADS("is WAITING", t);
1050 threadlist_unlock();
1054 /* thread_set_state_timed_waiting **********************************************
1056 Set the current state of the given thread to
1057 THREAD_STATE_TIMED_WAITING.
1059 NOTE: If the thread has already terminated, don't set the state.
1060 This is important for threads_detach_thread.
1062 *******************************************************************************/
1064 void thread_set_state_timed_waiting(threadobject *t)
1066 /* Set the state inside a lock. */
1070 if (t->state != THREAD_STATE_TERMINATED) {
1071 t->state = THREAD_STATE_TIMED_WAITING;
1073 DEBUGTHREADS("is TIMED_WAITING", t);
1076 threadlist_unlock();
1080 /* thread_set_state_terminated *************************************************
1082 Set the current state of the given thread to
1083 THREAD_STATE_TERMINATED.
1085 *******************************************************************************/
1087 void thread_set_state_terminated(threadobject *t)
1089 /* Set the state inside a lock. */
1093 t->state = THREAD_STATE_TERMINATED;
1095 DEBUGTHREADS("is TERMINATED", t);
1097 threadlist_unlock();
1101 /* thread_get_thread **********************************************************
1103 Return the thread data structure of the given Java thread object.
1106 h ... java.lang.{VM}Thread object
1111 *******************************************************************************/
1113 threadobject *thread_get_thread(java_handle_t *h)
1115 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1117 java_lang_VMThread jlvmt(h);
1118 threadobject* t = jlvmt.get_vmdata();
1120 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1122 /* XXX This is just a quick hack. */
1128 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1129 LLNI_equals(t->object, h, equal);
1135 threadlist_unlock();
1137 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1139 log_println("threads_get_thread: IMPLEMENT ME!");
1140 threadobject* t = NULL;
1143 # error unknown classpath configuration
1150 /* threads_thread_is_alive *****************************************************
1152 Returns if the give thread is alive.
1154 *******************************************************************************/
1156 bool threads_thread_is_alive(threadobject *t)
1160 state = cacaothread_get_state(t);
1163 case THREAD_STATE_NEW:
1164 case THREAD_STATE_TERMINATED:
1167 case THREAD_STATE_RUNNABLE:
1168 case THREAD_STATE_BLOCKED:
1169 case THREAD_STATE_WAITING:
1170 case THREAD_STATE_TIMED_WAITING:
1174 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1177 /* keep compiler happy */
1183 /* threads_dump ****************************************************************
1185 Dumps info for all threads running in the JVM. This function is
1186 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1188 *******************************************************************************/
1190 void threads_dump(void)
1194 /* XXX we should stop the world here */
1196 /* Lock the thread lists. */
1200 printf("Full thread dump CACAO "VERSION":\n");
1202 /* iterate over all started threads */
1204 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1205 /* ignore threads which are in state NEW */
1206 if (t->state == THREAD_STATE_NEW)
1209 #if defined(ENABLE_GC_CACAO)
1210 /* Suspend the thread. */
1211 /* XXX Is the suspend reason correct? */
1213 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1214 vm_abort("threads_dump: threads_suspend_thread failed");
1217 /* Print thread info. */
1220 thread_print_info(t);
1223 /* Print trace of thread. */
1225 stacktrace_print_of_thread(t);
1227 #if defined(ENABLE_GC_CACAO)
1228 /* Resume the thread. */
1230 if (threads_resume_thread(t) == false)
1231 vm_abort("threads_dump: threads_resume_thread failed");
1235 /* Unlock the thread lists. */
1237 threadlist_unlock();
1242 * These are local overrides for various environment variables in Emacs.
1243 * Please do not remove this and leave it at the end of the file, where
1244 * Emacs will automagically detect them.
1245 * ---------------------------------------------------------------------
1248 * indent-tabs-mode: t
1252 * vim:noexpandtab:sw=4:ts=4: