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(int32_t flags);
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(THREAD_FLAG_JAVA);
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 already running. */
151 mainthread->state = THREAD_STATE_RUNNABLE;
153 /* Store the internal thread data-structure in the TSD. */
155 thread_set_current(mainthread);
159 /* threads_init ****************************************************************
161 Initialize the main thread.
163 *******************************************************************************/
165 void threads_init(void)
167 TRACESUBSYSTEMINITIALIZATION("threads_init");
169 /* Create the system and main thread groups. */
171 thread_create_initial_threadgroups();
173 /* Cache the java.lang.Thread initialization method. */
175 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
178 class_resolveclassmethod(class_java_lang_Thread,
180 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
181 class_java_lang_Thread,
184 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
187 class_resolveclassmethod(class_java_lang_Thread,
189 utf_new_char("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"),
190 class_java_lang_Thread,
193 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
196 class_resolveclassmethod(class_java_lang_Thread,
198 utf_java_lang_String__void,
199 class_java_lang_Thread,
203 # error unknown classpath configuration
206 if (thread_method_init == NULL)
207 vm_abort("threads_init: failed to resolve thread init method");
209 thread_create_initial_thread();
213 /* thread_create_object ********************************************************
215 Create a Java thread object for the given thread data-structure,
216 initializes it and adds the thread to the threadgroup.
221 name .... thread name
222 group ... threadgroup
226 *******************************************************************************/
228 static bool thread_create_object(threadobject *t, java_handle_t *name, java_handle_t *group)
230 /* Create a java.lang.Thread Java object. */
232 java_handle_t* h = builtin_new(class_java_lang_Thread);
237 java_lang_Thread jlt(h);
239 // Set the Java object in the thread data-structure. This
240 // indicates that the thread is attached to the VM.
241 thread_set_object(t, jlt.get_handle());
243 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
245 h = builtin_new(class_java_lang_VMThread);
250 // Create and initialize a java.lang.VMThread object.
251 java_lang_VMThread jlvmt(h, jlt.get_handle(), t);
254 java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
256 bool isdaemon = thread_is_daemon(t);
258 (void) vm_call_method(thread_method_init, jlt.get_handle(), jlvmt.get_handle(),
259 name, NORM_PRIORITY, isdaemon);
261 if (exceptions_get_exception())
264 // Set the ThreadGroup in the Java thread object.
265 jlt.set_group(group);
267 /* Add thread to the threadgroup. */
270 LLNI_class_get(group, c);
272 methodinfo* m = class_resolveclassmethod(c,
274 utf_java_lang_Thread__V,
275 class_java_lang_ThreadGroup,
281 (void) vm_call_method(m, group, jlt.get_handle());
283 if (exceptions_get_exception())
286 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
288 /* Set the priority. java.lang.Thread.<init> requires it because
289 it sets the priority of the current thread to the parent's one
290 (which is the current thread in this case). */
291 jlt.set_priority(NORM_PRIORITY);
293 // Call: java.lang.Thread.<init>(Ljava/lang/ThreadGroup;Ljava/lang/String;)V
295 (void) vm_call_method(thread_method_init, jlt.get_handle(), group, name);
297 if (exceptions_get_exception())
300 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
302 // Set the thread data-structure in the Java thread object.
303 jlt.set_vm_thread(t);
305 // Call: public Thread(Ljava/lang/String;)V
306 (void) vm_call_method(thread_method_init, jlt.get_handle(), name);
308 if (exceptions_get_exception())
312 # error unknown classpath configuration
319 /* thread_create_initial_threadgroups ******************************************
321 Create the initial threadgroups.
324 Create the main threadgroup only and set the system
325 threadgroup to the main threadgroup.
328 Create the system and main threadgroup.
331 This function is a no-op.
333 *******************************************************************************/
335 static void thread_create_initial_threadgroups(void)
337 #if defined(ENABLE_JAVASE)
338 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
340 /* Allocate and initialize the main thread group. */
342 threadgroup_main = native_new_and_init(class_java_lang_ThreadGroup);
344 if (threadgroup_main == NULL)
345 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
347 /* Use the same threadgroup for system as for main. */
349 threadgroup_system = threadgroup_main;
351 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
356 /* Allocate and initialize the system thread group. */
358 threadgroup_system = native_new_and_init(class_java_lang_ThreadGroup);
360 if (threadgroup_system == NULL)
361 vm_abort("thread_create_initial_threadgroups: failed to allocate system threadgroup");
363 /* Allocate and initialize the main thread group. */
365 threadgroup_main = builtin_new(class_java_lang_ThreadGroup);
367 if (threadgroup_main == NULL)
368 vm_abort("thread_create_initial_threadgroups: failed to allocate main threadgroup");
370 name = javastring_new(utf_main);
372 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
374 utf_Ljava_lang_ThreadGroup_Ljava_lang_String__V,
375 class_java_lang_ThreadGroup,
379 vm_abort("thread_create_initial_threadgroups: failed to resolve threadgroup init method");
381 (void) vm_call_method(m, threadgroup_main, threadgroup_system, name);
383 if (exceptions_get_exception())
384 vm_abort("thread_create_initial_threadgroups: exception while initializing main threadgroup");
387 # error unknown classpath configuration
393 /* thread_create_initial_thread ***********************************************
395 Create the initial thread: main
397 *******************************************************************************/
399 static void thread_create_initial_thread(void)
404 /* Get the main-thread (NOTE: The main thread is always the first
405 thread in the list). */
407 t = ThreadList::get_main_thread();
409 /* The thread name. */
411 name = javastring_new(utf_main);
413 #if defined(ENABLE_INTRP)
414 /* create interpreter stack */
417 MSET(intrp_main_stack, 0, u1, opt_stacksize);
418 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
422 /* Create the Java thread object. */
424 if (!thread_create_object(t, name, threadgroup_main))
425 vm_abort("thread_create_initial_thread: failed to create Java object");
427 /* Initialize the implementation specific bits. */
431 DEBUGTHREADS("starting (main)", t);
435 /* thread_new ******************************************************************
437 Allocates and initializes an internal thread data-structure and
438 adds it to the threads list.
440 *******************************************************************************/
442 static threadobject *thread_new(int32_t flags)
447 /* Lock the thread lists */
451 index = ThreadList::get_free_thread_index();
453 /* Allocate a thread data structure. */
455 /* First, try to get one from the free-list. */
457 t = ThreadList::get_free_thread();
460 /* Equivalent of MZERO on the else path */
462 threads_impl_thread_clear(t);
465 #if defined(ENABLE_GC_BOEHM)
466 t = GCNEW_UNCOLLECTABLE(threadobject, 1);
468 t = NEW(threadobject);
471 #if defined(ENABLE_STATISTICS)
473 size_threadobject += sizeof(threadobject);
478 MZERO(t, threadobject, 1);
480 // Initialize the mutex and the condition.
481 t->flc_lock = new Mutex();
482 t->flc_cond = new Condition();
484 t->waitmutex = new Mutex();
485 t->waitcond = new Condition();
487 t->suspendmutex = new Mutex();
488 t->suspendcond = new Condition();
490 #if defined(ENABLE_TLH)
494 #if defined(ENABLE_GC_CACAO)
495 /* Register reference to java.lang.Thread with the GC. */
496 /* FIXME is it ok to do this only once? */
498 gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
499 gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
502 t->_dumpmemory = new DumpMemory();
505 /* Pre-compute the thinlock-word. */
510 t->thinlock = Lockword::pre_compute_thinlock(t->index);
512 t->state = THREAD_STATE_NEW;
514 #if defined(ENABLE_GC_CACAO)
515 t->flags |= THREAD_FLAG_IN_NATIVE;
518 /* Initialize the implementation-specific bits. */
520 threads_impl_thread_reuse(t);
522 /* Add the thread to the thread list. */
524 ThreadList::add_to_active_thread_list(t);
526 /* Unlock the thread lists. */
528 ThreadList::unlock();
534 /* thread_free *****************************************************************
536 Remove the thread from the threads-list and free the internal
537 thread data structure. The thread index is added to the
538 thread-index free-list.
541 t ... thread data structure
543 *******************************************************************************/
545 void thread_free(threadobject *t)
547 /* Set the reference to the Java object to NULL. */
549 thread_set_object(t, NULL);
551 /* Release the thread. */
553 ThreadList::release_thread(t);
557 /* threads_thread_start_internal ***********************************************
559 Start an internal thread in the JVM. No Java thread objects exists
563 name.......UTF-8 name of the thread
564 f..........function pointer to C function to start
566 *******************************************************************************/
568 bool threads_thread_start_internal(utf *name, functionptr f)
572 /* Enter the join-mutex, so if the main-thread is currently
573 waiting to join all threads, the number of non-daemon threads
576 threads_mutex_join_lock();
578 /* Create internal thread data-structure. */
580 t = thread_new(THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON);
582 /* The thread is flagged as (non-)daemon thread, we can leave the
585 threads_mutex_join_unlock();
587 /* Create the Java thread object. */
589 if (!thread_create_object(t, javastring_new(name), threadgroup_system))
592 /* Start the thread. */
594 threads_impl_thread_start(t, f);
596 /* everything's ok */
602 /* threads_thread_start ********************************************************
604 Start a Java thread in the JVM. Only the java thread object exists
608 object.....the java thread object java.lang.Thread
610 *******************************************************************************/
612 void threads_thread_start(java_handle_t *object)
614 java_lang_Thread jlt(object);
616 /* Enter the join-mutex, so if the main-thread is currently
617 waiting to join all threads, the number of non-daemon threads
620 threads_mutex_join_lock();
622 /* Create internal thread data-structure. */
624 threadobject* t = thread_new(THREAD_FLAG_JAVA);
626 #if defined(ENABLE_JAVASE)
627 /* Is this a daemon thread? */
629 if (jlt.get_daemon() == true)
630 t->flags |= THREAD_FLAG_DAEMON;
633 /* The thread is flagged and (non-)daemon thread, we can leave the
636 threads_mutex_join_unlock();
638 /* Link the two objects together. */
640 thread_set_object(t, object);
642 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
644 /* Get the java.lang.VMThread object and do some sanity checks. */
645 java_lang_VMThread jlvmt(jlt.get_vmThread());
647 assert(jlvmt.get_handle() != NULL);
648 assert(jlvmt.get_vmdata() == NULL);
652 ThreadList::unlock();
654 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
658 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
660 jlt.set_vm_thread(t);
663 # error unknown classpath configuration
666 /* Start the thread. Don't pass a function pointer (NULL) since
667 we want Thread.run()V here. */
669 threads_impl_thread_start(t, NULL);
674 * Attaches the current thread to the VM.
676 * @param vm_aargs Attach arguments.
677 * @param isdaemon true if the attached thread should be a daemon
680 * @return true on success, false otherwise.
682 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
688 java_handle_t *group;
690 /* If the current thread has already been attached, this operation
693 result = thread_current_is_attached();
698 /* Enter the join-mutex, so if the main-thread is currently
699 waiting to join all threads, the number of non-daemon threads
702 threads_mutex_join_lock();
704 /* Create internal thread data structure. */
706 t = thread_new(THREAD_FLAG_JAVA);
709 t->flags |= THREAD_FLAG_DAEMON;
711 /* Store the internal thread data-structure in the TSD. */
713 thread_set_current(t);
715 /* The thread is flagged and (non-)daemon thread, we can leave the
718 threads_mutex_join_unlock();
720 DEBUGTHREADS("attaching", t);
722 /* Get the thread name. */
724 if (vm_aargs != NULL) {
725 u = utf_new_char(vm_aargs->name);
731 name = javastring_new(u);
733 #if defined(ENABLE_JAVASE)
734 /* Get the threadgroup. */
736 if (vm_aargs != NULL)
737 group = (java_handle_t *) vm_aargs->group;
741 /* If no threadgroup was given, use the main threadgroup. */
744 group = threadgroup_main;
747 #if defined(ENABLE_INTRP)
748 /* create interpreter stack */
751 MSET(intrp_main_stack, 0, u1, opt_stacksize);
752 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
756 /* Create the Java thread object. */
758 if (!thread_create_object(t, name, group))
761 /* The thread is completely initialized. */
763 thread_set_state_runnable(t);
770 * Attaches the current external thread to the VM. This function is
771 * called by JNI's AttachCurrentThread.
773 * @param vm_aargs Attach arguments.
774 * @param isdaemon true if the attached thread should be a daemon
777 * @return true on success, false otherwise.
779 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
783 #if defined(ENABLE_GC_BOEHM)
784 struct GC_stack_base sb;
787 #if defined(ENABLE_GC_BOEHM)
788 /* Register the thread with Boehm-GC. This must happen before the
789 thread allocates any memory from the GC heap.*/
791 result = GC_get_stack_base(&sb);
793 if (result != GC_SUCCESS)
794 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
796 GC_register_my_thread(&sb);
799 result = thread_attach_current_thread(vm_aargs, isdaemon);
801 if (result == false) {
802 #if defined(ENABLE_GC_BOEHM)
803 /* Unregister the thread. */
805 GC_unregister_my_thread();
816 * Detaches the current external thread from the VM. This function is
817 * called by JNI's DetachCurrentThread.
819 * @return true on success, false otherwise.
821 bool thread_detach_current_external_thread(void)
825 result = thread_detach_current_thread();
830 #if defined(ENABLE_GC_BOEHM)
831 /* Unregister the thread with Boehm-GC. This must happen after
832 the thread allocates any memory from the GC heap. */
834 /* Don't detach the main thread. This is a workaround for
835 OpenJDK's java binary. */
836 if (thread_get_current()->index != 1)
837 GC_unregister_my_thread();
844 /* thread_fprint_name **********************************************************
846 Print the name of the given thread to the given stream.
849 t ........ thread data-structure
850 stream ... stream to print to
852 *******************************************************************************/
854 void thread_fprint_name(threadobject *t, FILE *stream)
856 if (thread_get_object(t) == NULL)
859 java_lang_Thread jlt(thread_get_object(t));
861 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
863 java_handle_t* name = jlt.get_name();
864 javastring_fprint(name, stream);
866 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
868 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
869 //java_chararray_t *name;
871 /* FIXME This prints to stdout. */
872 utf_display_printable_ascii(utf_null);
875 # error unknown classpath configuration
880 /* thread_print_info ***********************************************************
882 Print information of the passed thread.
885 t ... thread data-structure.
887 *******************************************************************************/
889 void thread_print_info(threadobject *t)
891 java_lang_Thread jlt(thread_get_object(t));
893 /* Print as much as we can when we are in state NEW. */
895 if (jlt.get_handle() != NULL) {
896 /* Print thread name. */
899 thread_fprint_name(t, stdout);
905 if (thread_is_daemon(t))
908 if (jlt.get_handle() != NULL) {
909 printf(" prio=%d", jlt.get_priority());
912 #if SIZEOF_VOID_P == 8
913 printf(" t=0x%016lx tid=0x%016lx (%ld)",
914 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
916 printf(" t=0x%08x tid=0x%08x (%d)",
917 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
920 printf(" index=%d", t->index);
922 /* Print thread state. */
924 int state = cacaothread_get_state(t);
927 case THREAD_STATE_NEW:
930 case THREAD_STATE_RUNNABLE:
933 case THREAD_STATE_BLOCKED:
936 case THREAD_STATE_WAITING:
939 case THREAD_STATE_TIMED_WAITING:
940 printf(" waiting on condition");
942 case THREAD_STATE_PARKED:
945 case THREAD_STATE_TIMED_PARKED:
946 printf(" timed parked");
948 case THREAD_STATE_TERMINATED:
949 printf(" terminated");
952 vm_abort("thread_print_info: unknown thread state %d", state);
957 /* threads_get_current_tid *****************************************************
959 Return the tid of the current thread.
964 *******************************************************************************/
966 intptr_t threads_get_current_tid(void)
968 threadobject *thread;
970 thread = THREADOBJECT;
972 /* this may happen during bootstrap */
977 return (intptr_t) thread->tid;
982 * Set the current state of the given thread. This method should only
983 * be called while holding the threadlist-lock and after checking that
984 * the new state is valid. It is best to not call this method directly
985 * but call the specific setter methods below.
987 static inline void thread_set_state(threadobject *t, int state)
989 // Set the state of our internal threadobject.
992 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
993 // Set the state of the java.lang.Thread object.
994 java_lang_Thread thread(thread_get_object(t));
995 assert(thread.is_non_null());
996 thread.set_threadStatus(state);
1001 /* thread_set_state_runnable ***************************************************
1003 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1005 NOTE: If the thread has already terminated, don't set the state.
1006 This is important for threads_detach_thread.
1008 *******************************************************************************/
1010 void thread_set_state_runnable(threadobject *t)
1012 /* Set the state inside a lock. */
1016 if (t->state != THREAD_STATE_TERMINATED) {
1017 thread_set_state(t, THREAD_STATE_RUNNABLE);
1019 DEBUGTHREADS("is RUNNABLE", t);
1022 ThreadList::unlock();
1026 /* thread_set_state_waiting ****************************************************
1028 Set the current state of the given thread to THREAD_STATE_WAITING.
1030 NOTE: If the thread has already terminated, don't set the state.
1031 This is important for threads_detach_thread.
1033 *******************************************************************************/
1035 void thread_set_state_waiting(threadobject *t)
1037 /* Set the state inside a lock. */
1041 if (t->state != THREAD_STATE_TERMINATED) {
1042 thread_set_state(t, THREAD_STATE_WAITING);
1044 DEBUGTHREADS("is WAITING", t);
1047 ThreadList::unlock();
1051 /* thread_set_state_timed_waiting **********************************************
1053 Set the current state of the given thread to
1054 THREAD_STATE_TIMED_WAITING.
1056 NOTE: If the thread has already terminated, don't set the state.
1057 This is important for threads_detach_thread.
1059 *******************************************************************************/
1061 void thread_set_state_timed_waiting(threadobject *t)
1063 /* Set the state inside a lock. */
1067 if (t->state != THREAD_STATE_TERMINATED) {
1068 thread_set_state(t, THREAD_STATE_TIMED_WAITING);
1070 DEBUGTHREADS("is TIMED_WAITING", t);
1073 ThreadList::unlock();
1077 /* thread_set_state_parked *****************************************************
1079 Set the current state of the given thread to THREAD_STATE_PARKED.
1081 NOTE: If the thread has already terminated, don't set the state.
1082 This is important for threads_detach_thread.
1084 *******************************************************************************/
1086 void thread_set_state_parked(threadobject *t)
1088 /* Set the state inside a lock. */
1092 if (t->state != THREAD_STATE_TERMINATED) {
1093 thread_set_state(t, THREAD_STATE_PARKED);
1095 DEBUGTHREADS("is PARKED", t);
1098 ThreadList::unlock();
1102 /* thread_set_state_timed_parked ***********************************************
1104 Set the current state of the given thread to THREAD_STATE_TIMED_PARKED.
1106 NOTE: If the thread has already terminated, don't set the state.
1107 This is important for threads_detach_thread.
1109 *******************************************************************************/
1111 void thread_set_state_timed_parked(threadobject *t)
1113 /* Set the state inside a lock. */
1117 if (t->state != THREAD_STATE_TERMINATED) {
1118 thread_set_state(t, THREAD_STATE_TIMED_PARKED);
1120 DEBUGTHREADS("is TIMED_PARKED", t);
1123 ThreadList::unlock();
1127 /* thread_set_state_terminated *************************************************
1129 Set the current state of the given thread to
1130 THREAD_STATE_TERMINATED.
1132 *******************************************************************************/
1134 void thread_set_state_terminated(threadobject *t)
1136 /* Set the state inside a lock. */
1140 thread_set_state(t, THREAD_STATE_TERMINATED);
1142 DEBUGTHREADS("is TERMINATED", t);
1144 ThreadList::unlock();
1148 /* thread_get_thread **********************************************************
1150 Return the thread data structure of the given Java thread object.
1153 h ... java.lang.{VM}Thread object
1159 Usage of this function without the thread list lock held is
1160 almost certainly a bug.
1162 *******************************************************************************/
1164 threadobject *thread_get_thread(java_handle_t *h)
1166 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1168 java_lang_VMThread jlvmt(h);
1169 threadobject* t = jlvmt.get_vmdata();
1171 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1173 /* XXX This is just a quick hack. */
1174 threadobject* t = ThreadList::get_thread_from_java_object(h);
1176 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1178 log_println("thread_get_thread: IMPLEMENT ME!");
1179 threadobject* t = NULL;
1182 # error unknown classpath configuration
1189 /* threads_thread_is_alive *****************************************************
1191 Returns if the give thread is alive.
1193 *******************************************************************************/
1195 bool threads_thread_is_alive(threadobject *t)
1199 state = cacaothread_get_state(t);
1202 case THREAD_STATE_NEW:
1203 case THREAD_STATE_TERMINATED:
1206 case THREAD_STATE_RUNNABLE:
1207 case THREAD_STATE_BLOCKED:
1208 case THREAD_STATE_WAITING:
1209 case THREAD_STATE_TIMED_WAITING:
1210 case THREAD_STATE_PARKED:
1211 case THREAD_STATE_TIMED_PARKED:
1215 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1218 /* keep compiler happy */
1223 /* thread_is_interrupted *******************************************************
1225 Check if the given thread has been interrupted.
1228 t ... the thread to check
1231 true, if the given thread had been interrupted
1233 *******************************************************************************/
1235 bool thread_is_interrupted(threadobject *t)
1237 /* We need the mutex because classpath will call this function when
1238 a blocking system call is interrupted. The mutex ensures that it will
1239 see the correct value for the interrupted flag. */
1241 t->waitmutex->lock();
1242 bool interrupted = t->interrupted;
1243 t->waitmutex->unlock();
1249 /* thread_set_interrupted ******************************************************
1251 Set the interrupted flag to the given value.
1254 interrupted ... value to set
1256 *******************************************************************************/
1258 void thread_set_interrupted(threadobject *t, bool interrupted)
1260 t->waitmutex->lock();
1261 t->interrupted = interrupted;
1262 t->waitmutex->unlock();
1265 /* thread_handle_set_priority **************************************************
1267 Calls threads_set_thread_priority for the threadobject associated
1268 with the thread indicated by handle th, while holding the thread
1271 *******************************************************************************/
1273 void thread_handle_set_priority(java_handle_t *th, int priority)
1277 threadobject *t = thread_get_thread(th);
1278 /* For GNU classpath, this should not happen, because both
1279 setPriority() and start() are synchronized. */
1281 threads_set_thread_priority(t->tid, priority);
1284 /* thread_handle_is_interrupted ************************************************
1286 Calls thread_is_interrupted for the threadobject associated with
1287 the thread indicated by handle th, while holding the thread list
1290 *******************************************************************************/
1292 bool thread_handle_is_interrupted(java_handle_t *th)
1296 threadobject *t = thread_get_thread(th);
1297 return t ? thread_is_interrupted(t) : false;
1300 /* thread_handle_interrupt *****************************************************
1302 Calls threads_thread_interrupt for the threadobject associated with
1303 the thread indicated by handle th, while holding the thread list
1306 *******************************************************************************/
1308 void thread_handle_interrupt(java_handle_t *th)
1312 threadobject *t = thread_get_thread(th);
1313 /* For GNU classpath, this should not happen, because both
1314 interrupt() and start() are synchronized. */
1316 threads_thread_interrupt(t);
1319 /* thread_handle_get_state *****************************************************
1321 Calls cacaothread_get_state for the threadobject associated with
1322 the thread indicated by handle th, while holding the thread list
1325 *******************************************************************************/
1327 int thread_handle_get_state(java_handle_t *th)
1331 threadobject *t = thread_get_thread(th);
1332 return t ? cacaothread_get_state(t) : THREAD_STATE_NEW;
1337 * These are local overrides for various environment variables in Emacs.
1338 * Please do not remove this and leave it at the end of the file, where
1339 * Emacs will automagically detect them.
1340 * ---------------------------------------------------------------------
1343 * indent-tabs-mode: t
1347 * vim:noexpandtab:sw=4:ts=4: