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 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
663 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
665 jlt.set_vm_thread(t);
668 # error unknown classpath configuration
671 /* Start the thread. Don't pass a function pointer (NULL) since
672 we want Thread.run()V here. */
674 threads_impl_thread_start(t, NULL);
679 * Attaches the current thread to the VM.
681 * @param vm_aargs Attach arguments.
682 * @param isdaemon true if the attached thread should be a daemon
685 * @return true on success, false otherwise.
687 bool thread_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
693 java_handle_t *group;
695 /* If the current thread has already been attached, this operation
698 result = thread_current_is_attached();
703 /* Enter the join-mutex, so if the main-thread is currently
704 waiting to join all threads, the number of non-daemon threads
707 threads_mutex_join_lock();
709 /* Create internal thread data structure. */
713 /* Thread is a Java thread and running. */
715 t->flags = THREAD_FLAG_JAVA;
718 t->flags |= THREAD_FLAG_DAEMON;
720 /* Store the internal thread data-structure in the TSD. */
722 thread_set_current(t);
724 /* The thread is flagged and (non-)daemon thread, we can leave the
727 threads_mutex_join_unlock();
729 DEBUGTHREADS("attaching", t);
731 /* Get the thread name. */
733 if (vm_aargs != NULL) {
734 u = utf_new_char(vm_aargs->name);
740 name = javastring_new(u);
742 #if defined(ENABLE_JAVASE)
743 /* Get the threadgroup. */
745 if (vm_aargs != NULL)
746 group = (java_handle_t *) vm_aargs->group;
750 /* If no threadgroup was given, use the main threadgroup. */
753 group = threadgroup_main;
756 #if defined(ENABLE_INTRP)
757 /* create interpreter stack */
760 MSET(intrp_main_stack, 0, u1, opt_stacksize);
761 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
765 /* Create the Java thread object. */
767 if (!thread_create_object(t, name, group))
770 /* The thread is completely initialized. */
772 thread_set_state_runnable(t);
779 * Attaches the current external thread to the VM. This function is
780 * called by JNI's AttachCurrentThread.
782 * @param vm_aargs Attach arguments.
783 * @param isdaemon true if the attached thread should be a daemon
786 * @return true on success, false otherwise.
788 bool thread_attach_current_external_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
792 #if defined(ENABLE_GC_BOEHM)
793 struct GC_stack_base sb;
796 #if defined(ENABLE_GC_BOEHM)
797 /* Register the thread with Boehm-GC. This must happen before the
798 thread allocates any memory from the GC heap.*/
800 result = GC_get_stack_base(&sb);
802 if (result != GC_SUCCESS)
803 vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
805 GC_register_my_thread(&sb);
808 result = thread_attach_current_thread(vm_aargs, isdaemon);
810 if (result == false) {
811 #if defined(ENABLE_GC_BOEHM)
812 /* Unregister the thread. */
814 GC_unregister_my_thread();
825 * Detaches the current external thread from the VM. This function is
826 * called by JNI's DetachCurrentThread.
828 * @return true on success, false otherwise.
830 bool thread_detach_current_external_thread(void)
834 result = thread_detach_current_thread();
839 #if defined(ENABLE_GC_BOEHM)
840 /* Unregister the thread with Boehm-GC. This must happen after
841 the thread allocates any memory from the GC heap. */
843 /* Don't detach the main thread. This is a workaround for
844 OpenJDK's java binary. */
845 if (thread_get_current()->index != 1)
846 GC_unregister_my_thread();
853 /* thread_fprint_name **********************************************************
855 Print the name of the given thread to the given stream.
858 t ........ thread data-structure
859 stream ... stream to print to
861 *******************************************************************************/
863 void thread_fprint_name(threadobject *t, FILE *stream)
865 if (thread_get_object(t) == NULL)
868 java_lang_Thread jlt(thread_get_object(t));
870 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
872 java_handle_t* name = jlt.get_name();
873 javastring_fprint(name, stream);
875 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
877 /* FIXME: In OpenJDK and CLDC the name is a char[]. */
878 //java_chararray_t *name;
880 /* FIXME This prints to stdout. */
881 utf_display_printable_ascii(utf_null);
884 # error unknown classpath configuration
889 /* thread_print_info ***********************************************************
891 Print information of the passed thread.
894 t ... thread data-structure.
896 *******************************************************************************/
898 void thread_print_info(threadobject *t)
900 java_lang_Thread jlt(thread_get_object(t));
902 /* Print as much as we can when we are in state NEW. */
904 if (jlt.get_handle() != NULL) {
905 /* Print thread name. */
908 thread_fprint_name(t, stdout);
914 if (thread_is_daemon(t))
917 if (jlt.get_handle() != NULL) {
918 printf(" prio=%d", jlt.get_priority());
921 #if SIZEOF_VOID_P == 8
922 printf(" t=0x%016lx tid=0x%016lx (%ld)",
923 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
925 printf(" t=0x%08x tid=0x%08x (%d)",
926 (ptrint) t, (ptrint) t->tid, (ptrint) t->tid);
929 printf(" index=%d", t->index);
931 /* Print thread state. */
933 int state = cacaothread_get_state(t);
936 case THREAD_STATE_NEW:
939 case THREAD_STATE_RUNNABLE:
942 case THREAD_STATE_BLOCKED:
945 case THREAD_STATE_WAITING:
948 case THREAD_STATE_TIMED_WAITING:
949 printf(" waiting on condition");
951 case THREAD_STATE_PARKED:
954 case THREAD_STATE_TIMED_PARKED:
955 printf(" timed parked");
957 case THREAD_STATE_TERMINATED:
958 printf(" terminated");
961 vm_abort("thread_print_info: unknown thread state %d", state);
966 /* threads_get_current_tid *****************************************************
968 Return the tid of the current thread.
973 *******************************************************************************/
975 intptr_t threads_get_current_tid(void)
977 threadobject *thread;
979 thread = THREADOBJECT;
981 /* this may happen during bootstrap */
986 return (intptr_t) thread->tid;
991 * Set the current state of the given thread. This method should only
992 * be called while holding the threadlist-lock and after checking that
993 * the new state is valid. It is best to not call this method directly
994 * but call the specific setter methods below.
996 static inline void thread_set_state(threadobject *t, int state)
998 // Set the state of our internal threadobject.
1001 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1002 // Set the state of the java.lang.Thread object.
1003 java_lang_Thread thread(thread_get_object(t));
1004 assert(thread.is_non_null());
1005 thread.set_threadStatus(state);
1010 /* thread_set_state_runnable ***************************************************
1012 Set the current state of the given thread to THREAD_STATE_RUNNABLE.
1014 NOTE: If the thread has already terminated, don't set the state.
1015 This is important for threads_detach_thread.
1017 *******************************************************************************/
1019 void thread_set_state_runnable(threadobject *t)
1021 /* Set the state inside a lock. */
1025 if (t->state != THREAD_STATE_TERMINATED) {
1026 thread_set_state(t, THREAD_STATE_RUNNABLE);
1028 DEBUGTHREADS("is RUNNABLE", t);
1031 ThreadList::unlock();
1035 /* thread_set_state_waiting ****************************************************
1037 Set the current state of the given thread to THREAD_STATE_WAITING.
1039 NOTE: If the thread has already terminated, don't set the state.
1040 This is important for threads_detach_thread.
1042 *******************************************************************************/
1044 void thread_set_state_waiting(threadobject *t)
1046 /* Set the state inside a lock. */
1050 if (t->state != THREAD_STATE_TERMINATED) {
1051 thread_set_state(t, THREAD_STATE_WAITING);
1053 DEBUGTHREADS("is WAITING", t);
1056 ThreadList::unlock();
1060 /* thread_set_state_timed_waiting **********************************************
1062 Set the current state of the given thread to
1063 THREAD_STATE_TIMED_WAITING.
1065 NOTE: If the thread has already terminated, don't set the state.
1066 This is important for threads_detach_thread.
1068 *******************************************************************************/
1070 void thread_set_state_timed_waiting(threadobject *t)
1072 /* Set the state inside a lock. */
1076 if (t->state != THREAD_STATE_TERMINATED) {
1077 thread_set_state(t, THREAD_STATE_TIMED_WAITING);
1079 DEBUGTHREADS("is TIMED_WAITING", t);
1082 ThreadList::unlock();
1086 /* thread_set_state_parked *****************************************************
1088 Set the current state of the given thread to THREAD_STATE_PARKED.
1090 NOTE: If the thread has already terminated, don't set the state.
1091 This is important for threads_detach_thread.
1093 *******************************************************************************/
1095 void thread_set_state_parked(threadobject *t)
1097 /* Set the state inside a lock. */
1101 if (t->state != THREAD_STATE_TERMINATED) {
1102 thread_set_state(t, THREAD_STATE_PARKED);
1104 DEBUGTHREADS("is PARKED", t);
1107 ThreadList::unlock();
1111 /* thread_set_state_timed_parked ***********************************************
1113 Set the current state of the given thread to THREAD_STATE_TIMED_PARKED.
1115 NOTE: If the thread has already terminated, don't set the state.
1116 This is important for threads_detach_thread.
1118 *******************************************************************************/
1120 void thread_set_state_timed_parked(threadobject *t)
1122 /* Set the state inside a lock. */
1126 if (t->state != THREAD_STATE_TERMINATED) {
1127 thread_set_state(t, THREAD_STATE_TIMED_PARKED);
1129 DEBUGTHREADS("is TIMED_PARKED", t);
1132 ThreadList::unlock();
1136 /* thread_set_state_terminated *************************************************
1138 Set the current state of the given thread to
1139 THREAD_STATE_TERMINATED.
1141 *******************************************************************************/
1143 void thread_set_state_terminated(threadobject *t)
1145 /* Set the state inside a lock. */
1149 thread_set_state(t, THREAD_STATE_TERMINATED);
1151 DEBUGTHREADS("is TERMINATED", t);
1153 ThreadList::unlock();
1157 /* thread_get_thread **********************************************************
1159 Return the thread data structure of the given Java thread object.
1162 h ... java.lang.{VM}Thread object
1167 *******************************************************************************/
1169 threadobject *thread_get_thread(java_handle_t *h)
1171 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1173 java_lang_VMThread jlvmt(h);
1174 threadobject* t = jlvmt.get_vmdata();
1176 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1178 /* XXX This is just a quick hack. */
1179 threadobject* t = ThreadList::get_thread_from_java_object(h);
1181 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1183 log_println("thread_get_thread: IMPLEMENT ME!");
1184 threadobject* t = NULL;
1187 # error unknown classpath configuration
1194 /* threads_thread_is_alive *****************************************************
1196 Returns if the give thread is alive.
1198 *******************************************************************************/
1200 bool threads_thread_is_alive(threadobject *t)
1204 state = cacaothread_get_state(t);
1207 case THREAD_STATE_NEW:
1208 case THREAD_STATE_TERMINATED:
1211 case THREAD_STATE_RUNNABLE:
1212 case THREAD_STATE_BLOCKED:
1213 case THREAD_STATE_WAITING:
1214 case THREAD_STATE_TIMED_WAITING:
1215 case THREAD_STATE_PARKED:
1216 case THREAD_STATE_TIMED_PARKED:
1220 vm_abort("threads_thread_is_alive: unknown thread state %d", state);
1223 /* keep compiler happy */
1228 /* thread_is_interrupted *******************************************************
1230 Check if the given thread has been interrupted.
1233 t ... the thread to check
1236 true, if the given thread had been interrupted
1238 *******************************************************************************/
1240 bool thread_is_interrupted(threadobject *t)
1242 /* We need the mutex because classpath will call this function when
1243 a blocking system call is interrupted. The mutex ensures that it will
1244 see the correct value for the interrupted flag. */
1246 t->waitmutex->lock();
1247 bool interrupted = t->interrupted;
1248 t->waitmutex->unlock();
1254 /* thread_set_interrupted ******************************************************
1256 Set the interrupted flag to the given value.
1259 interrupted ... value to set
1261 *******************************************************************************/
1263 void thread_set_interrupted(threadobject *t, bool interrupted)
1265 t->waitmutex->lock();
1266 t->interrupted = interrupted;
1267 t->waitmutex->unlock();
1273 * These are local overrides for various environment variables in Emacs.
1274 * Please do not remove this and leave it at the end of the file, where
1275 * Emacs will automagically detect them.
1276 * ---------------------------------------------------------------------
1279 * indent-tabs-mode: t
1283 * vim:noexpandtab:sw=4:ts=4: