1 /* src/threads/native/threads.c - native threads support
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: threads.c 8321 2007-08-16 11:37:25Z michi $
32 /* XXX cleanup these includes */
37 #include <sys/types.h>
50 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
51 # include "machine-instr.h"
53 # include "threads/native/generic-primitives.h"
56 #include "mm/gc-common.h"
57 #include "mm/memory.h"
59 #if defined(ENABLE_GC_CACAO)
60 # include "mm/cacao-gc/gc.h"
63 #include "native/jni.h"
64 #include "native/llni.h"
65 #include "native/native.h"
66 #include "native/include/java_lang_Object.h"
67 #include "native/include/java_lang_String.h"
68 #include "native/include/java_lang_Throwable.h"
69 #include "native/include/java_lang_Thread.h"
71 #if defined(ENABLE_JAVASE)
72 # include "native/include/java_lang_ThreadGroup.h"
75 #if defined(WITH_CLASSPATH_GNU)
76 # include "native/include/java_lang_VMThread.h"
79 #include "threads/lock-common.h"
80 #include "threads/threads-common.h"
82 #include "threads/native/threads.h"
84 #include "toolbox/logging.h"
86 #include "vm/builtin.h"
87 #include "vm/exceptions.h"
88 #include "vm/global.h"
89 #include "vm/stringlocal.h"
92 #include "vm/jit/asmpart.h"
94 #include "vmcore/options.h"
96 #if defined(ENABLE_STATISTICS)
97 # include "vmcore/statistics.h"
100 #if !defined(__DARWIN__)
101 # if defined(__LINUX__)
102 # define GC_LINUX_THREADS
103 # elif defined(__MIPS__)
104 # define GC_IRIX_THREADS
106 # include <semaphore.h>
107 # if defined(ENABLE_GC_BOEHM)
108 # include "mm/boehm-gc/include/gc.h"
112 #if defined(ENABLE_JVMTI)
113 #include "native/jvmti/cacaodbg.h"
116 #if defined(__DARWIN__)
117 /* Darwin has no working semaphore implementation. This one is taken
121 This is a very simple semaphore implementation for darwin. It
122 is implemented in terms of pthreads calls so it isn't async signal
123 safe. This isn't a problem because signals aren't used to
124 suspend threads on darwin.
127 static int sem_init(sem_t *sem, int pshared, int value)
134 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
137 if (pthread_cond_init(&sem->cond, NULL) < 0)
143 static int sem_post(sem_t *sem)
145 if (pthread_mutex_lock(&sem->mutex) < 0)
150 if (pthread_cond_signal(&sem->cond) < 0) {
151 pthread_mutex_unlock(&sem->mutex);
155 if (pthread_mutex_unlock(&sem->mutex) < 0)
161 static int sem_wait(sem_t *sem)
163 if (pthread_mutex_lock(&sem->mutex) < 0)
166 while (sem->value == 0) {
167 pthread_cond_wait(&sem->cond, &sem->mutex);
172 if (pthread_mutex_unlock(&sem->mutex) < 0)
178 static int sem_destroy(sem_t *sem)
180 if (pthread_cond_destroy(&sem->cond) < 0)
183 if (pthread_mutex_destroy(&sem->mutex) < 0)
188 #endif /* defined(__DARWIN__) */
191 /* internally used constants **************************************************/
193 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
194 #define STOPWORLD_FROM_GC 1
195 #define STOPWORLD_FROM_CLASS_NUMBERING 2
198 /* startupinfo *****************************************************************
200 Struct used to pass info from threads_start_thread to
201 threads_startup_thread.
203 ******************************************************************************/
206 threadobject *thread; /* threadobject for this thread */
207 functionptr function; /* function to run in the new thread */
208 sem_t *psem; /* signals when thread has been entered */
209 /* in the thread list */
210 sem_t *psem_first; /* signals when pthread_create has returned */
214 /* prototypes *****************************************************************/
216 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
219 /******************************************************************************/
220 /* GLOBAL VARIABLES */
221 /******************************************************************************/
223 static methodinfo *method_thread_init;
225 /* the thread object of the current thread */
226 /* This is either a thread-local variable defined with __thread, or */
227 /* a thread-specific value stored with key threads_current_threadobject_key. */
228 #if defined(HAVE___THREAD)
229 __thread threadobject *threads_current_threadobject;
231 pthread_key_t threads_current_threadobject_key;
234 /* global mutex for the threads table */
235 static pthread_mutex_t mutex_threads_list;
237 /* global mutex for stop-the-world */
238 static pthread_mutex_t stopworldlock;
240 /* global mutex and condition for joining threads on exit */
241 static pthread_mutex_t mutex_join;
242 static pthread_cond_t cond_join;
244 /* XXX We disable that whole bunch of code until we have the exact-GC
249 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
251 static volatile int stopworldwhere;
253 /* semaphore used for acknowleding thread suspension */
254 static sem_t suspend_ack;
255 #if defined(__MIPS__)
256 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
257 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
262 /* mutexes used by the fake atomic instructions */
263 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
264 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
265 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
266 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
270 /* threads_sem_init ************************************************************
272 Initialize a semaphore. Checks against errors and interruptions.
275 sem..............the semaphore to initialize
276 shared...........true if this semaphore will be shared between processes
277 value............the initial value for the semaphore
279 *******************************************************************************/
281 void threads_sem_init(sem_t *sem, bool shared, int value)
288 r = sem_init(sem, shared, value);
291 } while (errno == EINTR);
293 vm_abort("sem_init failed: %s", strerror(errno));
297 /* threads_sem_wait ************************************************************
299 Wait for a semaphore, non-interruptible.
301 IMPORTANT: Always use this function instead of `sem_wait` directly, as
302 `sem_wait` may be interrupted by signals!
305 sem..............the semaphore to wait on
307 *******************************************************************************/
309 void threads_sem_wait(sem_t *sem)
319 } while (errno == EINTR);
321 vm_abort("sem_wait failed: %s", strerror(errno));
325 /* threads_sem_post ************************************************************
327 Increase the count of a semaphore. Checks for errors.
330 sem..............the semaphore to increase the count of
332 *******************************************************************************/
334 void threads_sem_post(sem_t *sem)
340 /* unlike sem_wait, sem_post is not interruptible */
346 vm_abort("sem_post failed: %s", strerror(errno));
350 /* lock_stopworld **************************************************************
352 Enter the stopworld lock, specifying why the world shall be stopped.
355 where........ STOPWORLD_FROM_GC (1) from within GC
356 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
358 ******************************************************************************/
360 void lock_stopworld(int where)
362 pthread_mutex_lock(&stopworldlock);
363 /* stopworldwhere = where; */
367 /* unlock_stopworld ************************************************************
369 Release the stopworld lock.
371 ******************************************************************************/
373 void unlock_stopworld(void)
375 /* stopworldwhere = 0; */
376 pthread_mutex_unlock(&stopworldlock);
379 /* XXX We disable that whole bunch of code until we have the exact-GC
384 #if !defined(__DARWIN__)
385 /* Caller must hold threadlistlock */
386 static s4 threads_cast_sendsignals(s4 sig)
394 /* iterate over all started threads */
398 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
399 /* don't send the signal to ourself */
404 /* don't send the signal to NEW threads (because they are not
405 completely initialized) */
407 if (t->state == THREAD_STATE_NEW)
410 /* send the signal */
412 pthread_kill(t->tid, sig);
414 /* increase threads count */
424 static void threads_cast_darwinstop(void)
426 threadobject *tobj = mainthreadobj;
427 threadobject *self = THREADOBJECT;
432 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
433 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
434 #if defined(__I386__)
435 i386_thread_state_t thread_state;
437 ppc_thread_state_t thread_state;
439 mach_port_t thread = tobj->mach_thread;
442 r = thread_suspend(thread);
444 if (r != KERN_SUCCESS)
445 vm_abort("thread_suspend failed");
447 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
448 &thread_state_count);
450 if (r != KERN_SUCCESS)
451 vm_abort("thread_get_state failed");
453 md_critical_section_restart((ucontext_t *) &thread_state);
455 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
458 if (r != KERN_SUCCESS)
459 vm_abort("thread_set_state failed");
463 } while (tobj != mainthreadobj);
466 static void threads_cast_darwinresume(void)
468 threadobject *tobj = mainthreadobj;
469 threadobject *self = THREADOBJECT;
474 mach_port_t thread = tobj->mach_thread;
477 r = thread_resume(thread);
479 if (r != KERN_SUCCESS)
480 vm_abort("thread_resume failed");
484 } while (tobj != mainthreadobj);
489 #if defined(__MIPS__)
490 static void threads_cast_irixresume(void)
492 pthread_mutex_lock(&suspend_ack_lock);
493 pthread_cond_broadcast(&suspend_cond);
494 pthread_mutex_unlock(&suspend_ack_lock);
499 #if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
500 static void threads_sigsuspend_handler(ucontext_t *_uc)
505 /* XXX TWISTI: this is just a quick hack */
506 #if defined(ENABLE_JIT)
507 md_critical_section_restart(_uc);
510 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
511 (not POSIX async-safe). */
512 #if defined(__IRIX__)
513 pthread_mutex_lock(&suspend_ack_lock);
514 threads_sem_post(&suspend_ack);
515 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
516 pthread_mutex_unlock(&suspend_ack_lock);
517 #elif defined(__CYGWIN__)
524 sigdelset(&sigs, sig);
530 /* threads_stopworld ***********************************************************
532 Stops the world from turning. All threads except the calling one
533 are suspended. The function returns as soon as all threads have
534 acknowledged their suspension.
536 *******************************************************************************/
538 #if !defined(DISABLE_GC)
539 void threads_stopworld(void)
541 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
548 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
550 /* lock the threads lists */
554 #if defined(__DARWIN__)
555 threads_cast_darwinstop();
556 #elif defined(__CYGWIN__)
564 /* suspend all running threads */
565 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
566 /* don't send the signal to ourself */
571 /* don't send the signal to NEW threads (because they are not
572 completely initialized) */
574 if (t->state == THREAD_STATE_NEW)
577 /* send the signal */
579 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
582 /* increase threads count */
587 /* wait for all threads signaled to suspend */
588 for (i = 0; i < count; i++)
589 threads_sem_wait(&suspend_ack);
592 /* ATTENTION: Don't unlock the threads-lists here so that
593 non-signaled NEW threads can't change their state and execute
596 #endif /* !defined(DISABLE_GC) */
599 /* threads_startworld **********************************************************
601 Starts the world again after it has previously been stopped.
603 *******************************************************************************/
605 #if !defined(DISABLE_GC)
606 void threads_startworld(void)
608 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
615 #if defined(__DARWIN__)
616 threads_cast_darwinresume();
617 #elif defined(__MIPS__)
618 threads_cast_irixresume();
619 #elif defined(__CYGWIN__)
627 /* resume all thread we haltet */
628 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
629 /* don't send the signal to ourself */
634 /* don't send the signal to NEW threads (because they are not
635 completely initialized) */
637 if (t->state == THREAD_STATE_NEW)
640 /* send the signal */
642 result = threads_resume_thread(t);
645 /* increase threads count */
650 /* wait for all threads signaled to suspend */
651 for (i = 0; i < count; i++)
652 threads_sem_wait(&suspend_ack);
656 /* unlock the threads lists */
658 threads_list_unlock();
665 /* threads_set_current_threadobject ********************************************
667 Set the current thread object.
670 thread.......the thread object to set
672 *******************************************************************************/
674 void threads_set_current_threadobject(threadobject *thread)
676 #if !defined(HAVE___THREAD)
677 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
678 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
680 threads_current_threadobject = thread;
685 /* threads_impl_thread_new *****************************************************
687 Initialize implementation fields of a threadobject.
690 t....the threadobject
692 *******************************************************************************/
694 void threads_impl_thread_new(threadobject *t)
696 /* get the pthread id */
698 t->tid = pthread_self();
700 /* initialize the mutex and the condition */
702 pthread_mutex_init(&(t->waitmutex), NULL);
703 pthread_cond_init(&(t->waitcond), NULL);
704 pthread_mutex_init(&(t->suspendmutex), NULL);
705 pthread_cond_init(&(t->suspendcond), NULL);
707 #if defined(ENABLE_DEBUG_FILTER)
708 /* Initialize filter counters */
709 t->filterverbosecallctr[0] = 0;
710 t->filterverbosecallctr[1] = 0;
714 t->tracejavacallindent = 0;
715 t->tracejavacallcount = 0;
720 /* threads_impl_thread_free ****************************************************
722 Cleanup thread stuff.
725 t....the threadobject
727 *******************************************************************************/
729 void threads_impl_thread_free(threadobject *t)
731 /* destroy the mutex and the condition */
733 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
734 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
737 if (pthread_cond_destroy(&(t->waitcond)) != 0)
738 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
741 if (pthread_mutex_destroy(&(t->suspendmutex)) != 0)
742 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
745 if (pthread_cond_destroy(&(t->suspendcond)) != 0)
746 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
751 /* threads_get_current_threadobject ********************************************
753 Return the threadobject of the current thread.
756 the current threadobject *
758 *******************************************************************************/
760 threadobject *threads_get_current_threadobject(void)
766 /* threads_impl_preinit ********************************************************
768 Do some early initialization of stuff required.
770 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
771 is called AFTER this function!
773 *******************************************************************************/
775 void threads_impl_preinit(void)
777 pthread_mutex_init(&stopworldlock, NULL);
779 /* initialize exit mutex and condition (on exit we join all
782 pthread_mutex_init(&mutex_join, NULL);
783 pthread_cond_init(&cond_join, NULL);
785 /* initialize the threads-list mutex */
787 pthread_mutex_init(&mutex_threads_list, NULL);
789 #if !defined(HAVE___THREAD)
790 pthread_key_create(&threads_current_threadobject_key, NULL);
793 threads_sem_init(&suspend_ack, 0, 0);
797 /* threads_list_lock ***********************************************************
799 Enter the threads table mutex.
801 NOTE: We need this function as we can't use an internal lock for
802 the threads lists because the thread's lock is initialized in
803 threads_table_add (when we have the thread index), but we
804 already need the lock at the entry of the function.
806 *******************************************************************************/
808 void threads_list_lock(void)
810 if (pthread_mutex_lock(&mutex_threads_list) != 0)
811 vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
816 /* threads_list_unlock *********************************************************
818 Leave the threads list mutex.
820 *******************************************************************************/
822 void threads_list_unlock(void)
824 if (pthread_mutex_unlock(&mutex_threads_list) != 0)
825 vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
830 /* threads_mutex_join_lock *****************************************************
832 Enter the join mutex.
834 *******************************************************************************/
836 void threads_mutex_join_lock(void)
838 if (pthread_mutex_lock(&mutex_join) != 0)
839 vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
844 /* threads_mutex_join_unlock ***************************************************
846 Leave the join mutex.
848 *******************************************************************************/
850 void threads_mutex_join_unlock(void)
852 if (pthread_mutex_unlock(&mutex_join) != 0)
853 vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
858 /* threads_init ****************************************************************
860 Initializes the threads required by the JVM: main, finalizer.
862 *******************************************************************************/
864 bool threads_init(void)
866 threadobject *mainthread;
867 java_handle_t *threadname;
871 #if defined(ENABLE_JAVASE)
872 java_lang_ThreadGroup *threadgroup;
876 #if defined(WITH_CLASSPATH_GNU)
877 java_lang_VMThread *vmt;
882 /* get methods we need in this file */
884 #if defined(WITH_CLASSPATH_GNU)
886 class_resolveclassmethod(class_java_lang_Thread,
888 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
889 class_java_lang_Thread,
893 class_resolveclassmethod(class_java_lang_Thread,
895 utf_new_char("(Ljava/lang/String;)V"),
896 class_java_lang_Thread,
900 if (method_thread_init == NULL)
903 /* Get the main-thread (NOTE: The main threads is always the first
904 thread in the list). */
906 mainthread = threads_list_first();
908 #if defined(ENABLE_GC_CACAO)
909 /* register reference to java.lang.Thread with the GC */
911 gc_reference_register((java_objectheader **) &(mainthread->object));
914 /* create a java.lang.Thread for the main thread */
916 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
921 /* set the object in the internal data structure */
923 mainthread->object = t;
925 #if defined(ENABLE_INTRP)
926 /* create interpreter stack */
929 MSET(intrp_main_stack, 0, u1, opt_stacksize);
930 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
934 threadname = javastring_new(utf_new_char("main"));
936 #if defined(ENABLE_JAVASE)
937 /* allocate and init ThreadGroup */
939 threadgroup = (java_lang_ThreadGroup *)
940 native_new_and_init(class_java_lang_ThreadGroup);
942 if (threadgroup == NULL)
946 #if defined(WITH_CLASSPATH_GNU)
947 /* create a java.lang.VMThread for the main thread */
949 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
956 LLNI_field_set_ref(vmt, thread, t);
957 LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) mainthread);
959 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
960 o = (java_handle_t *) t;
962 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
965 #elif defined(WITH_CLASSPATH_SUN)
967 /* We trick java.lang.Thread.init, which sets the priority of the
968 current thread to the parent's one. */
970 t->priority = NORM_PRIORITY;
972 #elif defined(WITH_CLASSPATH_CLDC1_1)
976 t->vm_thread = (java_lang_Object *) mainthread;
978 /* call public Thread(String name) */
980 o = (java_handle_t *) t;
982 (void) vm_call_method(method_thread_init, o, threadname);
984 # error unknown classpath configuration
987 if (exceptions_get_exception())
990 #if defined(ENABLE_JAVASE)
991 LLNI_field_set_ref(t, group, threadgroup);
993 # if defined(WITH_CLASSPATH_GNU)
994 /* add main thread to java.lang.ThreadGroup */
996 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
998 utf_java_lang_Thread__V,
999 class_java_lang_ThreadGroup,
1002 o = (java_handle_t *) threadgroup;
1004 (void) vm_call_method(m, o, t);
1006 if (exceptions_get_exception())
1009 # warning Do not know what to do here
1013 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
1015 /* initialize the thread attribute object */
1017 if (pthread_attr_init(&attr) != 0)
1018 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
1020 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1021 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
1024 #if !defined(NDEBUG)
1025 if (opt_verbosethreads) {
1026 printf("[Starting thread ");
1027 threads_thread_print_info(mainthread);
1032 /* everything's ok */
1038 /* threads_startup_thread ******************************************************
1040 Thread startup function called by pthread_create.
1042 Thread which have a startup.function != NULL are marked as internal
1043 threads. All other threads are threated as normal Java threads.
1045 NOTE: This function is not called directly by pthread_create. The Boehm GC
1046 inserts its own GC_start_routine in between, which then calls
1050 arg..........the argument passed to pthread_create, ie. a pointer to
1051 a startupinfo struct. CAUTION: When the `psem` semaphore
1052 is posted, the startupinfo struct becomes invalid! (It
1053 is allocated on the stack of threads_start_thread.)
1055 ******************************************************************************/
1057 static void *threads_startup_thread(void *arg)
1059 startupinfo *startup;
1060 threadobject *thread;
1061 #if defined(WITH_CLASSPATH_GNU)
1062 java_lang_VMThread *vmt;
1068 functionptr function;
1070 #if defined(ENABLE_INTRP)
1071 u1 *intrp_thread_stack;
1073 /* create interpreter stack */
1076 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1077 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1080 intrp_thread_stack = NULL;
1083 /* get passed startupinfo structure and the values in there */
1087 thread = startup->thread;
1088 function = startup->function;
1089 psem = startup->psem;
1091 /* Seems like we've encountered a situation where thread->tid was
1092 not set by pthread_create. We alleviate this problem by waiting
1093 for pthread_create to return. */
1095 threads_sem_wait(startup->psem_first);
1097 #if defined(__DARWIN__)
1098 thread->mach_thread = mach_thread_self();
1101 /* store the internal thread data-structure in the TSD */
1103 threads_set_current_threadobject(thread);
1105 /* set our priority */
1107 threads_set_thread_priority(thread->tid, LLNI_field_direct(thread->object, priority));
1109 /* thread is completely initialized */
1111 threads_thread_state_runnable(thread);
1113 /* tell threads_startup_thread that we registered ourselves */
1114 /* CAUTION: *startup becomes invalid with this! */
1117 threads_sem_post(psem);
1119 #if defined(ENABLE_INTRP)
1120 /* set interpreter stack */
1123 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1126 #if defined(ENABLE_JVMTI)
1127 /* fire thread start event */
1130 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1133 #if !defined(NDEBUG)
1134 if (opt_verbosethreads) {
1135 printf("[Starting thread ");
1136 threads_thread_print_info(thread);
1141 /* find and run the Thread.run()V method if no other function was passed */
1143 if (function == NULL) {
1144 #if defined(WITH_CLASSPATH_GNU)
1145 /* We need to start the run method of
1146 java.lang.VMThread. Since this is a final class, we can use
1147 the class object directly. */
1149 c = class_java_lang_VMThread;
1150 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1151 c = thread->object->header.vftbl->class;
1153 # error unknown classpath configuration
1156 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1159 vm_abort("threads_startup_thread: run() method not found in class");
1161 /* set ThreadMXBean variables */
1163 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1164 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1166 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1167 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1168 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1169 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1171 #if defined(WITH_CLASSPATH_GNU)
1172 /* we need to start the run method of java.lang.VMThread */
1174 vmt = (java_lang_VMThread *) LLNI_field_direct(thread->object, vmThread);
1175 o = (java_handle_t *) vmt;
1177 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1178 o = (java_handle_t *) thread->object;
1180 # error unknown classpath configuration
1183 /* run the thread */
1185 (void) vm_call_method(m, o);
1188 /* set ThreadMXBean variables */
1190 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1191 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1193 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1194 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1195 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1196 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1198 /* call passed function, e.g. finalizer_thread */
1203 #if !defined(NDEBUG)
1204 if (opt_verbosethreads) {
1205 printf("[Stopping thread ");
1206 threads_thread_print_info(thread);
1211 #if defined(ENABLE_JVMTI)
1212 /* fire thread end event */
1215 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1218 if (!threads_detach_thread(thread))
1219 vm_abort("threads_startup_thread: threads_detach_thread failed");
1221 /* set ThreadMXBean variables */
1223 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1229 /* threads_impl_thread_start ***************************************************
1231 Start a thread in the JVM. Both (vm internal and java) thread
1235 thread....the thread object
1236 f.........function to run in the new thread. NULL means that the
1237 "run" method of the object `t` should be called
1239 ******************************************************************************/
1241 void threads_impl_thread_start(threadobject *thread, functionptr f)
1245 pthread_attr_t attr;
1246 startupinfo startup;
1249 /* fill startupinfo structure passed by pthread_create to
1250 * threads_startup_thread */
1252 startup.thread = thread;
1253 startup.function = f; /* maybe we don't call Thread.run()V */
1254 startup.psem = &sem;
1255 startup.psem_first = &sem_first;
1257 threads_sem_init(&sem, 0, 0);
1258 threads_sem_init(&sem_first, 0, 0);
1260 /* initialize thread attributes */
1262 if (pthread_attr_init(&attr) != 0)
1263 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1266 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1267 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1270 /* initialize thread stacksize */
1272 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1273 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1276 /* create the thread */
1278 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1280 /* destroy the thread attributes */
1282 if (pthread_attr_destroy(&attr) != 0)
1283 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1286 /* check for pthread_create error */
1289 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1292 /* signal that pthread_create has returned, so thread->tid is valid */
1294 threads_sem_post(&sem_first);
1296 /* wait here until the thread has entered itself into the thread list */
1298 threads_sem_wait(&sem);
1303 sem_destroy(&sem_first);
1307 /* threads_set_thread_priority *************************************************
1309 Set the priority of the given thread.
1312 tid..........thread id
1313 priority.....priority to set
1315 ******************************************************************************/
1317 void threads_set_thread_priority(pthread_t tid, int priority)
1319 struct sched_param schedp;
1322 pthread_getschedparam(tid, &policy, &schedp);
1323 schedp.sched_priority = priority;
1324 pthread_setschedparam(tid, policy, &schedp);
1328 /* threads_attach_current_thread ***********************************************
1330 Attaches the current thread to the VM. Used in JNI.
1332 *******************************************************************************/
1334 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1336 threadobject *thread;
1340 java_lang_Thread *t;
1342 #if defined(ENABLE_JAVASE)
1343 java_lang_ThreadGroup *group;
1344 threadobject *mainthread;
1349 #if defined(WITH_CLASSPATH_GNU)
1350 java_lang_VMThread *vmt;
1353 /* Enter the join-mutex, so if the main-thread is currently
1354 waiting to join all threads, the number of non-daemon threads
1357 threads_mutex_join_lock();
1359 /* create internal thread data-structure */
1361 thread = threads_thread_new();
1363 /* thread is a Java thread and running */
1365 thread->flags = THREAD_FLAG_JAVA;
1368 thread->flags |= THREAD_FLAG_DAEMON;
1370 /* The thread is flagged and (non-)daemon thread, we can leave the
1373 threads_mutex_join_unlock();
1375 /* create a java.lang.Thread object */
1377 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1379 /* XXX memory leak!!! */
1385 /* thread is completely initialized */
1387 threads_thread_state_runnable(thread);
1389 #if !defined(NDEBUG)
1390 if (opt_verbosethreads) {
1391 printf("[Attaching thread ");
1392 threads_thread_print_info(thread);
1397 #if defined(ENABLE_INTRP)
1398 /* create interpreter stack */
1401 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1402 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1406 #if defined(WITH_CLASSPATH_GNU)
1408 /* create a java.lang.VMThread object */
1410 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1412 /* XXX memory leak!!! */
1416 /* set the thread */
1418 LLNI_field_set_ref(vmt, thread, t);
1419 LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
1421 #elif defined(WITH_CLASSPATH_SUN)
1423 vm_abort("threads_attach_current_thread: IMPLEMENT ME!");
1425 #elif defined(WITH_CLASSPATH_CLDC1_1)
1427 LLNI_field_set_val(t, vm_thread, (java_lang_Object *) thread);
1430 # error unknown classpath configuration
1433 if (vm_aargs != NULL) {
1434 u = utf_new_char(vm_aargs->name);
1435 #if defined(ENABLE_JAVASE)
1436 group = (java_lang_ThreadGroup *) vm_aargs->group;
1441 #if defined(ENABLE_JAVASE)
1442 /* get the main thread */
1444 mainthread = threads_list_first();
1445 group = LLNI_field_direct(mainthread->object, group);
1449 /* the the thread name */
1451 s = javastring_new(u);
1453 /* for convenience */
1455 o = (java_handle_t *) thread->object;
1457 #if defined(WITH_CLASSPATH_GNU)
1458 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1460 #elif defined(WITH_CLASSPATH_CLDC1_1)
1461 (void) vm_call_method(method_thread_init, o, s);
1464 if (exceptions_get_exception())
1467 #if defined(ENABLE_JAVASE)
1468 /* store the thread group in the object */
1470 LLNI_field_direct(thread->object, group) = group;
1472 /* add thread to given thread-group */
1474 LLNI_class_get(group, c);
1476 m = class_resolveclassmethod(c,
1478 utf_java_lang_Thread__V,
1479 class_java_lang_ThreadGroup,
1482 o = (java_handle_t *) group;
1484 (void) vm_call_method(m, o, t);
1486 if (exceptions_get_exception())
1494 /* threads_detach_thread *******************************************************
1496 Detaches the passed thread from the VM. Used in JNI.
1498 *******************************************************************************/
1500 bool threads_detach_thread(threadobject *thread)
1502 #if defined(ENABLE_JAVASE)
1503 java_lang_ThreadGroup *group;
1507 java_lang_Thread *t;
1510 /* XXX implement uncaught exception stuff (like JamVM does) */
1512 #if defined(ENABLE_JAVASE)
1513 /* remove thread from the thread group */
1515 group = LLNI_field_direct(thread->object, group);
1517 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1519 if (group != NULL) {
1520 LLNI_class_get(group, c);
1522 # if defined(WITH_CLASSPATH_GNU)
1523 m = class_resolveclassmethod(c,
1525 utf_java_lang_Thread__V,
1526 class_java_lang_ThreadGroup,
1528 # elif defined(WITH_CLASSPATH_SUN)
1529 m = class_resolveclassmethod(c,
1531 utf_java_lang_Thread__V,
1532 class_java_lang_ThreadGroup,
1535 # error unknown classpath configuration
1541 o = (java_handle_t *) group;
1544 (void) vm_call_method(m, o, t);
1546 if (exceptions_get_exception())
1551 /* thread is terminated */
1553 threads_thread_state_terminated(thread);
1555 #if !defined(NDEBUG)
1556 if (opt_verbosethreads) {
1557 printf("[Detaching thread ");
1558 threads_thread_print_info(thread);
1563 /* Enter the join-mutex before calling threads_thread_free, so
1564 threads_join_all_threads gets the correct number of non-daemon
1567 threads_mutex_join_lock();
1569 /* free the vm internal thread object */
1571 threads_thread_free(thread);
1573 /* Signal that this thread has finished and leave the mutex. */
1575 pthread_cond_signal(&cond_join);
1576 threads_mutex_join_unlock();
1582 /* threads_suspend_thread ******************************************************
1584 Suspend the passed thread. Execution stops until the thread
1585 is explicitly resumend again.
1588 reason.....Reason for suspending this thread.
1590 *******************************************************************************/
1592 bool threads_suspend_thread(threadobject *thread, s4 reason)
1594 /* acquire the suspendmutex */
1595 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1596 vm_abort("threads_suspend_thread: pthread_mutex_lock failed: %s",
1599 if (thread->suspended) {
1600 pthread_mutex_unlock(&(thread->suspendmutex));
1604 /* set the reason for the suspension */
1605 thread->suspend_reason = reason;
1607 /* send the suspend signal to the thread */
1608 assert(thread != THREADOBJECT);
1609 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1610 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1613 /* REMEMBER: do not release the suspendmutex, this is done
1614 by the thread itself in threads_suspend_ack(). */
1620 /* threads_suspend_ack *********************************************************
1622 Acknowledges the suspension of the current thread.
1625 pc.....The PC where the thread suspended its execution.
1626 sp.....The SP before the thread suspended its execution.
1628 *******************************************************************************/
1630 void threads_suspend_ack(u1* pc, u1* sp)
1632 threadobject *thread;
1634 thread = THREADOBJECT;
1636 assert(thread->suspend_reason != 0);
1638 /* TODO: remember dump memory size */
1640 #if defined(ENABLE_GC_CACAO)
1641 /* inform the GC about the suspension */
1642 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1644 /* check if the GC wants to leave the thread running */
1645 if (!gc_suspend(thread, pc, sp)) {
1647 /* REMEMBER: we do not unlock the suspendmutex because the thread
1648 will suspend itself again at a later time */
1655 /* mark this thread as suspended and remember the PC */
1657 thread->suspended = true;
1659 /* if we are stopping the world, we should send a global ack */
1660 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1661 threads_sem_post(&suspend_ack);
1664 /* release the suspension mutex and wait till we are resumed */
1665 /*printf("thread down %p\n", thread);*/
1666 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1667 /*printf("thread up %p\n", thread);*/
1669 /* if we are stopping the world, we should send a global ack */
1670 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1671 threads_sem_post(&suspend_ack);
1674 /* TODO: free dump memory */
1676 /* release the suspendmutex */
1677 if (pthread_mutex_unlock(&(thread->suspendmutex)) != 0)
1678 vm_abort("threads_suspend_ack: pthread_mutex_unlock failed: %s",
1683 /* threads_resume_thread *******************************************************
1685 Resumes the execution of the passed thread.
1687 *******************************************************************************/
1689 bool threads_resume_thread(threadobject *thread)
1691 /* acquire the suspendmutex */
1692 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1693 vm_abort("threads_resume_ack: pthread_mutex_unlock failed: %s",
1696 if (!thread->suspended) {
1697 pthread_mutex_unlock(&(thread->suspendmutex));
1701 thread->suspended = false;
1703 /* tell everyone that the thread should resume */
1704 assert(thread != THREADOBJECT);
1705 pthread_cond_broadcast(&(thread->suspendcond));
1707 /* release the suspendmutex */
1708 pthread_mutex_unlock(&(thread->suspendmutex));
1714 /* threads_join_all_threads ****************************************************
1716 Join all non-daemon threads.
1718 *******************************************************************************/
1720 void threads_join_all_threads(void)
1724 /* get current thread */
1728 /* this thread is waiting for all non-daemon threads to exit */
1730 threads_thread_state_waiting(t);
1732 /* enter join mutex */
1734 threads_mutex_join_lock();
1736 /* Wait for condition as long as we have non-daemon threads. We
1737 compare against 1 because the current (main thread) is also a
1738 non-daemon thread. */
1740 while (threads_list_get_non_daemons() > 1)
1741 pthread_cond_wait(&cond_join, &mutex_join);
1743 /* leave join mutex */
1745 threads_mutex_join_unlock();
1749 /* threads_timespec_earlier ****************************************************
1751 Return true if timespec tv1 is earlier than timespec tv2.
1754 tv1..........first timespec
1755 tv2..........second timespec
1758 true, if the first timespec is earlier
1760 *******************************************************************************/
1762 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1763 const struct timespec *tv2)
1765 return (tv1->tv_sec < tv2->tv_sec)
1767 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1771 /* threads_current_time_is_earlier_than ****************************************
1773 Check if the current time is earlier than the given timespec.
1776 tv...........the timespec to compare against
1779 true, if the current time is earlier
1781 *******************************************************************************/
1783 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1785 struct timeval tvnow;
1786 struct timespec tsnow;
1788 /* get current time */
1790 if (gettimeofday(&tvnow, NULL) != 0)
1791 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1793 /* convert it to a timespec */
1795 tsnow.tv_sec = tvnow.tv_sec;
1796 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1798 /* compare current time with the given timespec */
1800 return threads_timespec_earlier(&tsnow, tv);
1804 /* threads_wait_with_timeout ***************************************************
1806 Wait until the given point in time on a monitor until either
1807 we are notified, we are interrupted, or the time is up.
1810 t............the current thread
1811 wakeupTime...absolute (latest) wakeup time
1812 If both tv_sec and tv_nsec are zero, this function
1813 waits for an unlimited amount of time.
1816 true.........if the wait has been interrupted,
1817 false........if the wait was ended by notification or timeout
1819 *******************************************************************************/
1821 static bool threads_wait_with_timeout(threadobject *thread,
1822 struct timespec *wakeupTime)
1824 bool wasinterrupted;
1826 /* acquire the waitmutex */
1828 pthread_mutex_lock(&thread->waitmutex);
1830 /* mark us as sleeping */
1832 thread->sleeping = true;
1834 /* wait on waitcond */
1836 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1838 while (!thread->interrupted && !thread->signaled
1839 && threads_current_time_is_earlier_than(wakeupTime))
1841 threads_thread_state_timed_waiting(thread);
1843 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1846 threads_thread_state_runnable(thread);
1851 while (!thread->interrupted && !thread->signaled) {
1852 threads_thread_state_waiting(thread);
1854 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1856 threads_thread_state_runnable(thread);
1860 /* check if we were interrupted */
1862 wasinterrupted = thread->interrupted;
1864 /* reset all flags */
1866 thread->interrupted = false;
1867 thread->signaled = false;
1868 thread->sleeping = false;
1870 /* release the waitmutex */
1872 pthread_mutex_unlock(&thread->waitmutex);
1874 return wasinterrupted;
1878 /* threads_wait_with_timeout_relative ******************************************
1880 Wait for the given maximum amount of time on a monitor until either
1881 we are notified, we are interrupted, or the time is up.
1884 t............the current thread
1885 millis.......milliseconds to wait
1886 nanos........nanoseconds to wait
1889 true.........if the wait has been interrupted,
1890 false........if the wait was ended by notification or timeout
1892 *******************************************************************************/
1894 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1897 struct timespec wakeupTime;
1899 /* calculate the the (latest) wakeup time */
1901 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1905 return threads_wait_with_timeout(thread, &wakeupTime);
1909 /* threads_calc_absolute_time **************************************************
1911 Calculate the absolute point in time a given number of ms and ns from now.
1914 millis............milliseconds from now
1915 nanos.............nanoseconds from now
1918 *tm...............receives the timespec of the absolute point in time
1920 *******************************************************************************/
1922 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1924 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1927 gettimeofday(&tv, NULL);
1928 tv.tv_sec += millis / 1000;
1930 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1931 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1932 tm->tv_nsec = nsec % 1000000000;
1941 /* threads_thread_interrupt ****************************************************
1943 Interrupt the given thread.
1945 The thread gets the "waitcond" signal and
1946 its interrupted flag is set to true.
1949 thread............the thread to interrupt
1951 *******************************************************************************/
1953 void threads_thread_interrupt(threadobject *thread)
1955 /* Signal the thread a "waitcond" and tell it that it has been
1958 pthread_mutex_lock(&thread->waitmutex);
1960 /* Interrupt blocking system call using a signal. */
1962 pthread_kill(thread->tid, SIGHUP);
1964 if (thread->sleeping)
1965 pthread_cond_signal(&thread->waitcond);
1967 thread->interrupted = true;
1969 pthread_mutex_unlock(&thread->waitmutex);
1973 /* threads_check_if_interrupted_and_reset **************************************
1975 Check if the current thread has been interrupted and reset the
1979 true, if the current thread had been interrupted
1981 *******************************************************************************/
1983 bool threads_check_if_interrupted_and_reset(void)
1985 threadobject *thread;
1988 thread = THREADOBJECT;
1990 /* get interrupted flag */
1992 intr = thread->interrupted;
1994 /* reset interrupted flag */
1996 thread->interrupted = false;
2002 /* threads_thread_has_been_interrupted *****************************************
2004 Check if the given thread has been interrupted
2007 t............the thread to check
2010 true, if the given thread had been interrupted
2012 *******************************************************************************/
2014 bool threads_thread_has_been_interrupted(threadobject *thread)
2016 return thread->interrupted;
2020 /* threads_sleep ***************************************************************
2022 Sleep the current thread for the specified amount of time.
2024 *******************************************************************************/
2026 void threads_sleep(s8 millis, s4 nanos)
2028 threadobject *thread;
2029 struct timespec wakeupTime;
2030 bool wasinterrupted;
2032 thread = THREADOBJECT;
2034 threads_calc_absolute_time(&wakeupTime, millis, nanos);
2036 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
2039 exceptions_throw_interruptedexception();
2043 /* threads_yield ***************************************************************
2045 Yield to the scheduler.
2047 *******************************************************************************/
2049 void threads_yield(void)
2056 * These are local overrides for various environment variables in Emacs.
2057 * Please do not remove this and leave it at the end of the file, where
2058 * Emacs will automagically detect them.
2059 * ---------------------------------------------------------------------
2062 * indent-tabs-mode: t
2066 * vim:noexpandtab:sw=4:ts=4: