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.hpp"
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.hpp"
45 #include "threads/lock.hpp"
46 #include "threads/threadlist.hpp"
47 #include "threads/thread.hpp"
49 #include "vm/jit/builtin.hpp"
50 #include "vm/class.hpp"
51 #include "vm/exceptions.hpp"
52 #include "vm/globals.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/method.hpp"
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::get_main_thread();
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_thread_index();
454 /* Allocate a thread data structure. */
456 /* First, try to get one from the free-list. */
458 t = ThreadList::get_free_thread();
461 /* Equivalent of MZERO on the else path */
463 threads_impl_thread_clear(t);
466 #if defined(ENABLE_GC_BOEHM)
467 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
469 t = NEW(threadobject);
472 #if defined(ENABLE_STATISTICS)
474 size_threadobject += sizeof(threadobject);
479 MZERO(t, threadobject, 1);
481 // Initialize the mutex and the condition.
482 t->flc_lock = new Mutex();
483 t->flc_cond = new Condition();
485 t->waitmutex = new Mutex();
486 t->waitcond = new Condition();
488 t->suspendmutex = new Mutex();
489 t->suspendcond = new Condition();
491 #if defined(ENABLE_TLH)
495 #if defined(ENABLE_GC_CACAO)
496 /* Register reference to java.lang.Thread with the GC. */
497 /* FIXME is it ok to do this only once? */
499 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
500 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
503 t->_dumpmemory = new DumpMemory();
506 /* Pre-compute the thinlock-word. */
511 t->thinlock = Lockword::pre_compute_thinlock(t->index);
513 t->state = THREAD_STATE_NEW;
515 #if defined(ENABLE_GC_CACAO)
516 t->flags |= THREAD_FLAG_IN_NATIVE;
519 /* Initialize the implementation-specific bits. */
521 threads_impl_thread_reuse(t);
523 /* Add the thread to the thread list. */
525 ThreadList::add_to_active_thread_list(t);
527 /* Unlock the thread lists. */
529 ThreadList::unlock();
535 /* thread_free *****************************************************************
537 Remove the thread from the threads-list and free the internal
538 thread data structure. The thread index is added to the
539 thread-index free-list.
542 t ... thread data structure
544 *******************************************************************************/
546 void thread_free(threadobject *t)
548 /* Set the reference to the Java object to NULL. */
550 thread_set_object(t, NULL);
552 /* Release the thread. */
554 ThreadList::release_thread(t);
558 /* threads_thread_start_internal ***********************************************
560 Start an internal thread in the JVM. No Java thread objects exists
564 name.......UTF-8 name of the thread
565 f..........function pointer to C function to start
567 *******************************************************************************/
569 bool threads_thread_start_internal(utf *name, functionptr f)
573 /* Enter the join-mutex, so if the main-thread is currently
574 waiting to join all threads, the number of non-daemon threads
577 threads_mutex_join_lock();
579 /* Create internal thread data-structure. */
583 t->flags |= THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
585 /* The thread is flagged as (non-)daemon thread, we can leave the
588 threads_mutex_join_unlock();
590 /* Create the Java thread object. */
592 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
595 /* Start the thread. */
597 threads_impl_thread_start(t, f);
599 /* everything's ok */
605 /* threads_thread_start ********************************************************
607 Start a Java thread in the JVM. Only the java thread object exists
611 object.....the java thread object java.lang.Thread
613 *******************************************************************************/
615 void threads_thread_start(java_handle_t *object)
617 java_lang_Thread jlt(object);
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. */
627 threadobject* t = thread_new();
629 /* this is a normal Java thread */
631 t->flags |= THREAD_FLAG_JAVA;
633 #if defined(ENABLE_JAVASE)
634 /* Is this a daemon thread? */
636 if (jlt.get_daemon() == true)
637 t->flags |= THREAD_FLAG_DAEMON;
640 /* The thread is flagged and (non-)daemon thread, we can leave the
643 threads_mutex_join_unlock();
645 /* Link the two objects together. */
647 thread_set_object(t, object);
649 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
651 /* Get the java.lang.VMThread object and do some sanity checks. */
652 java_lang_VMThread jlvmt(jlt.get_vmThread());
654 assert(jlvmt.get_handle() != NULL);
655 assert(jlvmt.get_vmdata() == NULL);
659 ThreadList::unlock();
661 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
665 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
667 jlt.set_vm_thread(t);
670 # error unknown classpath configuration
673 /* Start the thread. Don't pass a function pointer (NULL) since
674 we want Thread.run()V here. */
676 threads_impl_thread_start(t, NULL);
681 * Attaches the current thread to the VM.
683 * @param vm_aargs Attach arguments.
684 * @param isdaemon true if the attached thread should be a daemon
687 * @return true on success, false otherwise.
689 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
695 java_handle_t *group;
697 /* If the current thread has already been attached, this operation
700 result = thread_current_is_attached();
705 /* Enter the join-mutex, so if the main-thread is currently
706 waiting to join all threads, the number of non-daemon threads
709 threads_mutex_join_lock();
711 /* Create internal thread data structure. */
715 /* Thread is a Java thread and running. */
717 t->flags = THREAD_FLAG_JAVA;
720 t->flags |= THREAD_FLAG_DAEMON;
722 /* Store the internal thread data-structure in the TSD. */
724 thread_set_current(t);
726 /* The thread is flagged and (non-)daemon thread, we can leave the
729 threads_mutex_join_unlock();
731 DEBUGTHREADS("attaching", t);
733 /* Get the thread name. */
735 if (vm_aargs != NULL) {
736 u = utf_new_char(vm_aargs->name);
742 name = javastring_new(u);
744 #if defined(ENABLE_JAVASE)
745 /* Get the threadgroup. */
747 if (vm_aargs != NULL)
748 group = (java_handle_t *) vm_aargs->group;
752 /* If no threadgroup was given, use the main threadgroup. */
755 group = threadgroup_main;
758 #if defined(ENABLE_INTRP)
759 /* create interpreter stack */
762 MSET(intrp_main_stack, 0, u1, opt_stacksize);
763 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
767 /* Create the Java thread object. */
769 if (!thread_create_object(t, name, group))
772 /* The thread is completely initialized. */
774 thread_set_state_runnable(t);
781 * Attaches the current external thread to the VM. This function is
782 * called by JNI's AttachCurrentThread.
784 * @param vm_aargs Attach arguments.
785 * @param isdaemon true if the attached thread should be a daemon
788 * @return true on success, false otherwise.
790 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
794 #if defined(ENABLE_GC_BOEHM)
795 struct GC_stack_base sb;
798 #if defined(ENABLE_GC_BOEHM)
799 /* Register the thread with Boehm-GC. This must happen before the
800 thread allocates any memory from the GC heap.*/
802 result = GC_get_stack_base(&sb);
804 if (result != GC_SUCCESS)
805 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
807 GC_register_my_thread(&sb);
810 result = thread_attach_current_thread(vm_aargs, isdaemon);
812 if (result == false) {
813 #if defined(ENABLE_GC_BOEHM)
814 /* Unregister the thread. */
816 GC_unregister_my_thread();
827 * Detaches the current external thread from the VM. This function is
828 * called by JNI's DetachCurrentThread.
830 * @return true on success, false otherwise.
832 bool thread_detach_current_external_thread(void)
836 result = thread_detach_current_thread();
841 #if defined(ENABLE_GC_BOEHM)
842 /* Unregister the thread with Boehm-GC. This must happen after
843 the thread allocates any memory from the GC heap. */
845 /* Don't detach the main thread. This is a workaround for
846 OpenJDK's java binary. */
847 if (thread_get_current()->index != 1)
848 GC_unregister_my_thread();
855 /* thread_fprint_name **********************************************************
857 Print the name of the given thread to the given stream.
860 t ........ thread data-structure
861 stream ... stream to print to
863 *******************************************************************************/
865 void thread_fprint_name(threadobject *t, FILE *stream)
867 if (thread_get_object(t) == NULL)
870 java_lang_Thread jlt(thread_get_object(t));
872 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
874 java_handle_t* name = jlt.get_name();
875 javastring_fprint(name, stream);
877 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
879 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
880 //java_chararray_t *name;
882 /* FIXME This prints to stdout. */
883 utf_display_printable_ascii(utf_null);
886 # error unknown classpath configuration
891 /* thread_print_info ***********************************************************
893 Print information of the passed thread.
896 t ... thread data-structure.
898 *******************************************************************************/
900 void thread_print_info(threadobject *t)
902 java_lang_Thread jlt(thread_get_object(t));
904 /* Print as much as we can when we are in state NEW. */
906 if (jlt.get_handle() != NULL) {
907 /* Print thread name. */
910 thread_fprint_name(t, stdout);
916 if (thread_is_daemon(t))
919 if (jlt.get_handle() != NULL) {
920 printf(" prio=%d", jlt.get_priority());
923 #if SIZEOF_VOID_P == 8
924 printf(" t=0x%016lx tid=0x%016lx (%ld)",
925 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
927 printf(" t=0x%08x tid=0x%08x (%d)",
928 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
931 printf(" index=%d", t->index);
933 /* Print thread state. */
935 int state = cacaothread_get_state(t);
938 case THREAD_STATE_NEW:
941 case THREAD_STATE_RUNNABLE:
944 case THREAD_STATE_BLOCKED:
947 case THREAD_STATE_WAITING:
950 case THREAD_STATE_TIMED_WAITING:
951 printf(" waiting on condition");
953 case THREAD_STATE_PARKED:
956 case THREAD_STATE_TIMED_PARKED:
957 printf(" timed parked");
959 case THREAD_STATE_TERMINATED:
960 printf(" terminated");
963 vm_abort("thread_print_info: unknown thread state %d", state);
968 /* threads_get_current_tid *****************************************************
970 Return the tid of the current thread.
975 *******************************************************************************/
977 intptr_t threads_get_current_tid(void)
979 threadobject *thread;
981 thread = THREADOBJECT;
983 /* this may happen during bootstrap */
988 return (intptr_t) thread->tid;
993 * Set the current state of the given thread. This method should only
994 * be called while holding the threadlist-lock and after checking that
995 * the new state is valid. It is best to not call this method directly
996 * but call the specific setter methods below.
998 static inline void thread_set_state(threadobject *t, int state)
1000 // Set the state of our internal threadobject.
1003 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1004 // Set the state of the java.lang.Thread object.
1005 java_lang_Thread thread(thread_get_object(t));
1006 assert(thread.is_non_null());
1007 thread.set_threadStatus(state);
1012 /* thread_set_state_runnable ***************************************************
1014 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1016 NOTE: If the thread has already terminated, don't set the state.
1017 This is important for threads_detach_thread.
1019 *******************************************************************************/
1021 void thread_set_state_runnable(threadobject *t)
1023 /* Set the state inside a lock. */
1027 if (t->state != THREAD_STATE_TERMINATED) {
1028 thread_set_state(t, THREAD_STATE_RUNNABLE);
1030 DEBUGTHREADS("is RUNNABLE", t);
1033 ThreadList::unlock();
1037 /* thread_set_state_waiting ****************************************************
1039 Set the current state of the given thread to THREAD_STATE_WAITING.
1041 NOTE: If the thread has already terminated, don't set the state.
1042 This is important for threads_detach_thread.
1044 *******************************************************************************/
1046 void thread_set_state_waiting(threadobject *t)
1048 /* Set the state inside a lock. */
1052 if (t->state != THREAD_STATE_TERMINATED) {
1053 thread_set_state(t, THREAD_STATE_WAITING);
1055 DEBUGTHREADS("is WAITING", t);
1058 ThreadList::unlock();
1062 /* thread_set_state_timed_waiting **********************************************
1064 Set the current state of the given thread to
1065 THREAD_STATE_TIMED_WAITING.
1067 NOTE: If the thread has already terminated, don't set the state.
1068 This is important for threads_detach_thread.
1070 *******************************************************************************/
1072 void thread_set_state_timed_waiting(threadobject *t)
1074 /* Set the state inside a lock. */
1078 if (t->state != THREAD_STATE_TERMINATED) {
1079 thread_set_state(t, THREAD_STATE_TIMED_WAITING);
1081 DEBUGTHREADS("is TIMED_WAITING", t);
1084 ThreadList::unlock();
1088 /* thread_set_state_parked *****************************************************
1090 Set the current state of the given thread to THREAD_STATE_PARKED.
1092 NOTE: If the thread has already terminated, don't set the state.
1093 This is important for threads_detach_thread.
1095 *******************************************************************************/
1097 void thread_set_state_parked(threadobject *t)
1099 /* Set the state inside a lock. */
1103 if (t->state != THREAD_STATE_TERMINATED) {
1104 thread_set_state(t, THREAD_STATE_PARKED);
1106 DEBUGTHREADS("is PARKED", t);
1109 ThreadList::unlock();
1113 /* thread_set_state_timed_parked ***********************************************
1115 Set the current state of the given thread to THREAD_STATE_TIMED_PARKED.
1117 NOTE: If the thread has already terminated, don't set the state.
1118 This is important for threads_detach_thread.
1120 *******************************************************************************/
1122 void thread_set_state_timed_parked(threadobject *t)
1124 /* Set the state inside a lock. */
1128 if (t->state != THREAD_STATE_TERMINATED) {
1129 thread_set_state(t, THREAD_STATE_TIMED_PARKED);
1131 DEBUGTHREADS("is TIMED_PARKED", t);
1134 ThreadList::unlock();
1138 /* thread_set_state_terminated *************************************************
1140 Set the current state of the given thread to
1141 THREAD_STATE_TERMINATED.
1143 *******************************************************************************/
1145 void thread_set_state_terminated(threadobject *t)
1147 /* Set the state inside a lock. */
1151 thread_set_state(t, THREAD_STATE_TERMINATED);
1153 DEBUGTHREADS("is TERMINATED", t);
1155 ThreadList::unlock();
1159 /* thread_get_thread **********************************************************
1161 Return the thread data structure of the given Java thread object.
1164 h ... java.lang.{VM}Thread object
1170 Usage of this function without the thread list lock held is
1171 almost certainly a bug.
1173 *******************************************************************************/
1175 threadobject *thread_get_thread(java_handle_t *h)
1177 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1179 java_lang_VMThread jlvmt(h);
1180 threadobject* t = jlvmt.get_vmdata();
1182 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1184 /* XXX This is just a quick hack. */
1185 threadobject* t = ThreadList::get_thread_from_java_object(h);
1187 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1189 log_println("thread_get_thread: IMPLEMENT ME!");
1190 threadobject* t = NULL;
1193 # error unknown classpath configuration
1200 /* threads_thread_is_alive *****************************************************
1202 Returns if the give thread is alive.
1204 *******************************************************************************/
1206 bool threads_thread_is_alive(threadobject *t)
1210 state = cacaothread_get_state(t);
1213 case THREAD_STATE_NEW:
1214 case THREAD_STATE_TERMINATED:
1217 case THREAD_STATE_RUNNABLE:
1218 case THREAD_STATE_BLOCKED:
1219 case THREAD_STATE_WAITING:
1220 case THREAD_STATE_TIMED_WAITING:
1221 case THREAD_STATE_PARKED:
1222 case THREAD_STATE_TIMED_PARKED:
1226 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1229 /* keep compiler happy */
1234 /* thread_is_interrupted *******************************************************
1236 Check if the given thread has been interrupted.
1239 t ... the thread to check
1242 true, if the given thread had been interrupted
1244 *******************************************************************************/
1246 bool thread_is_interrupted(threadobject *t)
1248 /* We need the mutex because classpath will call this function when
1249 a blocking system call is interrupted. The mutex ensures that it will
1250 see the correct value for the interrupted flag. */
1252 t->waitmutex->lock();
1253 bool interrupted = t->interrupted;
1254 t->waitmutex->unlock();
1260 /* thread_set_interrupted ******************************************************
1262 Set the interrupted flag to the given value.
1265 interrupted ... value to set
1267 *******************************************************************************/
1269 void thread_set_interrupted(threadobject *t, bool interrupted)
1271 t->waitmutex->lock();
1272 t->interrupted = interrupted;
1273 t->waitmutex->unlock();
1276 /* thread_handle_set_priority **************************************************
1278 Calls threads_set_thread_priority for the threadobject associated
1279 with the thread indicated by handle th, while holding the thread
1282 *******************************************************************************/
1284 void thread_handle_set_priority(java_handle_t *th, int priority)
1288 threadobject *t = thread_get_thread(th);
1289 /* For GNU classpath, this should not happen, because both
1290 setPriority() and start() are synchronized. */
1292 threads_set_thread_priority(t->tid, priority);
1295 /* thread_handle_is_interrupted ************************************************
1297 Calls thread_is_interrupted for the threadobject associated with
1298 the thread indicated by handle th, while holding the thread list
1301 *******************************************************************************/
1303 bool thread_handle_is_interrupted(java_handle_t *th)
1307 threadobject *t = thread_get_thread(th);
1308 return t ? thread_is_interrupted(t) : false;
1311 /* thread_handle_interrupt *****************************************************
1313 Calls threads_thread_interrupt for the threadobject associated with
1314 the thread indicated by handle th, while holding the thread list
1317 *******************************************************************************/
1319 void thread_handle_interrupt(java_handle_t *th)
1323 threadobject *t = thread_get_thread(th);
1324 /* For GNU classpath, this should not happen, because both
1325 interrupt() and start() are synchronized. */
1327 threads_thread_interrupt(t);
1330 /* thread_handle_get_state *****************************************************
1332 Calls cacaothread_get_state for the threadobject associated with
1333 the thread indicated by handle th, while holding the thread list
1336 *******************************************************************************/
1338 int thread_handle_get_state(java_handle_t *th)
1342 threadobject *t = thread_get_thread(th);
1343 return t ? cacaothread_get_state(t) : THREAD_STATE_NEW;
1348 * These are local overrides for various environment variables in Emacs.
1349 * Please do not remove this and leave it at the end of the file, where
1350 * Emacs will automagically detect them.
1351 * ---------------------------------------------------------------------
1354 * indent-tabs-mode: t
1358 * vim:noexpandtab:sw=4:ts=4: