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 8052 2007-06-10 13:44:33Z 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/native.h"
65 #include "native/include/java_lang_Object.h"
66 #include "native/include/java_lang_String.h"
67 #include "native/include/java_lang_Throwable.h"
68 #include "native/include/java_lang_Thread.h"
70 #if defined(ENABLE_JAVASE)
71 # include "native/include/java_lang_ThreadGroup.h"
74 #if defined(WITH_CLASSPATH_GNU)
75 # include "native/include/java_lang_VMThread.h"
78 #include "threads/lock-common.h"
79 #include "threads/threads-common.h"
81 #include "threads/native/threads.h"
83 #include "toolbox/logging.h"
85 #include "vm/builtin.h"
86 #include "vm/exceptions.h"
87 #include "vm/global.h"
88 #include "vm/stringlocal.h"
91 #include "vm/jit/asmpart.h"
93 #include "vmcore/options.h"
95 #if defined(ENABLE_STATISTICS)
96 # include "vmcore/statistics.h"
99 #if !defined(__DARWIN__)
100 # if defined(__LINUX__)
101 # define GC_LINUX_THREADS
102 # elif defined(__MIPS__)
103 # define GC_IRIX_THREADS
105 # include <semaphore.h>
106 # if defined(ENABLE_GC_BOEHM)
107 # include "mm/boehm-gc/include/gc.h"
111 #if defined(ENABLE_JVMTI)
112 #include "native/jvmti/cacaodbg.h"
115 #if defined(__DARWIN__)
116 /* Darwin has no working semaphore implementation. This one is taken
120 This is a very simple semaphore implementation for darwin. It
121 is implemented in terms of pthreads calls so it isn't async signal
122 safe. This isn't a problem because signals aren't used to
123 suspend threads on darwin.
126 static int sem_init(sem_t *sem, int pshared, int value)
133 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
136 if (pthread_cond_init(&sem->cond, NULL) < 0)
142 static int sem_post(sem_t *sem)
144 if (pthread_mutex_lock(&sem->mutex) < 0)
149 if (pthread_cond_signal(&sem->cond) < 0) {
150 pthread_mutex_unlock(&sem->mutex);
154 if (pthread_mutex_unlock(&sem->mutex) < 0)
160 static int sem_wait(sem_t *sem)
162 if (pthread_mutex_lock(&sem->mutex) < 0)
165 while (sem->value == 0) {
166 pthread_cond_wait(&sem->cond, &sem->mutex);
171 if (pthread_mutex_unlock(&sem->mutex) < 0)
177 static int sem_destroy(sem_t *sem)
179 if (pthread_cond_destroy(&sem->cond) < 0)
182 if (pthread_mutex_destroy(&sem->mutex) < 0)
187 #endif /* defined(__DARWIN__) */
190 /* internally used constants **************************************************/
192 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
193 #define STOPWORLD_FROM_GC 1
194 #define STOPWORLD_FROM_CLASS_NUMBERING 2
197 /* startupinfo *****************************************************************
199 Struct used to pass info from threads_start_thread to
200 threads_startup_thread.
202 ******************************************************************************/
205 threadobject *thread; /* threadobject for this thread */
206 functionptr function; /* function to run in the new thread */
207 sem_t *psem; /* signals when thread has been entered */
208 /* in the thread list */
209 sem_t *psem_first; /* signals when pthread_create has returned */
213 /* prototypes *****************************************************************/
215 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
218 /******************************************************************************/
219 /* GLOBAL VARIABLES */
220 /******************************************************************************/
222 static methodinfo *method_thread_init;
224 /* the thread object of the current thread */
225 /* This is either a thread-local variable defined with __thread, or */
226 /* a thread-specific value stored with key threads_current_threadobject_key. */
227 #if defined(HAVE___THREAD)
228 __thread threadobject *threads_current_threadobject;
230 pthread_key_t threads_current_threadobject_key;
233 /* global mutex for the threads table */
234 static pthread_mutex_t mutex_threads_list;
236 /* global mutex for stop-the-world */
237 static pthread_mutex_t stopworldlock;
239 /* global mutex and condition for joining threads on exit */
240 static pthread_mutex_t mutex_join;
241 static pthread_cond_t cond_join;
243 /* XXX We disable that whole bunch of code until we have the exact-GC
248 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
250 static volatile int stopworldwhere;
252 /* semaphore used for acknowleding thread suspension */
253 static sem_t suspend_ack;
254 #if defined(__MIPS__)
255 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
256 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
261 /* mutexes used by the fake atomic instructions */
262 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
263 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
264 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
265 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
269 /* threads_sem_init ************************************************************
271 Initialize a semaphore. Checks against errors and interruptions.
274 sem..............the semaphore to initialize
275 shared...........true if this semaphore will be shared between processes
276 value............the initial value for the semaphore
278 *******************************************************************************/
280 void threads_sem_init(sem_t *sem, bool shared, int value)
287 r = sem_init(sem, shared, value);
290 } while (errno == EINTR);
292 vm_abort("sem_init failed: %s", strerror(errno));
296 /* threads_sem_wait ************************************************************
298 Wait for a semaphore, non-interruptible.
300 IMPORTANT: Always use this function instead of `sem_wait` directly, as
301 `sem_wait` may be interrupted by signals!
304 sem..............the semaphore to wait on
306 *******************************************************************************/
308 void threads_sem_wait(sem_t *sem)
318 } while (errno == EINTR);
320 vm_abort("sem_wait failed: %s", strerror(errno));
324 /* threads_sem_post ************************************************************
326 Increase the count of a semaphore. Checks for errors.
329 sem..............the semaphore to increase the count of
331 *******************************************************************************/
333 void threads_sem_post(sem_t *sem)
339 /* unlike sem_wait, sem_post is not interruptible */
345 vm_abort("sem_post failed: %s", strerror(errno));
349 /* lock_stopworld **************************************************************
351 Enter the stopworld lock, specifying why the world shall be stopped.
354 where........ STOPWORLD_FROM_GC (1) from within GC
355 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
357 ******************************************************************************/
359 void lock_stopworld(int where)
361 pthread_mutex_lock(&stopworldlock);
362 /* stopworldwhere = where; */
366 /* unlock_stopworld ************************************************************
368 Release the stopworld lock.
370 ******************************************************************************/
372 void unlock_stopworld(void)
374 /* stopworldwhere = 0; */
375 pthread_mutex_unlock(&stopworldlock);
378 /* XXX We disable that whole bunch of code until we have the exact-GC
383 #if !defined(__DARWIN__)
384 /* Caller must hold threadlistlock */
385 static s4 threads_cast_sendsignals(s4 sig)
393 /* iterate over all started threads */
397 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
398 /* don't send the signal to ourself */
403 /* don't send the signal to NEW threads (because they are not
404 completely initialized) */
406 if (t->state == THREAD_STATE_NEW)
409 /* send the signal */
411 pthread_kill(t->tid, sig);
413 /* increase threads count */
423 static void threads_cast_darwinstop(void)
425 threadobject *tobj = mainthreadobj;
426 threadobject *self = THREADOBJECT;
431 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
432 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
433 #if defined(__I386__)
434 i386_thread_state_t thread_state;
436 ppc_thread_state_t thread_state;
438 mach_port_t thread = tobj->mach_thread;
441 r = thread_suspend(thread);
443 if (r != KERN_SUCCESS)
444 vm_abort("thread_suspend failed");
446 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
447 &thread_state_count);
449 if (r != KERN_SUCCESS)
450 vm_abort("thread_get_state failed");
452 md_critical_section_restart((ucontext_t *) &thread_state);
454 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
457 if (r != KERN_SUCCESS)
458 vm_abort("thread_set_state failed");
462 } while (tobj != mainthreadobj);
465 static void threads_cast_darwinresume(void)
467 threadobject *tobj = mainthreadobj;
468 threadobject *self = THREADOBJECT;
473 mach_port_t thread = tobj->mach_thread;
476 r = thread_resume(thread);
478 if (r != KERN_SUCCESS)
479 vm_abort("thread_resume failed");
483 } while (tobj != mainthreadobj);
488 #if defined(__MIPS__)
489 static void threads_cast_irixresume(void)
491 pthread_mutex_lock(&suspend_ack_lock);
492 pthread_cond_broadcast(&suspend_cond);
493 pthread_mutex_unlock(&suspend_ack_lock);
498 #if !defined(__DARWIN__)
499 static void threads_sigsuspend_handler(ucontext_t *_uc)
504 /* XXX TWISTI: this is just a quick hack */
505 #if defined(ENABLE_JIT)
506 md_critical_section_restart(_uc);
509 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
510 (not POSIX async-safe). */
511 #if defined(__IRIX__)
512 pthread_mutex_lock(&suspend_ack_lock);
513 threads_sem_post(&suspend_ack);
514 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
515 pthread_mutex_unlock(&suspend_ack_lock);
516 #elif defined(__CYGWIN__)
523 sigdelset(&sigs, sig);
529 /* threads_stopworld ***********************************************************
531 Stops the world from turning. All threads except the calling one
532 are suspended. The function returns as soon as all threads have
533 acknowledged their suspension.
535 *******************************************************************************/
537 #if !defined(DISABLE_GC)
538 void threads_stopworld(void)
540 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
547 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
549 /* lock the threads lists */
553 #if defined(__DARWIN__)
554 threads_cast_darwinstop();
555 #elif defined(__CYGWIN__)
563 /* suspend all running threads */
564 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
565 /* don't send the signal to ourself */
570 /* don't send the signal to NEW threads (because they are not
571 completely initialized) */
573 if (t->state == THREAD_STATE_NEW)
576 /* send the signal */
578 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
581 /* increase threads count */
586 /* wait for all threads signaled to suspend */
587 for (i = 0; i < count; i++)
588 threads_sem_wait(&suspend_ack);
591 /* ATTENTION: Don't unlock the threads-lists here so that
592 non-signaled NEW threads can't change their state and execute
595 #endif /* !defined(DISABLE_GC) */
598 /* threads_startworld **********************************************************
600 Starts the world again after it has previously been stopped.
602 *******************************************************************************/
604 #if !defined(DISABLE_GC)
605 void threads_startworld(void)
607 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
614 #if defined(__DARWIN__)
615 threads_cast_darwinresume();
616 #elif defined(__MIPS__)
617 threads_cast_irixresume();
618 #elif defined(__CYGWIN__)
626 /* resume all thread we haltet */
627 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
628 /* don't send the signal to ourself */
633 /* don't send the signal to NEW threads (because they are not
634 completely initialized) */
636 if (t->state == THREAD_STATE_NEW)
639 /* send the signal */
641 result = threads_resume_thread(t);
644 /* increase threads count */
649 /* wait for all threads signaled to suspend */
650 for (i = 0; i < count; i++)
651 threads_sem_wait(&suspend_ack);
655 /* unlock the threads lists */
657 threads_list_unlock();
664 /* threads_set_current_threadobject ********************************************
666 Set the current thread object.
669 thread.......the thread object to set
671 *******************************************************************************/
673 void threads_set_current_threadobject(threadobject *thread)
675 #if !defined(HAVE___THREAD)
676 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
677 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
679 threads_current_threadobject = thread;
684 /* threads_impl_thread_new *****************************************************
686 Initialize implementation fields of a threadobject.
689 t....the threadobject
691 *******************************************************************************/
693 void threads_impl_thread_new(threadobject *t)
695 /* get the pthread id */
697 t->tid = pthread_self();
699 /* initialize the mutex and the condition */
701 pthread_mutex_init(&(t->waitmutex), NULL);
702 pthread_cond_init(&(t->waitcond), NULL);
703 pthread_mutex_init(&(t->suspendmutex), NULL);
704 pthread_cond_init(&(t->suspendcond), NULL);
706 #if defined(ENABLE_DEBUG_FILTER)
707 /* Initialize filter counters */
708 t->filterverbosecallctr[0] = 0;
709 t->filterverbosecallctr[1] = 0;
714 /* threads_impl_thread_free ****************************************************
716 Cleanup thread stuff.
719 t....the threadobject
721 *******************************************************************************/
723 void threads_impl_thread_free(threadobject *t)
725 /* destroy the mutex and the condition */
727 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
728 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
731 if (pthread_cond_destroy(&(t->waitcond)) != 0)
732 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
735 if (pthread_mutex_destroy(&(t->suspendmutex)) != 0)
736 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
739 if (pthread_cond_destroy(&(t->suspendcond)) != 0)
740 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
745 /* threads_get_current_threadobject ********************************************
747 Return the threadobject of the current thread.
750 the current threadobject *
752 *******************************************************************************/
754 threadobject *threads_get_current_threadobject(void)
760 /* threads_impl_preinit ********************************************************
762 Do some early initialization of stuff required.
764 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
765 is called AFTER this function!
767 *******************************************************************************/
769 void threads_impl_preinit(void)
771 pthread_mutex_init(&stopworldlock, NULL);
773 /* initialize exit mutex and condition (on exit we join all
776 pthread_mutex_init(&mutex_join, NULL);
777 pthread_cond_init(&cond_join, NULL);
779 /* initialize the threads-list mutex */
781 pthread_mutex_init(&mutex_threads_list, NULL);
783 #if !defined(HAVE___THREAD)
784 pthread_key_create(&threads_current_threadobject_key, NULL);
787 threads_sem_init(&suspend_ack, 0, 0);
791 /* threads_list_lock ***********************************************************
793 Enter the threads table mutex.
795 NOTE: We need this function as we can't use an internal lock for
796 the threads lists because the thread's lock is initialized in
797 threads_table_add (when we have the thread index), but we
798 already need the lock at the entry of the function.
800 *******************************************************************************/
802 void threads_list_lock(void)
804 if (pthread_mutex_lock(&mutex_threads_list) != 0)
805 vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
810 /* threads_list_unlock *********************************************************
812 Leave the threads list mutex.
814 *******************************************************************************/
816 void threads_list_unlock(void)
818 if (pthread_mutex_unlock(&mutex_threads_list) != 0)
819 vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
824 /* threads_mutex_join_lock *****************************************************
826 Enter the join mutex.
828 *******************************************************************************/
830 void threads_mutex_join_lock(void)
832 if (pthread_mutex_lock(&mutex_join) != 0)
833 vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
838 /* threads_mutex_join_unlock ***************************************************
840 Leave the join mutex.
842 *******************************************************************************/
844 void threads_mutex_join_unlock(void)
846 if (pthread_mutex_unlock(&mutex_join) != 0)
847 vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
852 /* threads_init ****************************************************************
854 Initializes the threads required by the JVM: main, finalizer.
856 *******************************************************************************/
858 bool threads_init(void)
860 threadobject *mainthread;
861 java_objectheader *threadname;
863 java_objectheader *o;
865 #if defined(ENABLE_JAVASE)
866 java_lang_ThreadGroup *threadgroup;
870 #if defined(WITH_CLASSPATH_GNU)
871 java_lang_VMThread *vmt;
876 /* get methods we need in this file */
878 #if defined(WITH_CLASSPATH_GNU)
880 class_resolveclassmethod(class_java_lang_Thread,
882 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
883 class_java_lang_Thread,
887 class_resolveclassmethod(class_java_lang_Thread,
889 utf_new_char("(Ljava/lang/String;)V"),
890 class_java_lang_Thread,
894 if (method_thread_init == NULL)
897 /* Get the main-thread (NOTE: The main threads is always the first
898 thread in the list). */
900 mainthread = threads_list_first();
902 #if defined(ENABLE_GC_CACAO)
903 /* register reference to java.lang.Thread with the GC */
905 gc_reference_register((java_objectheader **) &(mainthread->object));
908 /* create a java.lang.Thread for the main thread */
910 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
915 /* set the object in the internal data structure */
917 mainthread->object = t;
919 #if defined(ENABLE_INTRP)
920 /* create interpreter stack */
923 MSET(intrp_main_stack, 0, u1, opt_stacksize);
924 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
928 threadname = javastring_new(utf_new_char("main"));
930 #if defined(ENABLE_JAVASE)
931 /* allocate and init ThreadGroup */
933 threadgroup = (java_lang_ThreadGroup *)
934 native_new_and_init(class_java_lang_ThreadGroup);
936 if (threadgroup == NULL)
940 #if defined(WITH_CLASSPATH_GNU)
941 /* create a java.lang.VMThread for the main thread */
943 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
951 vmt->vmdata = (java_lang_Object *) mainthread;
953 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
954 o = (java_objectheader *) t;
956 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
958 #elif defined(WITH_CLASSPATH_CLDC1_1)
961 t->vm_thread = (java_lang_Object *) mainthread;
963 /* call public Thread(String name) */
965 o = (java_objectheader *) t;
967 (void) vm_call_method(method_thread_init, o, threadname);
973 #if defined(ENABLE_JAVASE)
974 t->group = threadgroup;
976 /* add main thread to java.lang.ThreadGroup */
978 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
980 utf_java_lang_Thread__V,
981 class_java_lang_ThreadGroup,
984 o = (java_objectheader *) threadgroup;
986 (void) vm_call_method(m, o, t);
992 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
994 /* initialize the thread attribute object */
996 if (pthread_attr_init(&attr) != 0)
997 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
999 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1000 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
1003 #if !defined(NDEBUG)
1004 if (opt_verbosethreads) {
1005 printf("[Starting thread ");
1006 threads_thread_print_info(mainthread);
1011 /* everything's ok */
1017 /* threads_startup_thread ******************************************************
1019 Thread startup function called by pthread_create.
1021 Thread which have a startup.function != NULL are marked as internal
1022 threads. All other threads are threated as normal Java threads.
1024 NOTE: This function is not called directly by pthread_create. The Boehm GC
1025 inserts its own GC_start_routine in between, which then calls
1029 arg..........the argument passed to pthread_create, ie. a pointer to
1030 a startupinfo struct. CAUTION: When the `psem` semaphore
1031 is posted, the startupinfo struct becomes invalid! (It
1032 is allocated on the stack of threads_start_thread.)
1034 ******************************************************************************/
1036 static void *threads_startup_thread(void *arg)
1038 startupinfo *startup;
1039 threadobject *thread;
1040 #if defined(WITH_CLASSPATH_GNU)
1041 java_lang_VMThread *vmt;
1046 java_objectheader *o;
1047 functionptr function;
1049 #if defined(ENABLE_INTRP)
1050 u1 *intrp_thread_stack;
1052 /* create interpreter stack */
1055 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1056 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1059 intrp_thread_stack = NULL;
1062 /* get passed startupinfo structure and the values in there */
1066 thread = startup->thread;
1067 function = startup->function;
1068 psem = startup->psem;
1070 /* Seems like we've encountered a situation where thread->tid was
1071 not set by pthread_create. We alleviate this problem by waiting
1072 for pthread_create to return. */
1074 threads_sem_wait(startup->psem_first);
1076 #if defined(__DARWIN__)
1077 thread->mach_thread = mach_thread_self();
1080 /* store the internal thread data-structure in the TSD */
1082 threads_set_current_threadobject(thread);
1084 /* set our priority */
1086 threads_set_thread_priority(thread->tid, thread->object->priority);
1088 /* thread is completely initialized */
1090 threads_thread_state_runnable(thread);
1092 /* tell threads_startup_thread that we registered ourselves */
1093 /* CAUTION: *startup becomes invalid with this! */
1096 threads_sem_post(psem);
1098 #if defined(ENABLE_INTRP)
1099 /* set interpreter stack */
1102 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1105 #if defined(ENABLE_JVMTI)
1106 /* fire thread start event */
1109 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1112 #if !defined(NDEBUG)
1113 if (opt_verbosethreads) {
1114 printf("[Starting thread ");
1115 threads_thread_print_info(thread);
1120 /* find and run the Thread.run()V method if no other function was passed */
1122 if (function == NULL) {
1123 #if defined(WITH_CLASSPATH_GNU)
1124 /* We need to start the run method of
1125 java.lang.VMThread. Since this is a final class, we can use
1126 the class object directly. */
1128 c = class_java_lang_VMThread;
1129 #elif defined(WITH_CLASSPATH_CLDC1_1)
1130 c = thread->object->header.vftbl->class;
1133 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1136 vm_abort("threads_startup_thread: run() method not found in class");
1138 /* set ThreadMXBean variables */
1140 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1141 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1143 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1144 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1145 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1146 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1148 #if defined(WITH_CLASSPATH_GNU)
1149 /* we need to start the run method of java.lang.VMThread */
1151 vmt = (java_lang_VMThread *) thread->object->vmThread;
1152 o = (java_objectheader *) vmt;
1154 #elif defined(WITH_CLASSPATH_CLDC1_1)
1155 o = (java_objectheader *) thread->object;
1158 /* run the thread */
1160 (void) vm_call_method(m, o);
1163 /* set ThreadMXBean variables */
1165 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1166 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1168 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1169 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1170 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1171 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1173 /* call passed function, e.g. finalizer_thread */
1178 #if !defined(NDEBUG)
1179 if (opt_verbosethreads) {
1180 printf("[Stopping thread ");
1181 threads_thread_print_info(thread);
1186 #if defined(ENABLE_JVMTI)
1187 /* fire thread end event */
1190 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1193 if (!threads_detach_thread(thread))
1194 vm_abort("threads_startup_thread: threads_detach_thread failed");
1196 /* set ThreadMXBean variables */
1198 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1204 /* threads_impl_thread_start ***************************************************
1206 Start a thread in the JVM. Both (vm internal and java) thread
1210 thread....the thread object
1211 f.........function to run in the new thread. NULL means that the
1212 "run" method of the object `t` should be called
1214 ******************************************************************************/
1216 void threads_impl_thread_start(threadobject *thread, functionptr f)
1220 pthread_attr_t attr;
1221 startupinfo startup;
1224 /* fill startupinfo structure passed by pthread_create to
1225 * threads_startup_thread */
1227 startup.thread = thread;
1228 startup.function = f; /* maybe we don't call Thread.run()V */
1229 startup.psem = &sem;
1230 startup.psem_first = &sem_first;
1232 threads_sem_init(&sem, 0, 0);
1233 threads_sem_init(&sem_first, 0, 0);
1235 /* initialize thread attributes */
1237 if (pthread_attr_init(&attr) != 0)
1238 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1241 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1242 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1245 /* initialize thread stacksize */
1247 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1248 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1251 /* create the thread */
1253 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1255 /* destroy the thread attributes */
1257 if (pthread_attr_destroy(&attr) != 0)
1258 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1261 /* check for pthread_create error */
1264 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1267 /* signal that pthread_create has returned, so thread->tid is valid */
1269 threads_sem_post(&sem_first);
1271 /* wait here until the thread has entered itself into the thread list */
1273 threads_sem_wait(&sem);
1278 sem_destroy(&sem_first);
1282 /* threads_set_thread_priority *************************************************
1284 Set the priority of the given thread.
1287 tid..........thread id
1288 priority.....priority to set
1290 ******************************************************************************/
1292 void threads_set_thread_priority(pthread_t tid, int priority)
1294 struct sched_param schedp;
1297 pthread_getschedparam(tid, &policy, &schedp);
1298 schedp.sched_priority = priority;
1299 pthread_setschedparam(tid, policy, &schedp);
1303 /* threads_attach_current_thread ***********************************************
1305 Attaches the current thread to the VM. Used in JNI.
1307 *******************************************************************************/
1309 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1311 threadobject *thread;
1313 java_objectheader *s;
1314 java_objectheader *o;
1315 java_lang_Thread *t;
1317 #if defined(ENABLE_JAVASE)
1318 java_lang_ThreadGroup *group;
1319 threadobject *mainthread;
1323 #if defined(WITH_CLASSPATH_GNU)
1324 java_lang_VMThread *vmt;
1327 /* Enter the join-mutex, so if the main-thread is currently
1328 waiting to join all threads, the number of non-daemon threads
1331 threads_mutex_join_lock();
1333 /* create internal thread data-structure */
1335 thread = threads_thread_new();
1337 /* thread is a Java thread and running */
1339 thread->flags = THREAD_FLAG_JAVA;
1342 thread->flags |= THREAD_FLAG_DAEMON;
1344 /* The thread is flagged and (non-)daemon thread, we can leave the
1347 threads_mutex_join_unlock();
1349 /* create a java.lang.Thread object */
1351 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1353 /* XXX memory leak!!! */
1359 /* thread is completely initialized */
1361 threads_thread_state_runnable(thread);
1363 #if !defined(NDEBUG)
1364 if (opt_verbosethreads) {
1365 printf("[Attaching thread ");
1366 threads_thread_print_info(thread);
1371 #if defined(ENABLE_INTRP)
1372 /* create interpreter stack */
1375 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1376 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1380 #if defined(WITH_CLASSPATH_GNU)
1381 /* create a java.lang.VMThread object */
1383 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1385 /* XXX memory leak!!! */
1389 /* set the thread */
1392 vmt->vmdata = (java_lang_Object *) thread;
1393 #elif defined(WITH_CLASSPATH_CLDC1_1)
1394 t->vm_thread = (java_lang_Object *) thread;
1397 if (vm_aargs != NULL) {
1398 u = utf_new_char(vm_aargs->name);
1399 #if defined(ENABLE_JAVASE)
1400 group = (java_lang_ThreadGroup *) vm_aargs->group;
1405 #if defined(ENABLE_JAVASE)
1406 /* get the main thread */
1408 mainthread = threads_list_first();
1409 group = mainthread->object->group;
1413 /* the the thread name */
1415 s = javastring_new(u);
1417 /* for convenience */
1419 o = (java_objectheader *) thread->object;
1421 #if defined(WITH_CLASSPATH_GNU)
1422 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1424 #elif defined(WITH_CLASSPATH_CLDC1_1)
1425 (void) vm_call_method(method_thread_init, o, s);
1431 #if defined(ENABLE_JAVASE)
1432 /* store the thread group in the object */
1434 thread->object->group = group;
1436 /* add thread to given thread-group */
1438 m = class_resolveclassmethod(group->header.vftbl->class,
1440 utf_java_lang_Thread__V,
1441 class_java_lang_ThreadGroup,
1444 o = (java_objectheader *) group;
1446 (void) vm_call_method(m, o, t);
1456 /* threads_detach_thread *******************************************************
1458 Detaches the passed thread from the VM. Used in JNI.
1460 *******************************************************************************/
1462 bool threads_detach_thread(threadobject *thread)
1464 #if defined(ENABLE_JAVASE)
1465 java_lang_ThreadGroup *group;
1467 java_objectheader *o;
1468 java_lang_Thread *t;
1471 /* XXX implement uncaught exception stuff (like JamVM does) */
1473 #if defined(ENABLE_JAVASE)
1474 /* remove thread from the thread group */
1476 group = thread->object->group;
1478 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1480 if (group != NULL) {
1481 m = class_resolveclassmethod(group->header.vftbl->class,
1483 utf_java_lang_Thread__V,
1484 class_java_lang_ThreadGroup,
1490 o = (java_objectheader *) group;
1493 (void) vm_call_method(m, o, t);
1500 /* thread is terminated */
1502 threads_thread_state_terminated(thread);
1504 #if !defined(NDEBUG)
1505 if (opt_verbosethreads) {
1506 printf("[Detaching thread ");
1507 threads_thread_print_info(thread);
1512 /* Enter the join-mutex before calling threads_thread_free, so
1513 threads_join_all_threads gets the correct number of non-daemon
1516 threads_mutex_join_lock();
1518 /* free the vm internal thread object */
1520 threads_thread_free(thread);
1522 /* Signal that this thread has finished and leave the mutex. */
1524 pthread_cond_signal(&cond_join);
1525 threads_mutex_join_unlock();
1531 /* threads_suspend_thread ******************************************************
1533 Suspend the passed thread. Execution stops until the thread
1534 is explicitly resumend again.
1537 reason.....Reason for suspending this thread.
1539 *******************************************************************************/
1541 bool threads_suspend_thread(threadobject *thread, s4 reason)
1543 /* acquire the suspendmutex */
1544 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1545 vm_abort("threads_suspend_thread: pthread_mutex_lock failed: %s",
1548 if (thread->suspended) {
1549 pthread_mutex_unlock(&(thread->suspendmutex));
1553 /* set the reason for the suspension */
1554 thread->suspend_reason = reason;
1556 /* send the suspend signal to the thread */
1557 assert(thread != THREADOBJECT);
1558 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1559 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1562 /* REMEMBER: do not release the suspendmutex, this is done
1563 by the thread itself in threads_suspend_ack(). */
1569 /* threads_suspend_ack *********************************************************
1571 Acknowledges the suspension of the current thread.
1574 pc.....The PC where the thread suspended its execution.
1575 sp.....The SP before the thread suspended its execution.
1577 *******************************************************************************/
1579 void threads_suspend_ack(u1* pc, u1* sp)
1581 threadobject *thread;
1583 thread = THREADOBJECT;
1585 assert(thread->suspend_reason != 0);
1587 /* TODO: remember dump memory size */
1589 #if defined(ENABLE_GC_CACAO)
1590 /* inform the GC about the suspension */
1591 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1593 /* check if the GC wants to leave the thread running */
1594 if (!gc_suspend(thread, pc, sp)) {
1596 /* REMEMBER: we do not unlock the suspendmutex because the thread
1597 will suspend itself again at a later time */
1604 /* mark this thread as suspended and remember the PC */
1606 thread->suspended = true;
1608 /* if we are stopping the world, we should send a global ack */
1609 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1610 threads_sem_post(&suspend_ack);
1613 /* release the suspension mutex and wait till we are resumed */
1614 /*printf("thread down %p\n", thread);*/
1615 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1616 /*printf("thread up %p\n", thread);*/
1618 /* if we are stopping the world, we should send a global ack */
1619 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1620 threads_sem_post(&suspend_ack);
1623 /* TODO: free dump memory */
1625 /* release the suspendmutex */
1626 if (pthread_mutex_unlock(&(thread->suspendmutex)) != 0)
1627 vm_abort("threads_suspend_ack: pthread_mutex_unlock failed: %s",
1632 /* threads_resume_thread *******************************************************
1634 Resumes the execution of the passed thread.
1636 *******************************************************************************/
1638 bool threads_resume_thread(threadobject *thread)
1640 /* acquire the suspendmutex */
1641 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1642 vm_abort("threads_resume_ack: pthread_mutex_unlock failed: %s",
1645 if (!thread->suspended) {
1646 pthread_mutex_unlock(&(thread->suspendmutex));
1650 thread->suspended = false;
1652 /* tell everyone that the thread should resume */
1653 assert(thread != THREADOBJECT);
1654 pthread_cond_broadcast(&(thread->suspendcond));
1656 /* release the suspendmutex */
1657 pthread_mutex_unlock(&(thread->suspendmutex));
1663 /* threads_join_all_threads ****************************************************
1665 Join all non-daemon threads.
1667 *******************************************************************************/
1669 void threads_join_all_threads(void)
1673 /* get current thread */
1677 /* this thread is waiting for all non-daemon threads to exit */
1679 threads_thread_state_waiting(t);
1681 /* enter join mutex */
1683 threads_mutex_join_lock();
1685 /* Wait for condition as long as we have non-daemon threads. We
1686 compare against 1 because the current (main thread) is also a
1687 non-daemon thread. */
1689 while (threads_list_get_non_daemons() > 1)
1690 pthread_cond_wait(&cond_join, &mutex_join);
1692 /* leave join mutex */
1694 threads_mutex_join_unlock();
1698 /* threads_timespec_earlier ****************************************************
1700 Return true if timespec tv1 is earlier than timespec tv2.
1703 tv1..........first timespec
1704 tv2..........second timespec
1707 true, if the first timespec is earlier
1709 *******************************************************************************/
1711 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1712 const struct timespec *tv2)
1714 return (tv1->tv_sec < tv2->tv_sec)
1716 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1720 /* threads_current_time_is_earlier_than ****************************************
1722 Check if the current time is earlier than the given timespec.
1725 tv...........the timespec to compare against
1728 true, if the current time is earlier
1730 *******************************************************************************/
1732 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1734 struct timeval tvnow;
1735 struct timespec tsnow;
1737 /* get current time */
1739 if (gettimeofday(&tvnow, NULL) != 0)
1740 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1742 /* convert it to a timespec */
1744 tsnow.tv_sec = tvnow.tv_sec;
1745 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1747 /* compare current time with the given timespec */
1749 return threads_timespec_earlier(&tsnow, tv);
1753 /* threads_wait_with_timeout ***************************************************
1755 Wait until the given point in time on a monitor until either
1756 we are notified, we are interrupted, or the time is up.
1759 t............the current thread
1760 wakeupTime...absolute (latest) wakeup time
1761 If both tv_sec and tv_nsec are zero, this function
1762 waits for an unlimited amount of time.
1765 true.........if the wait has been interrupted,
1766 false........if the wait was ended by notification or timeout
1768 *******************************************************************************/
1770 static bool threads_wait_with_timeout(threadobject *thread,
1771 struct timespec *wakeupTime)
1773 bool wasinterrupted;
1775 /* acquire the waitmutex */
1777 pthread_mutex_lock(&thread->waitmutex);
1779 /* mark us as sleeping */
1781 thread->sleeping = true;
1783 /* wait on waitcond */
1785 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1787 while (!thread->interrupted && !thread->signaled
1788 && threads_current_time_is_earlier_than(wakeupTime))
1790 threads_thread_state_timed_waiting(thread);
1792 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1795 threads_thread_state_runnable(thread);
1800 while (!thread->interrupted && !thread->signaled) {
1801 threads_thread_state_waiting(thread);
1803 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1805 threads_thread_state_runnable(thread);
1809 /* check if we were interrupted */
1811 wasinterrupted = thread->interrupted;
1813 /* reset all flags */
1815 thread->interrupted = false;
1816 thread->signaled = false;
1817 thread->sleeping = false;
1819 /* release the waitmutex */
1821 pthread_mutex_unlock(&thread->waitmutex);
1823 return wasinterrupted;
1827 /* threads_wait_with_timeout_relative ******************************************
1829 Wait for the given maximum amount of time on a monitor until either
1830 we are notified, we are interrupted, or the time is up.
1833 t............the current thread
1834 millis.......milliseconds to wait
1835 nanos........nanoseconds to wait
1838 true.........if the wait has been interrupted,
1839 false........if the wait was ended by notification or timeout
1841 *******************************************************************************/
1843 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1846 struct timespec wakeupTime;
1848 /* calculate the the (latest) wakeup time */
1850 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1854 return threads_wait_with_timeout(thread, &wakeupTime);
1858 /* threads_calc_absolute_time **************************************************
1860 Calculate the absolute point in time a given number of ms and ns from now.
1863 millis............milliseconds from now
1864 nanos.............nanoseconds from now
1867 *tm...............receives the timespec of the absolute point in time
1869 *******************************************************************************/
1871 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1873 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1876 gettimeofday(&tv, NULL);
1877 tv.tv_sec += millis / 1000;
1879 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1880 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1881 tm->tv_nsec = nsec % 1000000000;
1890 /* threads_thread_interrupt ****************************************************
1892 Interrupt the given thread.
1894 The thread gets the "waitcond" signal and
1895 its interrupted flag is set to true.
1898 thread............the thread to interrupt
1900 *******************************************************************************/
1902 void threads_thread_interrupt(threadobject *thread)
1904 /* Signal the thread a "waitcond" and tell it that it has been
1907 pthread_mutex_lock(&thread->waitmutex);
1909 /* Interrupt blocking system call using a signal. */
1911 pthread_kill(thread->tid, SIGHUP);
1913 if (thread->sleeping)
1914 pthread_cond_signal(&thread->waitcond);
1916 thread->interrupted = true;
1918 pthread_mutex_unlock(&thread->waitmutex);
1922 /* threads_check_if_interrupted_and_reset **************************************
1924 Check if the current thread has been interrupted and reset the
1928 true, if the current thread had been interrupted
1930 *******************************************************************************/
1932 bool threads_check_if_interrupted_and_reset(void)
1934 threadobject *thread;
1937 thread = THREADOBJECT;
1939 /* get interrupted flag */
1941 intr = thread->interrupted;
1943 /* reset interrupted flag */
1945 thread->interrupted = false;
1951 /* threads_thread_has_been_interrupted *****************************************
1953 Check if the given thread has been interrupted
1956 t............the thread to check
1959 true, if the given thread had been interrupted
1961 *******************************************************************************/
1963 bool threads_thread_has_been_interrupted(threadobject *thread)
1965 return thread->interrupted;
1969 /* threads_sleep ***************************************************************
1971 Sleep the current thread for the specified amount of time.
1973 *******************************************************************************/
1975 void threads_sleep(s8 millis, s4 nanos)
1977 threadobject *thread;
1978 struct timespec wakeupTime;
1979 bool wasinterrupted;
1981 thread = THREADOBJECT;
1983 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1985 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1988 exceptions_throw_interruptedexception();
1992 /* threads_yield ***************************************************************
1994 Yield to the scheduler.
1996 *******************************************************************************/
1998 void threads_yield(void)
2005 * These are local overrides for various environment variables in Emacs.
2006 * Please do not remove this and leave it at the end of the file, where
2007 * Emacs will automagically detect them.
2008 * ---------------------------------------------------------------------
2011 * indent-tabs-mode: t
2015 * vim:noexpandtab:sw=4:ts=4: