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.hpp"
69 #include "vmcore/class.h"
70 #include "vmcore/globals.hpp"
71 #include "vmcore/method.h"
72 #include "vmcore/options.h"
74 #if defined(ENABLE_STATISTICS)
75 # include "vmcore/statistics.h"
78 #include "vmcore/utf8.h"
81 /* global variables ***********************************************************/
83 static methodinfo *thread_method_init;
84 static java_handle_t *threadgroup_system;
85 static java_handle_t *threadgroup_main;
87 #if defined(__LINUX__)
88 /* XXX Remove for exact-GC. */
89 bool threads_pthreads_implementation_nptl;
93 /* static functions ***********************************************************/
95 static void thread_create_initial_threadgroups(void);
96 static void thread_create_initial_thread(void);
97 static threadobject *thread_new(void);
100 /* threads_preinit *************************************************************
102 Do some early initialization of stuff required.
104 *******************************************************************************/
106 void threads_preinit(void)
108 threadobject *mainthread;
109 #if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
114 TRACESUBSYSTEMINITIALIZATION("threads_preinit");
116 #if defined(__LINUX__)
117 /* XXX Remove for exact-GC. */
119 /* On Linux we need to check the pthread implementation. */
121 /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
122 /* If the glibc is a pre-2.3.2 version, we fall back to
125 # if defined(_CS_GNU_LIBPTHREAD_VERSION)
126 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
128 /* Some systems return as length 0 (maybe cross-compilation
129 related). In this case we also fall back to linuxthreads. */
132 pathbuf = MNEW(char, len);
134 (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
136 if (strstr(pathbuf, "NPTL") != NULL)
137 threads_pthreads_implementation_nptl = true;
139 threads_pthreads_implementation_nptl = false;
142 threads_pthreads_implementation_nptl = false;
144 threads_pthreads_implementation_nptl = false;
148 /* Initialize the threads implementation (sets the thinlock on the
151 threads_impl_preinit();
153 /* Create internal thread data-structure for the main thread. */
155 mainthread = thread_new();
157 /* The main thread should always have index 1. */
159 if (mainthread->index != 1)
160 vm_abort("threads_preinit: main thread index not 1: %d != 1",
163 /* thread is a Java thread and running */
165 mainthread->flags |= THREAD_FLAG_JAVA;
166 mainthread->state = THREAD_STATE_RUNNABLE;
168 /* Store the internal thread data-structure in the TSD. */
170 thread_set_current(mainthread);
174 /* threads_init ****************************************************************
176 Initialize the main thread.
178 *******************************************************************************/
180 void threads_init(void)
182 TRACESUBSYSTEMINITIALIZATION("threads_init");
184 /* Create the system and main thread groups. */
186 thread_create_initial_threadgroups();
188 /* Cache the java.lang.Thread initialization method. */
190 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
193 class_resolveclassmethod(class_java_lang_Thread,
195 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
196 class_java_lang_Thread,
199 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
202 class_resolveclassmethod(class_java_lang_Thread,
204 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
205 class_java_lang_Thread,
208 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
211 class_resolveclassmethod(class_java_lang_Thread,
213 utf_java_lang_String__void,
214 class_java_lang_Thread,
218 # error unknown classpath configuration
221 if (thread_method_init == NULL)
222 vm_abort("threads_init: failed to resolve thread init method");
224 thread_create_initial_thread();
228 /* thread_create_object ********************************************************
230 Create a Java thread object for the given thread data-structure,
231 initializes it and adds the thread to the threadgroup.
236 name .... thread name
237 group ... threadgroup
241 *******************************************************************************/
243 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
246 java_lang_Thread *to;
248 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
249 java_lang_VMThread *vmto;
255 /* Create a java.lang.Thread Java object. */
257 o = builtin_new(class_java_lang_Thread);
262 to = (java_lang_Thread *) o;
264 /* Set the Java object in the thread data-structure. This
265 indicates that the thread is attached to the VM. */
267 thread_set_object(t, (java_handle_t *) to);
269 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
271 /* Create a java.lang.VMThread Java object. */
273 vmto = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
278 /* Set the Java thread object in the Java VM-thread object. */
280 LLNI_field_set_ref(vmto, thread, to);
282 /* Set the thread data-structure in the Java VM-thread object. */
284 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
287 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
289 isdaemon = thread_is_daemon(t);
291 (void) vm_call_method(thread_method_init, o, vmto, name, NORM_PRIORITY,
294 if (exceptions_get_exception())
297 /* Set the threadgroup in the Java thread object. */
299 LLNI_field_set_ref(to, group, (java_lang_ThreadGroup *) group);
301 /* Add thread to the threadgroup. */
303 LLNI_class_get(group, c);
305 m = class_resolveclassmethod(c,
307 utf_java_lang_Thread__V,
308 class_java_lang_ThreadGroup,
314 (void) vm_call_method(m, group, to);
316 if (exceptions_get_exception())
319 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
321 /* OpenJDK's java.lang.Thread does not have a VMThread field in
322 the class. Nothing to do here. */
324 /* Set the priority. java.lang.Thread.<init> requires it because
325 it sets the priority of the current thread to the parent's one
326 (which is the current thread in this case). */
328 LLNI_field_set_val(to, priority, NORM_PRIORITY);
331 java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V */
333 (void) vm_call_method(thread_method_init, o, group, name);
335 if (exceptions_get_exception())
338 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
340 /* Set the thread data-structure in the Java thread object. */
342 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
344 /* Call: public Thread(Ljava/lang/String;)V */
346 (void) vm_call_method(thread_method_init, o, name);
348 if (exceptions_get_exception())
352 # error unknown classpath configuration
359 /* thread_create_initial_threadgroups ******************************************
361 Create the initial threadgroups.
364 Create the main threadgroup only and set the system
365 threadgroup to the main threadgroup.
368 Create the system and main threadgroup.
371 This function is a no-op.
373 *******************************************************************************/
375 static void thread_create_initial_threadgroups(void)
377 #if defined(ENABLE_JAVASE)
378 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
380 /* Allocate and initialize the main thread group. */
382 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
384 if (threadgroup_main == NULL)
385 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
387 /* Use the same threadgroup for system as for main. */
389 threadgroup_system = threadgroup_main;
391 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
396 /* Allocate and initialize the system thread group. */
398 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
400 if (threadgroup_system == NULL)
401 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
403 /* Allocate and initialize the main thread group. */
405 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
407 if (threadgroup_main == NULL)
408 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
410 name = javastring_new(utf_main);
412 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
414 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
415 class_java_lang_ThreadGroup,
419 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
421 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
423 if (exceptions_get_exception())
424 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
427 # error unknown classpath configuration
433 /* thread_create_initial_thread ***********************************************
435 Create the initial thread: main
437 *******************************************************************************/
439 static void thread_create_initial_thread(void)
444 /* Get the main-thread (NOTE: The main thread is always the first
445 thread in the list). */
447 t = threadlist_first();
449 /* The thread name. */
451 name = javastring_new(utf_main);
453 #if defined(ENABLE_INTRP)
454 /* create interpreter stack */
457 MSET(intrp_main_stack, 0, u1, opt_stacksize);
458 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
462 /* Create the Java thread object. */
464 if (!thread_create_object(t, name, threadgroup_main))
465 vm_abort("thread_create_initial_thread: failed to create Java object");
467 /* Initialize the implementation specific bits. */
471 DEBUGTHREADS("starting (main)", t);
475 /* thread_new ******************************************************************
477 Allocates and initializes an internal thread data-structure and
478 adds it to the threads list.
480 *******************************************************************************/
482 static threadobject *thread_new(void)
487 /* Lock the thread lists */
491 index = threadlist_get_free_index();
493 /* Allocate a thread data structure. */
495 /* First, try to get one from the free-list. */
497 t = threadlist_free_first();
500 /* Remove from free list. */
502 threadlist_free_remove(t);
504 /* Equivalent of MZERO on the else path */
506 threads_impl_thread_clear(t);
509 #if defined(ENABLE_GC_BOEHM)
510 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
512 t = NEW(threadobject);
515 #if defined(ENABLE_STATISTICS)
517 size_threadobject += sizeof(threadobject);
522 MZERO(t, threadobject, 1);
524 #if defined(ENABLE_GC_CACAO)
525 /* Register reference to java.lang.Thread with the GC. */
526 /* FIXME is it ok to do this only once? */
528 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
529 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
532 /* Initialize the implementation-specific bits. */
534 threads_impl_thread_init(t);
537 /* Pre-compute the thinlock-word. */
542 t->thinlock = lock_pre_compute_thinlock(t->index);
544 t->state = THREAD_STATE_NEW;
546 #if defined(ENABLE_GC_CACAO)
547 t->flags |= THREAD_FLAG_IN_NATIVE;
550 /* Initialize the implementation-specific bits. */
552 threads_impl_thread_reuse(t);
554 /* Add the thread to the thread list. */
558 /* Unlock the thread lists. */
566 /* thread_free *****************************************************************
568 Remove the thread from the threads-list and free the internal
569 thread data structure. The thread index is added to the
570 thread-index free-list.
573 t ... thread data structure
575 *******************************************************************************/
577 void thread_free(threadobject *t)
579 /* Lock the thread lists. */
583 /* Remove the thread from the thread-list. */
585 threadlist_remove(t);
587 /* Add the thread index to the free list. */
589 threadlist_index_add(t->index);
591 /* Set the reference to the Java object to NULL. */
593 thread_set_object(t, NULL);
595 /* Add the thread data structure to the free list. */
597 threadlist_free_add(t);
599 /* Unlock the thread lists. */
605 /* threads_thread_start_internal ***********************************************
607 Start an internal thread in the JVM. No Java thread objects exists
611 name.......UTF-8 name of the thread
612 f..........function pointer to C function to start
614 *******************************************************************************/
616 bool threads_thread_start_internal(utf *name, functionptr f)
620 /* Enter the join-mutex, so if the main-thread is currently
621 waiting to join all threads, the number of non-daemon threads
624 threads_mutex_join_lock();
626 /* Create internal thread data-structure. */
630 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
632 /* The thread is flagged as (non-)daemon thread, we can leave the
635 threads_mutex_join_unlock();
637 /* Create the Java thread object. */
639 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
642 /* Start the thread. */
644 threads_impl_thread_start(t, f);
646 /* everything's ok */
652 /* threads_thread_start ********************************************************
654 Start a Java thread in the JVM. Only the java thread object exists
658 object.....the java thread object java.lang.Thread
660 *******************************************************************************/
662 void threads_thread_start(java_handle_t *object)
664 java_lang_Thread *to;
666 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
667 java_lang_VMThread *vmto;
670 to = (java_lang_Thread *) object;
672 /* Enter the join-mutex, so if the main-thread is currently
673 waiting to join all threads, the number of non-daemon threads
676 threads_mutex_join_lock();
678 /* Create internal thread data-structure. */
682 /* this is a normal Java thread */
684 t->flags |= THREAD_FLAG_JAVA;
686 #if defined(ENABLE_JAVASE)
687 /* Is this a daemon thread? */
689 if (LLNI_field_direct(to, daemon) == true)
690 t->flags |= THREAD_FLAG_DAEMON;
693 /* The thread is flagged and (non-)daemon thread, we can leave the
696 threads_mutex_join_unlock();
698 /* Link the two objects together. */
700 thread_set_object(t, object);
702 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
704 /* Get the java.lang.VMThread object and do some sanity checks. */
706 LLNI_field_get_ref(to, vmThread, vmto);
709 assert(LLNI_field_direct(vmto, vmdata) == NULL);
711 LLNI_field_set_val(vmto, vmdata, (java_lang_Object *) t);
713 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
717 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
719 LLNI_field_set_val(to, vm_thread, (java_lang_Object *) t);
722 # error unknown classpath configuration
725 /* Start the thread. Don't pass a function pointer (NULL) since
726 we want Thread.run()V here. */
728 threads_impl_thread_start(t, NULL);
733 * Attaches the current thread to the VM.
735 * @param vm_aargs Attach arguments.
736 * @param isdaemon true if the attached thread should be a daemon
739 * @return true on success, false otherwise.
741 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
747 java_handle_t *group;
749 /* If the current thread has already been attached, this operation
752 result = thread_current_is_attached();
757 /* Enter the join-mutex, so if the main-thread is currently
758 waiting to join all threads, the number of non-daemon threads
761 threads_mutex_join_lock();
763 /* Create internal thread data structure. */
767 /* Thread is a Java thread and running. */
769 t->flags = THREAD_FLAG_JAVA;
772 t->flags |= THREAD_FLAG_DAEMON;
774 /* Store the internal thread data-structure in the TSD. */
776 thread_set_current(t);
778 /* The thread is flagged and (non-)daemon thread, we can leave the
781 threads_mutex_join_unlock();
783 DEBUGTHREADS("attaching", t);
785 /* Get the thread name. */
787 if (vm_aargs != NULL) {
788 u = utf_new_char(vm_aargs->name);
794 name = javastring_new(u);
796 #if defined(ENABLE_JAVASE)
797 /* Get the threadgroup. */
799 if (vm_aargs != NULL)
800 group = (java_handle_t *) vm_aargs->group;
804 /* If no threadgroup was given, use the main threadgroup. */
807 group = threadgroup_main;
810 #if defined(ENABLE_INTRP)
811 /* create interpreter stack */
814 MSET(intrp_main_stack, 0, u1, opt_stacksize);
815 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
819 /* Create the Java thread object. */
821 if (!thread_create_object(t, name, group))
824 /* The thread is completely initialized. */
826 thread_set_state_runnable(t);
833 * Attaches the current external thread to the VM. This function is
834 * called by JNI's AttachCurrentThread.
836 * @param vm_aargs Attach arguments.
837 * @param isdaemon true if the attached thread should be a daemon
840 * @return true on success, false otherwise.
842 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
846 #if defined(ENABLE_GC_BOEHM)
847 struct GC_stack_base sb;
850 #if defined(ENABLE_GC_BOEHM)
851 /* Register the thread with Boehm-GC. This must happen before the
852 thread allocates any memory from the GC heap.*/
854 result = GC_get_stack_base(&sb);
856 if (result != GC_SUCCESS)
857 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
859 GC_register_my_thread(&sb);
862 result = thread_attach_current_thread(vm_aargs, isdaemon);
864 if (result == false) {
865 #if defined(ENABLE_GC_BOEHM)
866 /* Unregister the thread. */
868 GC_unregister_my_thread();
879 * Detaches the current external thread from the VM. This function is
880 * called by JNI's DetachCurrentThread.
882 * @return true on success, false otherwise.
884 bool thread_detach_current_external_thread(void)
888 result = thread_detach_current_thread();
893 #if defined(ENABLE_GC_BOEHM)
894 /* Unregister the thread with Boehm-GC. This must happen after
895 the thread allocates any memory from the GC heap. */
897 /* Don't detach the main thread. This is a workaround for
898 OpenJDK's java binary. */
899 if (thread_get_current()->index != 1)
900 GC_unregister_my_thread();
907 /* thread_fprint_name **********************************************************
909 Print the name of the given thread to the given stream.
912 t ........ thread data-structure
913 stream ... stream to print to
915 *******************************************************************************/
917 void thread_fprint_name(threadobject *t, FILE *stream)
919 java_lang_Thread *to;
921 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
922 java_lang_String *name;
923 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
924 java_chararray_t *name;
927 to = (java_lang_Thread *) thread_get_object(t);
932 LLNI_field_get_ref(to, name, name);
934 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
936 javastring_fprint((java_handle_t *) name, stream);
938 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
940 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
941 /* FIXME This prints to stdout. */
942 utf_display_printable_ascii(utf_null);
945 # error unknown classpath configuration
950 /* thread_print_info ***********************************************************
952 Print information of the passed thread.
955 t ... thread data-structure.
957 *******************************************************************************/
959 void thread_print_info(threadobject *t)
961 java_lang_Thread *to;
964 /* If the thread is currently in initalization, don't print it. */
966 to = (java_lang_Thread *) thread_get_object(t);
968 /* Print as much as we can when we are in state NEW. */
971 /* Print thread name. */
974 thread_fprint_name(t, stdout);
980 if (thread_is_daemon(t))
984 printf(" prio=%d", LLNI_field_direct(to, priority));
987 #if SIZEOF_VOID_P == 8
988 printf(" t=0x%016lx tid=0x%016lx (%ld)",
989 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
991 printf(" t=0x%08x tid=0x%08x (%d)",
992 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
995 printf(" index=%d", t->index);
997 /* Print thread state. */
999 state = cacaothread_get_state(t);
1002 case THREAD_STATE_NEW:
1005 case THREAD_STATE_RUNNABLE:
1006 printf(" runnable");
1008 case THREAD_STATE_BLOCKED:
1011 case THREAD_STATE_WAITING:
1014 case THREAD_STATE_TIMED_WAITING:
1015 printf(" waiting on condition");
1017 case THREAD_STATE_TERMINATED:
1018 printf(" terminated");
1021 vm_abort("thread_print_info: unknown thread state %d", state);
1026 /* threads_get_current_tid *****************************************************
1028 Return the tid of the current thread.
1033 *******************************************************************************/
1035 intptr_t threads_get_current_tid(void)
1037 threadobject *thread;
1039 thread = THREADOBJECT;
1041 /* this may happen during bootstrap */
1046 return (intptr_t) thread->tid;
1050 /* thread_set_state_runnable ***************************************************
1052 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1054 NOTE: If the thread has already terminated, don't set the state.
1055 This is important for threads_detach_thread.
1057 *******************************************************************************/
1059 void thread_set_state_runnable(threadobject *t)
1061 /* Set the state inside a lock. */
1065 if (t->state != THREAD_STATE_TERMINATED) {
1066 t->state = THREAD_STATE_RUNNABLE;
1068 DEBUGTHREADS("is RUNNABLE", t);
1071 threadlist_unlock();
1075 /* thread_set_state_waiting ****************************************************
1077 Set the current state of the given thread to THREAD_STATE_WAITING.
1079 NOTE: If the thread has already terminated, don't set the state.
1080 This is important for threads_detach_thread.
1082 *******************************************************************************/
1084 void thread_set_state_waiting(threadobject *t)
1086 /* Set the state inside a lock. */
1090 if (t->state != THREAD_STATE_TERMINATED) {
1091 t->state = THREAD_STATE_WAITING;
1093 DEBUGTHREADS("is WAITING", t);
1096 threadlist_unlock();
1100 /* thread_set_state_timed_waiting **********************************************
1102 Set the current state of the given thread to
1103 THREAD_STATE_TIMED_WAITING.
1105 NOTE: If the thread has already terminated, don't set the state.
1106 This is important for threads_detach_thread.
1108 *******************************************************************************/
1110 void thread_set_state_timed_waiting(threadobject *t)
1112 /* Set the state inside a lock. */
1116 if (t->state != THREAD_STATE_TERMINATED) {
1117 t->state = THREAD_STATE_TIMED_WAITING;
1119 DEBUGTHREADS("is TIMED_WAITING", t);
1122 threadlist_unlock();
1126 /* thread_set_state_terminated *************************************************
1128 Set the current state of the given thread to
1129 THREAD_STATE_TERMINATED.
1131 *******************************************************************************/
1133 void thread_set_state_terminated(threadobject *t)
1135 /* Set the state inside a lock. */
1139 t->state = THREAD_STATE_TERMINATED;
1141 DEBUGTHREADS("is TERMINATED", t);
1143 threadlist_unlock();
1147 /* thread_get_thread **********************************************************
1149 Return the thread data structure of the given Java thread object.
1152 h ... java.lang.{VM}Thread object
1157 *******************************************************************************/
1159 threadobject *thread_get_thread(java_handle_t *h)
1162 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1163 java_lang_VMThread *vmto;
1164 java_lang_Object *to;
1166 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1170 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1172 vmto = (java_lang_VMThread *) h;
1174 LLNI_field_get_val(vmto, vmdata, to);
1176 t = (threadobject *) to;
1178 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1180 /* XXX This is just a quick hack. */
1184 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1185 LLNI_equals(t->object, h, equal);
1191 threadlist_unlock();
1193 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1195 log_println("threads_get_thread: IMPLEMENT ME!");
1198 # error unknown classpath configuration
1205 /* threads_thread_is_alive *****************************************************
1207 Returns if the give thread is alive.
1209 *******************************************************************************/
1211 bool threads_thread_is_alive(threadobject *t)
1215 state = cacaothread_get_state(t);
1218 case THREAD_STATE_NEW:
1219 case THREAD_STATE_TERMINATED:
1222 case THREAD_STATE_RUNNABLE:
1223 case THREAD_STATE_BLOCKED:
1224 case THREAD_STATE_WAITING:
1225 case THREAD_STATE_TIMED_WAITING:
1229 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1232 /* keep compiler happy */
1238 /* threads_dump ****************************************************************
1240 Dumps info for all threads running in the JVM. This function is
1241 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1243 *******************************************************************************/
1245 void threads_dump(void)
1249 /* XXX we should stop the world here */
1251 /* Lock the thread lists. */
1255 printf("Full thread dump CACAO "VERSION":\n");
1257 /* iterate over all started threads */
1259 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
1260 /* ignore threads which are in state NEW */
1261 if (t->state == THREAD_STATE_NEW)
1264 #if defined(ENABLE_GC_CACAO)
1265 /* Suspend the thread. */
1266 /* XXX Is the suspend reason correct? */
1268 if (threads_suspend_thread(t, SUSPEND_REASON_JNI) == false)
1269 vm_abort("threads_dump: threads_suspend_thread failed");
1272 /* Print thread info. */
1275 thread_print_info(t);
1278 /* Print trace of thread. */
1280 stacktrace_print_of_thread(t);
1282 #if defined(ENABLE_GC_CACAO)
1283 /* Resume the thread. */
1285 if (threads_resume_thread(t) == false)
1286 vm_abort("threads_dump: threads_resume_thread failed");
1290 /* Unlock the thread lists. */
1292 threadlist_unlock();
1297 * These are local overrides for various environment variables in Emacs.
1298 * Please do not remove this and leave it at the end of the file, where
1299 * Emacs will automagically detect them.
1300 * ---------------------------------------------------------------------
1303 * indent-tabs-mode: t
1307 * vim:noexpandtab:sw=4:ts=4: