1 /* src/threads/thread.c - 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 "native/include/java_lang_Object.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Thread.h"
50 #if defined(ENABLE_JAVASE)
51 # include "native/include/java_lang_ThreadGroup.h"
54 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
55 # include "native/include/java_lang_VMThread.h"
58 #include "threads/lock-common.h"
59 #include "threads/threadlist.h"
60 #include "threads/thread.h"
62 #include "vm/builtin.h"
63 #include "vm/exceptions.h"
64 #include "vm/stringlocal.h"
67 #include "vm/jit/stacktrace.h"
69 #include "vmcore/class.h"
70 #include "vmcore/method.h"
71 #include "vmcore/options.h"
73 #if defined(ENABLE_STATISTICS)
74 # include "vmcore/statistics.h"
77 #include "vmcore/utf8.h"
80 /* global variables ***********************************************************/
82 static methodinfo *thread_method_init;
83 static java_handle_t *threadgroup_system;
84 static java_handle_t *threadgroup_main;
86 #if defined(__LINUX__)
87 /* XXX Remove for exact-GC. */
88 bool threads_pthreads_implementation_nptl;
92 /* static functions ***********************************************************/
94 static void thread_create_initial_threadgroups(void);
95 static void thread_create_initial_thread(void);
96 static threadobject *thread_new(void);
99 /* threads_preinit *************************************************************
101 Do some early initialization of stuff required.
103 *******************************************************************************/
105 void threads_preinit(void)
107 threadobject *mainthread;
108 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
113 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
115 #if defined(__LINUX__)
116 /* XXX Remove for exact-GC. */
118 /* On Linux we need to check the pthread implementation. */
120 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
121 /* If the glibc is a pre-2.3.2 version, we fall back to
124 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
125 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
127 /* Some systems return as length 0 (maybe cross-compilation
128 related). In this case we also fall back to linuxthreads. */
131 pathbuf = MNEW(char, len);
133 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
135 if (strstr(pathbuf, "NPTL") != NULL)
136 threads_pthreads_implementation_nptl = true;
138 threads_pthreads_implementation_nptl = false;
141 threads_pthreads_implementation_nptl = false;
143 threads_pthreads_implementation_nptl = false;
147 /* Initialize the threads implementation (sets the thinlock on the
150 threads_impl_preinit();
152 /* Create internal thread data-structure for the main thread. */
154 mainthread = thread_new();
156 /* The main thread should always have index 1. */
158 if (mainthread->index != 1)
159 vm_abort("threads_preinit: main thread index not 1: %d != 1",
162 /* thread is a Java thread and running */
164 mainthread->flags |= THREAD_FLAG_JAVA;
165 mainthread->state = THREAD_STATE_RUNNABLE;
167 /* Store the internal thread data-structure in the TSD. */
169 thread_set_current(mainthread);
173 /* threads_init ****************************************************************
175 Initialize the main thread.
177 *******************************************************************************/
179 void threads_init(void)
181 TRACESUBSYSTEMINITIALIZATION("threads_init");
183 /* Create the system and main thread groups. */
185 thread_create_initial_threadgroups();
187 /* Cache the java.lang.Thread initialization method. */
189 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
192 class_resolveclassmethod(class_java_lang_Thread,
194 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
195 class_java_lang_Thread,
198 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
201 class_resolveclassmethod(class_java_lang_Thread,
203 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
204 class_java_lang_Thread,
207 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
210 class_resolveclassmethod(class_java_lang_Thread,
212 utf_java_lang_String__void,
213 class_java_lang_Thread,
217 # error unknown classpath configuration
220 if (thread_method_init == NULL)
221 vm_abort("threads_init: failed to resolve thread init method");
223 thread_create_initial_thread();
227 /* thread_create_object ********************************************************
229 Create a Java thread object for the given thread data-structure,
230 initializes it and adds the thread to the threadgroup.
235 name .... thread name
236 group ... threadgroup
240 *******************************************************************************/
242 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
245 java_lang_Thread *to;
247 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
248 java_lang_VMThread *vmto;
254 /* Create a java.lang.Thread Java object. */
256 o = builtin_new(class_java_lang_Thread);
261 to = (java_lang_Thread *) o;
263 /* Set the Java object in the thread data-structure. This
264 indicates that the thread is attached to the VM. */
266 thread_set_object(t, (java_handle_t *) to);
268 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
270 /* Create a java.lang.VMThread Java object. */
272 vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
277 /* Set the Java thread object in the Java VM-thread object. */
279 LLNI_field_set_ref(vmto, thread, to);
281 /* Set the thread data-structure in the Java VM-thread object. */
283 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
286 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
288 isdaemon = thread_is_daemon(t);
290 (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
293 if (exceptions_get_exception())
296 /* Set the threadgroup in the Java thread object. */
298 LLNI_field_set_ref(to, group, (java_lang_ThreadGroup *) group);
300 /* Add thread to the threadgroup. */
302 LLNI_class_get(group, c);
304 m = class_resolveclassmethod(c,
306 utf_java_lang_Thread__V,
307 class_java_lang_ThreadGroup,
313 (void) vm_call_method(m, group, to);
315 if (exceptions_get_exception())
318 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
320 /* OpenJDK's java.lang.Thread does not have a VMThread field in
321 the class. Nothing to do here. */
323 /* Set the priority. java.lang.Thread.<init> requires it because
324 it sets the priority of the current thread to the parent's one
325 (which is the current thread in this case). */
327 LLNI_field_set_val(to, priority, NORM_PRIORITY);
330 java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
332 (void) vm_call_method(thread_method_init, o, group, name);
334 if (exceptions_get_exception())
337 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
339 /* Set the thread data-structure in the Java thread object. */
341 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
343 /* Call: public Thread(Ljava/lang/String;)V */
345 (void) vm_call_method(thread_method_init, o, name);
347 if (exceptions_get_exception())
351 # error unknown classpath configuration
358 /* thread_create_initial_threadgroups ******************************************
360 Create the initial threadgroups.
363 Create the main threadgroup only and set the system
364 threadgroup to the main threadgroup.
367 Create the system and main threadgroup.
370 This function is a no-op.
372 *******************************************************************************/
374 static void thread_create_initial_threadgroups(void)
376 #if defined(ENABLE_JAVASE)
377 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
379 /* Allocate and initialize the main thread group. */
381 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
383 if (threadgroup_main == NULL)
384 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
386 /* Use the same threadgroup for system as for main. */
388 threadgroup_system = threadgroup_main;
390 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
395 /* Allocate and initialize the system thread group. */
397 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
399 if (threadgroup_system == NULL)
400 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
402 /* Allocate and initialize the main thread group. */
404 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
406 if (threadgroup_main == NULL)
407 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
409 name = javastring_new(utf_main);
411 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
413 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
414 class_java_lang_ThreadGroup,
418 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
420 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
422 if (exceptions_get_exception())
423 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
426 # error unknown classpath configuration
432 /* thread_create_initial_thread ***********************************************
434 Create the initial thread: main
436 *******************************************************************************/
438 static void thread_create_initial_thread(void)
443 /* Get the main-thread (NOTE: The main thread is always the first
444 thread in the list). */
446 t = threadlist_first();
448 /* The thread name. */
450 name = javastring_new(utf_main);
452 #if defined(ENABLE_INTRP)
453 /* create interpreter stack */
456 MSET(intrp_main_stack, 0, u1, opt_stacksize);
457 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
461 /* Create the Java thread object. */
463 if (!thread_create_object(t, name, threadgroup_main))
464 vm_abort("thread_create_initial_thread: failed to create Java object");
466 /* Initialize the implementation specific bits. */
470 DEBUGTHREADS("starting (main)", t);
474 /* thread_new ******************************************************************
476 Allocates and initializes an internal thread data-structure and
477 adds it to the threads list.
479 *******************************************************************************/
481 static threadobject *thread_new(void)
486 /* Lock the thread lists */
490 index = threadlist_get_free_index();
492 /* Allocate a thread data structure. */
494 /* First, try to get one from the free-list. */
496 t = threadlist_free_first();
499 /* Remove from free list. */
501 threadlist_free_remove(t);
503 /* Equivalent of MZERO on the else path */
505 threads_impl_thread_clear(t);
508 #if defined(ENABLE_GC_BOEHM)
509 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
511 t = NEW(threadobject);
514 #if defined(ENABLE_STATISTICS)
516 size_threadobject += sizeof(threadobject);
521 MZERO(t, threadobject, 1);
523 #if defined(ENABLE_GC_CACAO)
524 /* Register reference to java.lang.Thread with the GC. */
525 /* FIXME is it ok to do this only once? */
527 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
528 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
531 /* Initialize the implementation-specific bits. */
533 threads_impl_thread_init(t);
536 /* Pre-compute the thinlock-word. */
541 t->thinlock = lock_pre_compute_thinlock(t->index);
543 t->state = THREAD_STATE_NEW;
545 #if defined(ENABLE_GC_CACAO)
546 t->flags |= THREAD_FLAG_IN_NATIVE;
549 /* Initialize the implementation-specific bits. */
551 threads_impl_thread_reuse(t);
553 /* Add the thread to the thread list. */
557 /* Unlock the thread lists. */
565 /* thread_free *****************************************************************
567 Remove the thread from the threads-list and free the internal
568 thread data structure. The thread index is added to the
569 thread-index free-list.
572 t ... thread data structure
574 *******************************************************************************/
576 void thread_free(threadobject *t)
578 /* Lock the thread lists. */
582 /* Remove the thread from the thread-list. */
584 threadlist_remove(t);
586 /* Add the thread index to the free list. */
588 threadlist_index_add(t->index);
590 /* Set the reference to the Java object to NULL. */
592 thread_set_object(t, NULL);
594 /* Add the thread data structure to the free list. */
596 threadlist_free_add(t);
598 /* Unlock the thread lists. */
604 /* threads_thread_start_internal ***********************************************
606 Start an internal thread in the JVM. No Java thread objects exists
610 name.......UTF-8 name of the thread
611 f..........function pointer to C function to start
613 *******************************************************************************/
615 bool threads_thread_start_internal(utf *name, functionptr f)
619 /* Enter the join-mutex, so if the main-thread is currently
620 waiting to join all threads, the number of non-daemon threads
623 threads_mutex_join_lock();
625 /* Create internal thread data-structure. */
629 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
631 /* The thread is flagged as (non-)daemon thread, we can leave the
634 threads_mutex_join_unlock();
636 /* Create the Java thread object. */
638 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
641 /* Start the thread. */
643 threads_impl_thread_start(t, f);
645 /* everything's ok */
651 /* threads_thread_start ********************************************************
653 Start a Java thread in the JVM. Only the java thread object exists
657 object.....the java thread object java.lang.Thread
659 *******************************************************************************/
661 void threads_thread_start(java_handle_t *object)
663 java_lang_Thread *to;
665 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
666 java_lang_VMThread *vmto;
669 to = (java_lang_Thread *) object;
671 /* Enter the join-mutex, so if the main-thread is currently
672 waiting to join all threads, the number of non-daemon threads
675 threads_mutex_join_lock();
677 /* Create internal thread data-structure. */
681 /* this is a normal Java thread */
683 t->flags |= THREAD_FLAG_JAVA;
685 #if defined(ENABLE_JAVASE)
686 /* Is this a daemon thread? */
688 if (LLNI_field_direct(to, daemon) == true)
689 t->flags |= THREAD_FLAG_DAEMON;
692 /* The thread is flagged and (non-)daemon thread, we can leave the
695 threads_mutex_join_unlock();
697 /* Link the two objects together. */
699 thread_set_object(t, object);
701 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
703 /* Get the java.lang.VMThread object and do some sanity checks. */
705 LLNI_field_get_ref(to, vmThread, vmto);
708 assert(LLNI_field_direct(vmto, vmdata) == NULL);
710 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
712 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
716 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
718 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
721 # error unknown classpath configuration
724 /* Start the thread. Don't pass a function pointer (NULL) since
725 we want Thread.run()V here. */
727 threads_impl_thread_start(t, NULL);
732 * Attaches the current thread to the VM.
734 * @param vm_aargs Attach arguments.
735 * @param isdaemon true if the attached thread should be a daemon
738 * @return true on success, false otherwise.
740 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
746 java_handle_t *group;
748 /* If the current thread has already been attached, this operation
751 result = thread_current_is_attached();
756 /* Enter the join-mutex, so if the main-thread is currently
757 waiting to join all threads, the number of non-daemon threads
760 threads_mutex_join_lock();
762 /* Create internal thread data structure. */
766 /* Thread is a Java thread and running. */
768 t->flags = THREAD_FLAG_JAVA;
771 t->flags |= THREAD_FLAG_DAEMON;
773 /* Store the internal thread data-structure in the TSD. */
775 thread_set_current(t);
777 /* The thread is flagged and (non-)daemon thread, we can leave the
780 threads_mutex_join_unlock();
782 DEBUGTHREADS("attaching", t);
784 /* Get the thread name. */
786 if (vm_aargs != NULL) {
787 u = utf_new_char(vm_aargs->name);
793 name = javastring_new(u);
795 #if defined(ENABLE_JAVASE)
796 /* Get the threadgroup. */
798 if (vm_aargs != NULL)
799 group = (java_handle_t *) vm_aargs->group;
803 /* If no threadgroup was given, use the main threadgroup. */
806 group = threadgroup_main;
809 #if defined(ENABLE_INTRP)
810 /* create interpreter stack */
813 MSET(intrp_main_stack, 0, u1, opt_stacksize);
814 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
818 /* Create the Java thread object. */
820 if (!thread_create_object(t, name, group))
823 /* The thread is completely initialized. */
825 thread_set_state_runnable(t);
832 * Attaches the current external thread to the VM. This function is
833 * called by JNI's AttachCurrentThread.
835 * @param vm_aargs Attach arguments.
836 * @param isdaemon true if the attached thread should be a daemon
839 * @return true on success, false otherwise.
841 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
845 #if defined(ENABLE_GC_BOEHM)
846 struct GC_stack_base sb;
849 #if defined(ENABLE_GC_BOEHM)
850 /* Register the thread with Boehm-GC. This must happen before the
851 thread allocates any memory from the GC heap.*/
853 result = GC_get_stack_base(&sb);
855 if (result != GC_SUCCESS)
856 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
858 GC_register_my_thread(&sb);
861 result = thread_attach_current_thread(vm_aargs, isdaemon);
863 if (result == false) {
864 #if defined(ENABLE_GC_BOEHM)
865 /* Unregister the thread. */
867 GC_unregister_my_thread();
878 * Detaches the current external thread from the VM. This function is
879 * called by JNI's DetachCurrentThread.
881 * @return true on success, false otherwise.
883 bool thread_detach_current_external_thread(void)
887 result = thread_detach_current_thread();
892 #if defined(ENABLE_GC_BOEHM)
893 /* Unregister the thread with Boehm-GC. This must happen after
894 the thread allocates any memory from the GC heap. */
896 /* Don't detach the main thread. This is a workaround for
897 OpenJDK's java binary. */
898 if (thread_get_current()->index != 1)
899 GC_unregister_my_thread();
906 /* thread_fprint_name **********************************************************
908 Print the name of the given thread to the given stream.
911 t ........ thread data-structure
912 stream ... stream to print to
914 *******************************************************************************/
916 void thread_fprint_name(threadobject *t, FILE *stream)
918 java_lang_Thread *to;
920 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
921 java_lang_String *name;
922 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
923 java_chararray_t *name;
926 to = (java_lang_Thread *) thread_get_object(t);
931 LLNI_field_get_ref(to, name, name);
933 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
935 javastring_fprint((java_handle_t *) name, stream);
937 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
939 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
940 /* FIXME This prints to stdout. */
941 utf_display_printable_ascii(utf_null);
944 # error unknown classpath configuration
949 /* thread_print_info ***********************************************************
951 Print information of the passed thread.
954 t ... thread data-structure.
956 *******************************************************************************/
958 void thread_print_info(threadobject *t)
960 java_lang_Thread *to;
963 /* If the thread is currently in initalization, don't print it. */
965 to = (java_lang_Thread *) thread_get_object(t);
967 /* Print as much as we can when we are in state NEW. */
970 /* Print thread name. */
973 thread_fprint_name(t, stdout);
979 if (thread_is_daemon(t))
983 printf(" prio=%d", LLNI_field_direct(to, priority));
986 #if SIZEOF_VOID_P == 8
987 printf(" t=0x%016lx tid=0x%016lx (%ld)",
988 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
990 printf(" t=0x%08x tid=0x%08x (%d)",
991 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
994 printf(" index=%d", t->index);
996 /* Print thread state. */
998 state = cacaothread_get_state(t);
1001 case THREAD_STATE_NEW:
1004 case THREAD_STATE_RUNNABLE:
1005 printf(" runnable");
1007 case THREAD_STATE_BLOCKED:
1010 case THREAD_STATE_WAITING:
1013 case THREAD_STATE_TIMED_WAITING:
1014 printf(" waiting on condition");
1016 case THREAD_STATE_TERMINATED:
1017 printf(" terminated");
1020 vm_abort("thread_print_info: unknown thread state %d", state);
1025 /* threads_get_current_tid *****************************************************
1027 Return the tid of the current thread.
1032 *******************************************************************************/
1034 intptr_t threads_get_current_tid(void)
1036 threadobject *thread;
1038 thread = THREADOBJECT;
1040 /* this may happen during bootstrap */
1045 return (intptr_t) thread->tid;
1049 /* thread_set_state_runnable ***************************************************
1051 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1053 NOTE: If the thread has already terminated, don't set the state.
1054 This is important for threads_detach_thread.
1056 *******************************************************************************/
1058 void thread_set_state_runnable(threadobject *t)
1060 /* Set the state inside a lock. */
1064 if (t->state != THREAD_STATE_TERMINATED) {
1065 t->state = THREAD_STATE_RUNNABLE;
1067 DEBUGTHREADS("is RUNNABLE", t);
1070 threadlist_unlock();
1074 /* thread_set_state_waiting ****************************************************
1076 Set the current state of the given thread to THREAD_STATE_WAITING.
1078 NOTE: If the thread has already terminated, don't set the state.
1079 This is important for threads_detach_thread.
1081 *******************************************************************************/
1083 void thread_set_state_waiting(threadobject *t)
1085 /* Set the state inside a lock. */
1089 if (t->state != THREAD_STATE_TERMINATED) {
1090 t->state = THREAD_STATE_WAITING;
1092 DEBUGTHREADS("is WAITING", t);
1095 threadlist_unlock();
1099 /* thread_set_state_timed_waiting **********************************************
1101 Set the current state of the given thread to
1102 THREAD_STATE_TIMED_WAITING.
1104 NOTE: If the thread has already terminated, don't set the state.
1105 This is important for threads_detach_thread.
1107 *******************************************************************************/
1109 void thread_set_state_timed_waiting(threadobject *t)
1111 /* Set the state inside a lock. */
1115 if (t->state != THREAD_STATE_TERMINATED) {
1116 t->state = THREAD_STATE_TIMED_WAITING;
1118 DEBUGTHREADS("is TIMED_WAITING", t);
1121 threadlist_unlock();
1125 /* thread_set_state_terminated *************************************************
1127 Set the current state of the given thread to
1128 THREAD_STATE_TERMINATED.
1130 *******************************************************************************/
1132 void thread_set_state_terminated(threadobject *t)
1134 /* Set the state inside a lock. */
1138 t->state = THREAD_STATE_TERMINATED;
1140 DEBUGTHREADS("is TERMINATED", t);
1142 threadlist_unlock();
1146 /* thread_get_thread **********************************************************
1148 Return the thread data structure of the given Java thread object.
1151 h ... java.lang.{VM}Thread object
1156 *******************************************************************************/
1158 threadobject *thread_get_thread(java_handle_t *h)
1161 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1162 java_lang_VMThread *vmto;
1163 java_lang_Object *to;
1165 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1169 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1171 vmto = (java_lang_VMThread *) h;
1173 LLNI_field_get_val(vmto, vmdata, to);
1175 t = (threadobject *) to;
1177 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1179 /* XXX This is just a quick hack. */
1183 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1184 LLNI_equals(t->object, h, equal);
1190 threadlist_unlock();
1192 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1194 log_println("threads_get_thread: IMPLEMENT ME!");
1197 # error unknown classpath configuration
1204 /* threads_thread_is_alive *****************************************************
1206 Returns if the give thread is alive.
1208 *******************************************************************************/
1210 bool threads_thread_is_alive(threadobject *t)
1214 state = cacaothread_get_state(t);
1217 case THREAD_STATE_NEW:
1218 case THREAD_STATE_TERMINATED:
1221 case THREAD_STATE_RUNNABLE:
1222 case THREAD_STATE_BLOCKED:
1223 case THREAD_STATE_WAITING:
1224 case THREAD_STATE_TIMED_WAITING:
1228 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1231 /* keep compiler happy */
1237 /* threads_dump ****************************************************************
1239 Dumps info for all threads running in the JVM. This function is
1240 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1242 *******************************************************************************/
1244 void threads_dump(void)
1248 /* XXX we should stop the world here */
1250 /* Lock the thread lists. */
1254 printf("Full thread dump CACAO "VERSION":\n");
1256 /* iterate over all started threads */
1258 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1259 /* ignore threads which are in state NEW */
1260 if (t->state == THREAD_STATE_NEW)
1263 #if defined(ENABLE_GC_CACAO)
1264 /* Suspend the thread. */
1265 /* XXX Is the suspend reason correct? */
1267 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1268 vm_abort("threads_dump: threads_suspend_thread failed");
1271 /* Print thread info. */
1274 thread_print_info(t);
1277 /* Print trace of thread. */
1279 stacktrace_print_of_thread(t);
1281 #if defined(ENABLE_GC_CACAO)
1282 /* Resume the thread. */
1284 if (threads_resume_thread(t) == false)
1285 vm_abort("threads_dump: threads_resume_thread failed");
1289 /* Unlock the thread lists. */
1291 threadlist_unlock();
1296 * These are local overrides for various environment variables in Emacs.
1297 * Please do not remove this and leave it at the end of the file, where
1298 * Emacs will automagically detect them.
1299 * ---------------------------------------------------------------------
1302 * indent-tabs-mode: t
1306 * vim:noexpandtab:sw=4:ts=4: