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
30 /* XXX cleanup these includes */
35 #include <sys/types.h>
48 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
49 # include "machine-instr.h"
51 # include "threads/native/generic-primitives.h"
54 #include "mm/gc-common.h"
55 #include "mm/memory.h"
57 #include "native/jni.h"
58 #include "native/llni.h"
59 #include "native/native.h"
60 #include "native/include/java_lang_Object.h"
61 #include "native/include/java_lang_String.h"
62 #include "native/include/java_lang_Throwable.h"
63 #include "native/include/java_lang_Thread.h"
65 #if defined(ENABLE_JAVASE)
66 # include "native/include/java_lang_ThreadGroup.h"
69 #if defined(WITH_CLASSPATH_GNU)
70 # include "native/include/java_lang_VMThread.h"
73 #include "threads/lock-common.h"
74 #include "threads/threads-common.h"
76 #include "threads/native/threads.h"
78 #include "toolbox/logging.h"
80 #include "vm/builtin.h"
81 #include "vm/exceptions.h"
82 #include "vm/global.h"
83 #include "vm/stringlocal.h"
86 #include "vm/jit/asmpart.h"
88 #include "vmcore/options.h"
90 #if defined(ENABLE_STATISTICS)
91 # include "vmcore/statistics.h"
94 #if !defined(__DARWIN__)
95 # if defined(__LINUX__)
96 # define GC_LINUX_THREADS
97 # elif defined(__MIPS__)
98 # define GC_IRIX_THREADS
100 # include <semaphore.h>
101 # if defined(ENABLE_GC_BOEHM)
102 # include "mm/boehm-gc/include/gc.h"
106 #if defined(ENABLE_JVMTI)
107 #include "native/jvmti/cacaodbg.h"
110 #if defined(__DARWIN__)
111 /* Darwin has no working semaphore implementation. This one is taken
115 This is a very simple semaphore implementation for darwin. It
116 is implemented in terms of pthreads calls so it isn't async signal
117 safe. This isn't a problem because signals aren't used to
118 suspend threads on darwin.
121 static int sem_init(sem_t *sem, int pshared, int value)
128 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
131 if (pthread_cond_init(&sem->cond, NULL) < 0)
137 static int sem_post(sem_t *sem)
139 if (pthread_mutex_lock(&sem->mutex) < 0)
144 if (pthread_cond_signal(&sem->cond) < 0) {
145 pthread_mutex_unlock(&sem->mutex);
149 if (pthread_mutex_unlock(&sem->mutex) < 0)
155 static int sem_wait(sem_t *sem)
157 if (pthread_mutex_lock(&sem->mutex) < 0)
160 while (sem->value == 0) {
161 pthread_cond_wait(&sem->cond, &sem->mutex);
166 if (pthread_mutex_unlock(&sem->mutex) < 0)
172 static int sem_destroy(sem_t *sem)
174 if (pthread_cond_destroy(&sem->cond) < 0)
177 if (pthread_mutex_destroy(&sem->mutex) < 0)
182 #endif /* defined(__DARWIN__) */
185 /* internally used constants **************************************************/
187 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
188 #define STOPWORLD_FROM_GC 1
189 #define STOPWORLD_FROM_CLASS_NUMBERING 2
192 /* startupinfo *****************************************************************
194 Struct used to pass info from threads_start_thread to
195 threads_startup_thread.
197 ******************************************************************************/
200 threadobject *thread; /* threadobject for this thread */
201 functionptr function; /* function to run in the new thread */
202 sem_t *psem; /* signals when thread has been entered */
203 /* in the thread list */
204 sem_t *psem_first; /* signals when pthread_create has returned */
208 /* prototypes *****************************************************************/
210 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
213 /******************************************************************************/
214 /* GLOBAL VARIABLES */
215 /******************************************************************************/
217 static methodinfo *method_thread_init;
219 /* the thread object of the current thread */
220 /* This is either a thread-local variable defined with __thread, or */
221 /* a thread-specific value stored with key threads_current_threadobject_key. */
222 #if defined(HAVE___THREAD)
223 __thread threadobject *threads_current_threadobject;
225 pthread_key_t threads_current_threadobject_key;
228 /* global mutex for the threads table */
229 static pthread_mutex_t mutex_threads_list;
231 /* global mutex for stop-the-world */
232 static pthread_mutex_t stopworldlock;
234 /* global mutex and condition for joining threads on exit */
235 static pthread_mutex_t mutex_join;
236 static pthread_cond_t cond_join;
238 /* XXX We disable that whole bunch of code until we have the exact-GC
243 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
245 static volatile int stopworldwhere;
247 /* semaphore used for acknowleding thread suspension */
248 static sem_t suspend_ack;
249 #if defined(__MIPS__)
250 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
251 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
256 /* mutexes used by the fake atomic instructions */
257 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
258 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
259 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
260 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
264 /* threads_sem_init ************************************************************
266 Initialize a semaphore. Checks against errors and interruptions.
269 sem..............the semaphore to initialize
270 shared...........true if this semaphore will be shared between processes
271 value............the initial value for the semaphore
273 *******************************************************************************/
275 void threads_sem_init(sem_t *sem, bool shared, int value)
282 r = sem_init(sem, shared, value);
285 } while (errno == EINTR);
287 vm_abort("sem_init failed: %s", strerror(errno));
291 /* threads_sem_wait ************************************************************
293 Wait for a semaphore, non-interruptible.
295 IMPORTANT: Always use this function instead of `sem_wait` directly, as
296 `sem_wait` may be interrupted by signals!
299 sem..............the semaphore to wait on
301 *******************************************************************************/
303 void threads_sem_wait(sem_t *sem)
313 } while (errno == EINTR);
315 vm_abort("sem_wait failed: %s", strerror(errno));
319 /* threads_sem_post ************************************************************
321 Increase the count of a semaphore. Checks for errors.
324 sem..............the semaphore to increase the count of
326 *******************************************************************************/
328 void threads_sem_post(sem_t *sem)
334 /* unlike sem_wait, sem_post is not interruptible */
340 vm_abort("sem_post failed: %s", strerror(errno));
344 /* lock_stopworld **************************************************************
346 Enter the stopworld lock, specifying why the world shall be stopped.
349 where........ STOPWORLD_FROM_GC (1) from within GC
350 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
352 ******************************************************************************/
354 void lock_stopworld(int where)
356 pthread_mutex_lock(&stopworldlock);
357 /* stopworldwhere = where; */
361 /* unlock_stopworld ************************************************************
363 Release the stopworld lock.
365 ******************************************************************************/
367 void unlock_stopworld(void)
369 /* stopworldwhere = 0; */
370 pthread_mutex_unlock(&stopworldlock);
373 /* XXX We disable that whole bunch of code until we have the exact-GC
378 #if !defined(__DARWIN__)
379 /* Caller must hold threadlistlock */
380 static s4 threads_cast_sendsignals(s4 sig)
388 /* iterate over all started threads */
392 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
393 /* don't send the signal to ourself */
398 /* don't send the signal to NEW threads (because they are not
399 completely initialized) */
401 if (t->state == THREAD_STATE_NEW)
404 /* send the signal */
406 pthread_kill(t->tid, sig);
408 /* increase threads count */
418 static void threads_cast_darwinstop(void)
420 threadobject *tobj = mainthreadobj;
421 threadobject *self = THREADOBJECT;
426 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
427 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
428 #if defined(__I386__)
429 i386_thread_state_t thread_state;
431 ppc_thread_state_t thread_state;
433 mach_port_t thread = tobj->mach_thread;
436 r = thread_suspend(thread);
438 if (r != KERN_SUCCESS)
439 vm_abort("thread_suspend failed");
441 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
442 &thread_state_count);
444 if (r != KERN_SUCCESS)
445 vm_abort("thread_get_state failed");
447 md_critical_section_restart((ucontext_t *) &thread_state);
449 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
452 if (r != KERN_SUCCESS)
453 vm_abort("thread_set_state failed");
457 } while (tobj != mainthreadobj);
460 static void threads_cast_darwinresume(void)
462 threadobject *tobj = mainthreadobj;
463 threadobject *self = THREADOBJECT;
468 mach_port_t thread = tobj->mach_thread;
471 r = thread_resume(thread);
473 if (r != KERN_SUCCESS)
474 vm_abort("thread_resume failed");
478 } while (tobj != mainthreadobj);
483 #if defined(__MIPS__)
484 static void threads_cast_irixresume(void)
486 pthread_mutex_lock(&suspend_ack_lock);
487 pthread_cond_broadcast(&suspend_cond);
488 pthread_mutex_unlock(&suspend_ack_lock);
492 #if !defined(DISABLE_GC)
494 void threads_cast_stopworld(void)
496 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
500 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
502 /* lock the threads lists */
506 #if defined(__DARWIN__)
507 threads_cast_darwinstop();
508 #elif defined(__CYGWIN__)
512 /* send all threads the suspend signal */
514 count = threads_cast_sendsignals(GC_signum1());
516 /* wait for all threads signaled to suspend */
518 for (i = 0; i < count; i++)
519 threads_sem_wait(&suspend_ack);
522 /* ATTENTION: Don't unlock the threads-lists here so that
523 non-signaled NEW threads can't change their state and execute
528 void threads_cast_startworld(void)
530 #if defined(__DARWIN__)
531 threads_cast_darwinresume();
532 #elif defined(__MIPS__)
533 threads_cast_irixresume();
534 #elif defined(__CYGWIN__)
538 (void) threads_cast_sendsignals(GC_signum2());
541 /* unlock the threads lists */
543 threads_list_unlock();
549 #if !defined(__DARWIN__)
550 static void threads_sigsuspend_handler(ucontext_t *_uc)
555 /* XXX TWISTI: this is just a quick hack */
556 #if defined(ENABLE_JIT)
557 md_critical_section_restart(_uc);
560 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
561 (not POSIX async-safe). */
562 #if defined(__IRIX__)
563 pthread_mutex_lock(&suspend_ack_lock);
564 threads_sem_post(&suspend_ack);
565 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
566 pthread_mutex_unlock(&suspend_ack_lock);
567 #elif defined(__CYGWIN__)
571 threads_sem_post(&suspend_ack);
575 sigdelset(&sigs, sig);
583 /* This function is called from Boehm GC code. */
585 int cacao_suspendhandler(ucontext_t *_uc)
587 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
590 threads_sigsuspend_handler(_uc);
594 #endif /* DISABLE_GC */
599 /* threads_set_current_threadobject ********************************************
601 Set the current thread object.
604 thread.......the thread object to set
606 *******************************************************************************/
608 void threads_set_current_threadobject(threadobject *thread)
610 #if !defined(HAVE___THREAD)
611 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
612 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
614 threads_current_threadobject = thread;
619 /* threads_impl_thread_new *****************************************************
621 Initialize implementation fields of a threadobject.
624 t....the threadobject
626 *******************************************************************************/
628 void threads_impl_thread_new(threadobject *t)
630 /* get the pthread id */
632 t->tid = pthread_self();
634 /* initialize the mutex and the condition */
636 pthread_mutex_init(&(t->waitmutex), NULL);
637 pthread_cond_init(&(t->waitcond), NULL);
639 #if defined(ENABLE_DEBUG_FILTER)
640 /* Initialize filter counters */
641 t->filterverbosecallctr[0] = 0;
642 t->filterverbosecallctr[1] = 0;
646 t->tracejavacallindent = 0;
647 t->tracejavacallcount = 0;
652 /* threads_impl_thread_free ****************************************************
654 Cleanup thread stuff.
657 t....the threadobject
659 *******************************************************************************/
661 void threads_impl_thread_free(threadobject *t)
663 /* destroy the mutex and the condition */
665 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
666 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
669 if (pthread_cond_destroy(&(t->waitcond)) != 0)
670 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
675 /* threads_get_current_threadobject ********************************************
677 Return the threadobject of the current thread.
680 the current threadobject * (an instance of java.lang.Thread)
682 *******************************************************************************/
684 threadobject *threads_get_current_threadobject(void)
690 /* threads_impl_preinit ********************************************************
692 Do some early initialization of stuff required.
694 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
695 is called AFTER this function!
697 *******************************************************************************/
699 void threads_impl_preinit(void)
701 pthread_mutex_init(&stopworldlock, NULL);
703 /* initialize exit mutex and condition (on exit we join all
706 pthread_mutex_init(&mutex_join, NULL);
707 pthread_cond_init(&cond_join, NULL);
709 /* initialize the threads-list mutex */
711 pthread_mutex_init(&mutex_threads_list, NULL);
713 #if !defined(HAVE___THREAD)
714 pthread_key_create(&threads_current_threadobject_key, NULL);
717 /* threads_sem_init(&suspend_ack, 0, 0); */
721 /* threads_list_lock ***********************************************************
723 Enter the threads table mutex.
725 NOTE: We need this function as we can't use an internal lock for
726 the threads lists because the thread's lock is initialized in
727 threads_table_add (when we have the thread index), but we
728 already need the lock at the entry of the function.
730 *******************************************************************************/
732 void threads_list_lock(void)
734 if (pthread_mutex_lock(&mutex_threads_list) != 0)
735 vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
740 /* threads_list_unlock *********************************************************
742 Leave the threads list mutex.
744 *******************************************************************************/
746 void threads_list_unlock(void)
748 if (pthread_mutex_unlock(&mutex_threads_list) != 0)
749 vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
754 /* threads_mutex_join_lock *****************************************************
756 Enter the join mutex.
758 *******************************************************************************/
760 void threads_mutex_join_lock(void)
762 if (pthread_mutex_lock(&mutex_join) != 0)
763 vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
768 /* threads_mutex_join_unlock ***************************************************
770 Leave the join mutex.
772 *******************************************************************************/
774 void threads_mutex_join_unlock(void)
776 if (pthread_mutex_unlock(&mutex_join) != 0)
777 vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
782 /* threads_init ****************************************************************
784 Initializes the threads required by the JVM: main, finalizer.
786 *******************************************************************************/
788 bool threads_init(void)
790 threadobject *mainthread;
791 java_handle_t *threadname;
795 #if defined(ENABLE_JAVASE)
796 java_lang_ThreadGroup *threadgroup;
800 #if defined(WITH_CLASSPATH_GNU)
801 java_lang_VMThread *vmt;
806 /* get methods we need in this file */
808 #if defined(WITH_CLASSPATH_GNU)
810 class_resolveclassmethod(class_java_lang_Thread,
812 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
813 class_java_lang_Thread,
815 #elif defined(WITH_CLASSPATH_SUN)
817 class_resolveclassmethod(class_java_lang_Thread,
819 utf_new_char("(Ljava/lang/String;)V"),
820 class_java_lang_Thread,
822 #elif defined(WITH_CLASSPATH_CLDC1_1)
824 class_resolveclassmethod(class_java_lang_Thread,
826 utf_new_char("(Ljava/lang/String;)V"),
827 class_java_lang_Thread,
830 # error unknown classpath configuration
833 if (method_thread_init == NULL)
836 /* Get the main-thread (NOTE: The main threads is always the first
837 thread in the list). */
839 mainthread = threads_list_first();
841 /* create a java.lang.Thread for the main thread */
843 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
848 /* set the object in the internal data structure */
850 mainthread->object = t;
852 #if defined(ENABLE_INTRP)
853 /* create interpreter stack */
856 MSET(intrp_main_stack, 0, u1, opt_stacksize);
857 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
861 threadname = javastring_new(utf_new_char("main"));
863 #if defined(ENABLE_JAVASE)
864 /* allocate and init ThreadGroup */
866 threadgroup = (java_lang_ThreadGroup *)
867 native_new_and_init(class_java_lang_ThreadGroup);
869 if (threadgroup == NULL)
873 #if defined(WITH_CLASSPATH_GNU)
874 /* create a java.lang.VMThread for the main thread */
876 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
883 LLNI_field_set_ref(vmt, thread, t);
884 LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) mainthread);
886 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
887 o = (java_handle_t *) t;
889 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
892 #elif defined(WITH_CLASSPATH_SUN)
894 /* We trick java.lang.Thread.<init>, which sets the priority of
895 the current thread to the parent's one. */
897 t->priority = NORM_PRIORITY;
899 /* Call java.lang.Thread.<init>(Ljava/lang/String;)V */
901 o = (java_object_t *) t;
903 (void) vm_call_method(method_thread_init, o, threadname);
905 #elif defined(WITH_CLASSPATH_CLDC1_1)
909 t->vm_thread = (java_lang_Object *) mainthread;
911 /* call public Thread(String name) */
913 o = (java_handle_t *) t;
915 (void) vm_call_method(method_thread_init, o, threadname);
917 # error unknown classpath configuration
920 if (exceptions_get_exception())
923 #if defined(ENABLE_JAVASE)
924 LLNI_field_set_ref(t, group, threadgroup);
926 # if defined(WITH_CLASSPATH_GNU)
927 /* add main thread to java.lang.ThreadGroup */
929 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
931 utf_java_lang_Thread__V,
932 class_java_lang_ThreadGroup,
935 o = (java_handle_t *) threadgroup;
937 (void) vm_call_method(m, o, t);
939 if (exceptions_get_exception())
942 # warning Do not know what to do here
946 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
948 /* initialize the thread attribute object */
950 if (pthread_attr_init(&attr) != 0)
951 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
953 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
954 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
958 if (opt_verbosethreads) {
959 printf("[Starting thread ");
960 threads_thread_print_info(mainthread);
965 /* everything's ok */
971 /* threads_startup_thread ******************************************************
973 Thread startup function called by pthread_create.
975 Thread which have a startup.function != NULL are marked as internal
976 threads. All other threads are threated as normal Java threads.
978 NOTE: This function is not called directly by pthread_create. The Boehm GC
979 inserts its own GC_start_routine in between, which then calls
983 arg..........the argument passed to pthread_create, ie. a pointer to
984 a startupinfo struct. CAUTION: When the `psem` semaphore
985 is posted, the startupinfo struct becomes invalid! (It
986 is allocated on the stack of threads_start_thread.)
988 ******************************************************************************/
990 static void *threads_startup_thread(void *arg)
992 startupinfo *startup;
993 threadobject *thread;
994 #if defined(WITH_CLASSPATH_GNU)
995 java_lang_VMThread *vmt;
1001 functionptr function;
1003 #if defined(ENABLE_INTRP)
1004 u1 *intrp_thread_stack;
1006 /* create interpreter stack */
1009 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1010 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1013 intrp_thread_stack = NULL;
1016 /* get passed startupinfo structure and the values in there */
1020 thread = startup->thread;
1021 function = startup->function;
1022 psem = startup->psem;
1024 /* Seems like we've encountered a situation where thread->tid was
1025 not set by pthread_create. We alleviate this problem by waiting
1026 for pthread_create to return. */
1028 threads_sem_wait(startup->psem_first);
1030 #if defined(__DARWIN__)
1031 thread->mach_thread = mach_thread_self();
1034 /* store the internal thread data-structure in the TSD */
1036 threads_set_current_threadobject(thread);
1038 /* set our priority */
1040 threads_set_thread_priority(thread->tid, LLNI_field_direct(thread->object, priority));
1042 /* thread is completely initialized */
1044 threads_thread_state_runnable(thread);
1046 /* tell threads_startup_thread that we registered ourselves */
1047 /* CAUTION: *startup becomes invalid with this! */
1050 threads_sem_post(psem);
1052 #if defined(ENABLE_INTRP)
1053 /* set interpreter stack */
1056 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1059 #if defined(ENABLE_JVMTI)
1060 /* fire thread start event */
1063 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1066 #if !defined(NDEBUG)
1067 if (opt_verbosethreads) {
1068 printf("[Starting thread ");
1069 threads_thread_print_info(thread);
1074 /* find and run the Thread.run()V method if no other function was passed */
1076 if (function == NULL) {
1077 #if defined(WITH_CLASSPATH_GNU)
1078 /* We need to start the run method of
1079 java.lang.VMThread. Since this is a final class, we can use
1080 the class object directly. */
1082 c = class_java_lang_VMThread;
1083 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1084 c = thread->object->header.vftbl->class;
1086 # error unknown classpath configuration
1089 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1092 vm_abort("threads_startup_thread: run() method not found in class");
1094 /* set ThreadMXBean variables */
1096 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1097 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1099 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1100 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1101 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1102 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1104 #if defined(WITH_CLASSPATH_GNU)
1105 /* we need to start the run method of java.lang.VMThread */
1107 vmt = (java_lang_VMThread *) LLNI_field_direct(thread->object, vmThread);
1108 o = (java_handle_t *) vmt;
1110 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1111 o = (java_handle_t *) thread->object;
1113 # error unknown classpath configuration
1116 /* run the thread */
1118 (void) vm_call_method(m, o);
1121 /* set ThreadMXBean variables */
1123 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1124 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1126 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1127 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1128 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1129 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1131 /* call passed function, e.g. finalizer_thread */
1136 #if !defined(NDEBUG)
1137 if (opt_verbosethreads) {
1138 printf("[Stopping thread ");
1139 threads_thread_print_info(thread);
1144 #if defined(ENABLE_JVMTI)
1145 /* fire thread end event */
1148 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1151 /* We ignore the return value. */
1153 (void) threads_detach_thread(thread);
1155 /* set ThreadMXBean variables */
1157 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1163 /* threads_impl_thread_start ***************************************************
1165 Start a thread in the JVM. Both (vm internal and java) thread
1169 thread....the thread object
1170 f.........function to run in the new thread. NULL means that the
1171 "run" method of the object `t` should be called
1173 ******************************************************************************/
1175 void threads_impl_thread_start(threadobject *thread, functionptr f)
1179 pthread_attr_t attr;
1180 startupinfo startup;
1183 /* fill startupinfo structure passed by pthread_create to
1184 * threads_startup_thread */
1186 startup.thread = thread;
1187 startup.function = f; /* maybe we don't call Thread.run()V */
1188 startup.psem = &sem;
1189 startup.psem_first = &sem_first;
1191 threads_sem_init(&sem, 0, 0);
1192 threads_sem_init(&sem_first, 0, 0);
1194 /* initialize thread attributes */
1196 if (pthread_attr_init(&attr) != 0)
1197 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1200 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1201 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1204 /* initialize thread stacksize */
1206 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1207 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1210 /* create the thread */
1212 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1214 /* destroy the thread attributes */
1216 if (pthread_attr_destroy(&attr) != 0)
1217 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1220 /* check for pthread_create error */
1223 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1226 /* signal that pthread_create has returned, so thread->tid is valid */
1228 threads_sem_post(&sem_first);
1230 /* wait here until the thread has entered itself into the thread list */
1232 threads_sem_wait(&sem);
1237 sem_destroy(&sem_first);
1241 /* threads_set_thread_priority *************************************************
1243 Set the priority of the given thread.
1246 tid..........thread id
1247 priority.....priority to set
1249 ******************************************************************************/
1251 void threads_set_thread_priority(pthread_t tid, int priority)
1253 struct sched_param schedp;
1256 pthread_getschedparam(tid, &policy, &schedp);
1257 schedp.sched_priority = priority;
1258 pthread_setschedparam(tid, policy, &schedp);
1262 /* threads_attach_current_thread ***********************************************
1264 Attaches the current thread to the VM. Used in JNI.
1266 *******************************************************************************/
1268 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1270 threadobject *thread;
1274 java_lang_Thread *t;
1276 #if defined(ENABLE_JAVASE)
1277 java_lang_ThreadGroup *group;
1278 threadobject *mainthread;
1283 #if defined(WITH_CLASSPATH_GNU)
1284 java_lang_VMThread *vmt;
1287 /* Enter the join-mutex, so if the main-thread is currently
1288 waiting to join all threads, the number of non-daemon threads
1291 threads_mutex_join_lock();
1293 /* create internal thread data-structure */
1295 thread = threads_thread_new();
1297 /* thread is a Java thread and running */
1299 thread->flags = THREAD_FLAG_JAVA;
1302 thread->flags |= THREAD_FLAG_DAEMON;
1304 /* The thread is flagged and (non-)daemon thread, we can leave the
1307 threads_mutex_join_unlock();
1309 /* create a java.lang.Thread object */
1311 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1313 /* XXX memory leak!!! */
1319 /* thread is completely initialized */
1321 threads_thread_state_runnable(thread);
1323 #if !defined(NDEBUG)
1324 if (opt_verbosethreads) {
1325 printf("[Attaching thread ");
1326 threads_thread_print_info(thread);
1331 #if defined(ENABLE_INTRP)
1332 /* create interpreter stack */
1335 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1336 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1340 #if defined(WITH_CLASSPATH_GNU)
1342 /* create a java.lang.VMThread object */
1344 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1346 /* XXX memory leak!!! */
1350 /* set the thread */
1352 LLNI_field_set_ref(vmt, thread, t);
1353 LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
1355 #elif defined(WITH_CLASSPATH_SUN)
1357 vm_abort("threads_attach_current_thread: IMPLEMENT ME!");
1359 #elif defined(WITH_CLASSPATH_CLDC1_1)
1361 LLNI_field_set_val(t, vm_thread, (java_lang_Object *) thread);
1364 # error unknown classpath configuration
1367 if (vm_aargs != NULL) {
1368 u = utf_new_char(vm_aargs->name);
1369 #if defined(ENABLE_JAVASE)
1370 group = (java_lang_ThreadGroup *) vm_aargs->group;
1375 #if defined(ENABLE_JAVASE)
1376 /* get the main thread */
1378 mainthread = threads_list_first();
1379 group = LLNI_field_direct(mainthread->object, group);
1383 /* the the thread name */
1385 s = javastring_new(u);
1387 /* for convenience */
1389 o = (java_handle_t *) thread->object;
1391 #if defined(WITH_CLASSPATH_GNU)
1392 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1394 #elif defined(WITH_CLASSPATH_CLDC1_1)
1395 (void) vm_call_method(method_thread_init, o, s);
1398 if (exceptions_get_exception())
1401 #if defined(ENABLE_JAVASE)
1402 /* store the thread group in the object */
1404 LLNI_field_direct(thread->object, group) = group;
1406 /* add thread to given thread-group */
1408 LLNI_class_get(group, c);
1410 m = class_resolveclassmethod(c,
1412 utf_java_lang_Thread__V,
1413 class_java_lang_ThreadGroup,
1416 o = (java_handle_t *) group;
1418 (void) vm_call_method(m, o, t);
1420 if (exceptions_get_exception())
1428 /* threads_detach_thread *******************************************************
1430 Detaches the passed thread from the VM. Used in JNI.
1432 *******************************************************************************/
1434 bool threads_detach_thread(threadobject *t)
1436 #if defined(ENABLE_JAVASE)
1437 java_lang_Thread *object;
1438 java_lang_ThreadGroup *group;
1440 java_lang_Object *handler;
1446 #if defined(ENABLE_JAVASE)
1449 group = LLNI_field_direct(object, group);
1451 /* If there's an uncaught exception, call uncaughtException on the
1452 thread's exception handler, or the thread's group if this is
1455 e = exceptions_get_and_clear_exception();
1458 /* We use a java_lang_Object here, as it's not trivial to
1459 build the java_lang_Thread_UncaughtExceptionHandler header
1462 # if defined(WITH_CLASSPATH_GNU)
1463 handler = (java_lang_Object *) LLNI_field_direct(object, exceptionHandler);
1464 # elif defined(WITH_CLASSPATH_SUN)
1465 handler = (java_lang_Object *) LLNI_field_direct(object, uncaughtExceptionHandler);
1468 if (handler != NULL) {
1469 LLNI_class_get(handler, c);
1470 o = (java_handle_t *) handler;
1473 LLNI_class_get(group, c);
1474 o = (java_handle_t *) group;
1477 m = class_resolveclassmethod(c,
1478 utf_uncaughtException,
1479 utf_java_lang_Thread_java_lang_Throwable__V,
1486 (void) vm_call_method(m, o, object, e);
1488 if (exceptions_get_exception())
1492 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1494 /* Remove thread from the thread group. */
1496 if (group != NULL) {
1497 LLNI_class_get(group, c);
1499 # if defined(WITH_CLASSPATH_GNU)
1500 m = class_resolveclassmethod(c,
1502 utf_java_lang_Thread__V,
1503 class_java_lang_ThreadGroup,
1505 # elif defined(WITH_CLASSPATH_SUN)
1506 m = class_resolveclassmethod(c,
1508 utf_java_lang_Thread__V,
1509 class_java_lang_ThreadGroup,
1512 # error unknown classpath configuration
1518 o = (java_handle_t *) group;
1520 (void) vm_call_method(m, o, object);
1522 if (exceptions_get_exception())
1527 /* thread is terminated */
1529 threads_thread_state_terminated(t);
1531 #if !defined(NDEBUG)
1532 if (opt_verbosethreads) {
1533 printf("[Detaching thread ");
1534 threads_thread_print_info(t);
1539 /* Enter the join-mutex before calling threads_thread_free, so
1540 threads_join_all_threads gets the correct number of non-daemon
1543 threads_mutex_join_lock();
1545 /* free the vm internal thread object */
1547 threads_thread_free(t);
1549 /* Signal that this thread has finished and leave the mutex. */
1551 pthread_cond_signal(&cond_join);
1552 threads_mutex_join_unlock();
1558 /* threads_join_all_threads ****************************************************
1560 Join all non-daemon threads.
1562 *******************************************************************************/
1564 void threads_join_all_threads(void)
1568 /* get current thread */
1572 /* this thread is waiting for all non-daemon threads to exit */
1574 threads_thread_state_waiting(t);
1576 /* enter join mutex */
1578 threads_mutex_join_lock();
1580 /* Wait for condition as long as we have non-daemon threads. We
1581 compare against 1 because the current (main thread) is also a
1582 non-daemon thread. */
1584 while (threads_list_get_non_daemons() > 1)
1585 pthread_cond_wait(&cond_join, &mutex_join);
1587 /* leave join mutex */
1589 threads_mutex_join_unlock();
1593 /* threads_timespec_earlier ****************************************************
1595 Return true if timespec tv1 is earlier than timespec tv2.
1598 tv1..........first timespec
1599 tv2..........second timespec
1602 true, if the first timespec is earlier
1604 *******************************************************************************/
1606 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1607 const struct timespec *tv2)
1609 return (tv1->tv_sec < tv2->tv_sec)
1611 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1615 /* threads_current_time_is_earlier_than ****************************************
1617 Check if the current time is earlier than the given timespec.
1620 tv...........the timespec to compare against
1623 true, if the current time is earlier
1625 *******************************************************************************/
1627 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1629 struct timeval tvnow;
1630 struct timespec tsnow;
1632 /* get current time */
1634 if (gettimeofday(&tvnow, NULL) != 0)
1635 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1637 /* convert it to a timespec */
1639 tsnow.tv_sec = tvnow.tv_sec;
1640 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1642 /* compare current time with the given timespec */
1644 return threads_timespec_earlier(&tsnow, tv);
1648 /* threads_wait_with_timeout ***************************************************
1650 Wait until the given point in time on a monitor until either
1651 we are notified, we are interrupted, or the time is up.
1654 t............the current thread
1655 wakeupTime...absolute (latest) wakeup time
1656 If both tv_sec and tv_nsec are zero, this function
1657 waits for an unlimited amount of time.
1660 true.........if the wait has been interrupted,
1661 false........if the wait was ended by notification or timeout
1663 *******************************************************************************/
1665 static bool threads_wait_with_timeout(threadobject *thread,
1666 struct timespec *wakeupTime)
1668 bool wasinterrupted;
1670 /* acquire the waitmutex */
1672 pthread_mutex_lock(&thread->waitmutex);
1674 /* mark us as sleeping */
1676 thread->sleeping = true;
1678 /* wait on waitcond */
1680 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1682 while (!thread->interrupted && !thread->signaled
1683 && threads_current_time_is_earlier_than(wakeupTime))
1685 threads_thread_state_timed_waiting(thread);
1687 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1690 threads_thread_state_runnable(thread);
1695 while (!thread->interrupted && !thread->signaled) {
1696 threads_thread_state_waiting(thread);
1698 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1700 threads_thread_state_runnable(thread);
1704 /* check if we were interrupted */
1706 wasinterrupted = thread->interrupted;
1708 /* reset all flags */
1710 thread->interrupted = false;
1711 thread->signaled = false;
1712 thread->sleeping = false;
1714 /* release the waitmutex */
1716 pthread_mutex_unlock(&thread->waitmutex);
1718 return wasinterrupted;
1722 /* threads_wait_with_timeout_relative ******************************************
1724 Wait for the given maximum amount of time on a monitor until either
1725 we are notified, we are interrupted, or the time is up.
1728 t............the current thread
1729 millis.......milliseconds to wait
1730 nanos........nanoseconds to wait
1733 true.........if the wait has been interrupted,
1734 false........if the wait was ended by notification or timeout
1736 *******************************************************************************/
1738 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1741 struct timespec wakeupTime;
1743 /* calculate the the (latest) wakeup time */
1745 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1749 return threads_wait_with_timeout(thread, &wakeupTime);
1753 /* threads_calc_absolute_time **************************************************
1755 Calculate the absolute point in time a given number of ms and ns from now.
1758 millis............milliseconds from now
1759 nanos.............nanoseconds from now
1762 *tm...............receives the timespec of the absolute point in time
1764 *******************************************************************************/
1766 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1768 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1771 gettimeofday(&tv, NULL);
1772 tv.tv_sec += millis / 1000;
1774 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1775 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1776 tm->tv_nsec = nsec % 1000000000;
1785 /* threads_thread_interrupt ****************************************************
1787 Interrupt the given thread.
1789 The thread gets the "waitcond" signal and
1790 its interrupted flag is set to true.
1793 thread............the thread to interrupt
1795 *******************************************************************************/
1797 void threads_thread_interrupt(threadobject *thread)
1799 /* Signal the thread a "waitcond" and tell it that it has been
1802 pthread_mutex_lock(&thread->waitmutex);
1804 /* Interrupt blocking system call using a signal. */
1806 pthread_kill(thread->tid, SIGHUP);
1808 if (thread->sleeping)
1809 pthread_cond_signal(&thread->waitcond);
1811 thread->interrupted = true;
1813 pthread_mutex_unlock(&thread->waitmutex);
1817 /* threads_check_if_interrupted_and_reset **************************************
1819 Check if the current thread has been interrupted and reset the
1823 true, if the current thread had been interrupted
1825 *******************************************************************************/
1827 bool threads_check_if_interrupted_and_reset(void)
1829 threadobject *thread;
1832 thread = THREADOBJECT;
1834 /* get interrupted flag */
1836 intr = thread->interrupted;
1838 /* reset interrupted flag */
1840 thread->interrupted = false;
1846 /* threads_thread_has_been_interrupted *****************************************
1848 Check if the given thread has been interrupted
1851 t............the thread to check
1854 true, if the given thread had been interrupted
1856 *******************************************************************************/
1858 bool threads_thread_has_been_interrupted(threadobject *thread)
1860 return thread->interrupted;
1864 /* threads_sleep ***************************************************************
1866 Sleep the current thread for the specified amount of time.
1868 *******************************************************************************/
1870 void threads_sleep(s8 millis, s4 nanos)
1872 threadobject *thread;
1873 struct timespec wakeupTime;
1874 bool wasinterrupted;
1876 thread = THREADOBJECT;
1878 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1880 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1883 exceptions_throw_interruptedexception();
1887 /* threads_yield ***************************************************************
1889 Yield to the scheduler.
1891 *******************************************************************************/
1893 void threads_yield(void)
1900 * These are local overrides for various environment variables in Emacs.
1901 * Please do not remove this and leave it at the end of the file, where
1902 * Emacs will automagically detect them.
1903 * ---------------------------------------------------------------------
1906 * indent-tabs-mode: t
1910 * vim:noexpandtab:sw=4:ts=4: