1 /* src/threads/posix/thread-posix.c - POSIX thread functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 /* XXX cleanup these includes */
33 #include <sys/types.h>
46 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
47 # include "machine-instr.h"
49 # include "threads/posix/generic-primitives.h"
52 #include "mm/gc-common.h"
53 #include "mm/memory.h"
55 #if defined(ENABLE_GC_CACAO)
56 # include "mm/cacao-gc/gc.h"
59 #include "native/jni.h"
60 #include "native/llni.h"
61 #include "native/native.h"
63 #include "native/include/java_lang_Object.h"
64 #include "native/include/java_lang_String.h"
65 #include "native/include/java_lang_Throwable.h"
66 #include "native/include/java_lang_Thread.h"
68 #if defined(ENABLE_JAVASE)
69 # include "native/include/java_lang_ThreadGroup.h"
72 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
73 # include "native/include/java_lang_VMThread.h"
76 #include "threads/lock-common.h"
77 #include "threads/mutex.h"
78 #include "threads/threadlist.h"
79 #include "threads/thread.h"
81 #include "toolbox/logging.h"
83 #include "vm/builtin.h"
84 #include "vm/exceptions.h"
85 #include "vm/global.h"
86 #include "vm/stringlocal.h"
89 #include "vm/jit/asmpart.h"
91 #include "vmcore/options.h"
93 #if defined(ENABLE_STATISTICS)
94 # include "vmcore/statistics.h"
97 #if !defined(__DARWIN__)
98 # include <semaphore.h>
101 #if defined(__LINUX__)
102 # define GC_LINUX_THREADS
103 #elif defined(__IRIX__)
104 # define GC_IRIX_THREADS
105 #elif defined(__DARWIN__)
106 # define GC_DARWIN_THREADS
109 #if defined(ENABLE_GC_BOEHM)
110 /* We need to include Boehm's gc.h here because it overrides
111 pthread_create and friends. */
112 # include "mm/boehm-gc/include/gc.h"
115 #if defined(ENABLE_JVMTI)
116 #include "native/jvmti/cacaodbg.h"
119 #if defined(__DARWIN__)
120 /* Darwin has no working semaphore implementation. This one is taken
124 This is a very simple semaphore implementation for darwin. It
125 is implemented in terms of pthreads calls so it isn't async signal
126 safe. This isn't a problem because signals aren't used to
127 suspend threads on darwin.
130 static int sem_init(sem_t *sem, int pshared, int value)
137 mutex_init(&sem->mutex);
139 if (pthread_cond_init(&sem->cond, NULL) < 0)
145 static int sem_post(sem_t *sem)
147 mutex_lock(&sem->mutex);
151 if (pthread_cond_signal(&sem->cond) < 0) {
152 mutex_unlock(&sem->mutex);
156 mutex_unlock(&sem->mutex);
161 static int sem_wait(sem_t *sem)
163 mutex_lock(&sem->mutex);
165 while (sem->value == 0) {
166 pthread_cond_wait(&sem->cond, &sem->mutex);
171 mutex_unlock(&sem->mutex);
176 static int sem_destroy(sem_t *sem)
178 if (pthread_cond_destroy(&sem->cond) < 0)
181 mutex_destroy(&sem->mutex);
185 #endif /* defined(__DARWIN__) */
188 /* startupinfo *****************************************************************
190 Struct used to pass info from threads_start_thread to
191 threads_startup_thread.
193 ******************************************************************************/
196 threadobject *thread; /* threadobject for this thread */
197 functionptr function; /* function to run in the new thread */
198 sem_t *psem; /* signals when thread has been entered */
199 /* in the thread list */
200 sem_t *psem_first; /* signals when pthread_create has returned */
204 /* prototypes *****************************************************************/
206 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
209 /******************************************************************************/
210 /* GLOBAL VARIABLES */
211 /******************************************************************************/
213 /* the thread object of the current thread */
214 /* This is either a thread-local variable defined with __thread, or */
215 /* a thread-specific value stored with key threads_current_threadobject_key. */
216 #if defined(HAVE___THREAD)
217 __thread threadobject *thread_current;
219 pthread_key_t thread_current_key;
222 /* global mutex for stop-the-world */
223 static mutex_t stopworldlock;
225 #if defined(ENABLE_GC_CACAO)
226 /* global mutex for the GC */
227 static mutex_t mutex_gc;
230 /* global mutex and condition for joining threads on exit */
231 static mutex_t mutex_join;
232 static pthread_cond_t cond_join;
234 #if defined(ENABLE_GC_CACAO)
235 /* semaphore used for acknowleding thread suspension */
236 static sem_t suspend_ack;
239 /* mutexes used by the fake atomic instructions */
240 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
241 mutex_t _cas_lock = MUTEX_INITIALIZER;
242 mutex_t _mb_lock = MUTEX_INITIALIZER;
246 /* threads_sem_init ************************************************************
248 Initialize a semaphore. Checks against errors and interruptions.
251 sem..............the semaphore to initialize
252 shared...........true if this semaphore will be shared between processes
253 value............the initial value for the semaphore
255 *******************************************************************************/
257 void threads_sem_init(sem_t *sem, bool shared, int value)
264 r = sem_init(sem, shared, value);
267 } while (errno == EINTR);
269 vm_abort("sem_init failed: %s", strerror(errno));
273 /* threads_sem_wait ************************************************************
275 Wait for a semaphore, non-interruptible.
277 IMPORTANT: Always use this function instead of `sem_wait` directly, as
278 `sem_wait` may be interrupted by signals!
281 sem..............the semaphore to wait on
283 *******************************************************************************/
285 void threads_sem_wait(sem_t *sem)
295 } while (errno == EINTR);
297 vm_abort("sem_wait failed: %s", strerror(errno));
301 /* threads_sem_post ************************************************************
303 Increase the count of a semaphore. Checks for errors.
306 sem..............the semaphore to increase the count of
308 *******************************************************************************/
310 void threads_sem_post(sem_t *sem)
316 /* unlike sem_wait, sem_post is not interruptible */
322 vm_abort("sem_post failed: %s", strerror(errno));
326 /* threads_stopworld ***********************************************************
328 Stops the world from turning. All threads except the calling one
329 are suspended. The function returns as soon as all threads have
330 acknowledged their suspension.
332 *******************************************************************************/
334 #if defined(ENABLE_GC_CACAO)
335 void threads_stopworld(void)
337 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
344 mutex_lock(&stopworldlock);
346 /* lock the threads lists */
350 #if defined(__DARWIN__)
351 /*threads_cast_darwinstop();*/
353 #elif defined(__CYGWIN__)
359 DEBUGTHREADS("stops World", self);
363 /* suspend all running threads */
364 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
365 /* don't send the signal to ourself */
370 /* don't send the signal to NEW threads (because they are not
371 completely initialized) */
373 if (t->state == THREAD_STATE_NEW)
376 /* send the signal */
378 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
381 /* increase threads count */
386 /* wait for all threads signaled to suspend */
387 for (i = 0; i < count; i++)
388 threads_sem_wait(&suspend_ack);
391 /* ATTENTION: Don't unlock the threads-lists here so that
392 non-signaled NEW threads can't change their state and execute
398 /* threads_startworld **********************************************************
400 Starts the world again after it has previously been stopped.
402 *******************************************************************************/
404 #if defined(ENABLE_GC_CACAO)
405 void threads_startworld(void)
407 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
414 #if defined(__DARWIN__)
415 /*threads_cast_darwinresume();*/
417 #elif defined(__IRIX__)
418 threads_cast_irixresume();
419 #elif defined(__CYGWIN__)
425 DEBUGTHREADS("starts World", self);
429 /* resume all thread we haltet */
430 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
431 /* don't send the signal to ourself */
436 /* don't send the signal to NEW threads (because they are not
437 completely initialized) */
439 if (t->state == THREAD_STATE_NEW)
442 /* send the signal */
444 result = threads_resume_thread(t);
447 /* increase threads count */
452 /* wait for all threads signaled to suspend */
453 for (i = 0; i < count; i++)
454 threads_sem_wait(&suspend_ack);
458 /* unlock the threads lists */
462 mutex_unlock(&stopworldlock);
467 /* threads_impl_thread_init ****************************************************
469 Initialize OS-level locking constructs in threadobject.
472 t....the threadobject
474 *******************************************************************************/
476 void threads_impl_thread_init(threadobject *t)
480 /* initialize the mutex and the condition */
482 mutex_init(&t->flc_lock);
484 result = pthread_cond_init(&t->flc_cond, NULL);
486 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
488 mutex_init(&(t->waitmutex));
490 result = pthread_cond_init(&(t->waitcond), NULL);
492 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
494 mutex_init(&(t->suspendmutex));
496 result = pthread_cond_init(&(t->suspendcond), NULL);
498 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
501 /* threads_impl_thread_clear ***************************************************
503 Clears all fields in threadobject the way an MZERO would have
504 done. MZERO cannot be used anymore because it would mess up the
508 t....the threadobject
510 *******************************************************************************/
512 void threads_impl_thread_clear(threadobject *t)
524 #if defined(__DARWIN__)
528 t->interrupted = false;
531 t->suspended = false;
532 t->suspend_reason = 0;
536 t->_exceptionptr = NULL;
537 t->_stackframeinfo = NULL;
538 t->_localref_table = NULL;
540 #if defined(ENABLE_INTRP)
541 t->_global_sp = NULL;
544 #if defined(ENABLE_GC_CACAO)
545 t->gc_critical = false;
551 MZERO(&t->dumpinfo, dumpinfo_t, 1);
554 /* threads_impl_thread_reuse ***************************************************
556 Resets some implementation fields in threadobject. This was
557 previously done in threads_impl_thread_new.
560 t....the threadobject
562 *******************************************************************************/
564 void threads_impl_thread_reuse(threadobject *t)
566 /* get the pthread id */
568 t->tid = pthread_self();
570 #if defined(ENABLE_DEBUG_FILTER)
571 /* Initialize filter counters */
572 t->filterverbosecallctr[0] = 0;
573 t->filterverbosecallctr[1] = 0;
577 t->tracejavacallindent = 0;
578 t->tracejavacallcount = 0;
585 /* not really needed */
586 t->flc_object = NULL;
590 /* threads_impl_thread_free ****************************************************
592 Cleanup thread stuff.
595 t....the threadobject
597 *******************************************************************************/
601 void threads_impl_thread_free(threadobject *t)
605 /* Destroy the mutex and the condition. */
607 mutex_destroy(&(t->flc_lock));
609 result = pthread_cond_destroy(&(t->flc_cond));
612 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
614 mutex_destroy(&(t->waitmutex));
616 result = pthread_cond_destroy(&(t->waitcond));
619 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
621 mutex_destroy(&(t->suspendmutex));
623 result = pthread_cond_destroy(&(t->suspendcond));
626 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
631 /* threads_impl_preinit ********************************************************
633 Do some early initialization of stuff required.
635 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
636 is called AFTER this function!
638 *******************************************************************************/
640 void threads_impl_preinit(void)
644 mutex_init(&stopworldlock);
646 /* initialize exit mutex and condition (on exit we join all
649 mutex_init(&mutex_join);
651 result = pthread_cond_init(&cond_join, NULL);
653 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
655 #if defined(ENABLE_GC_CACAO)
656 /* initialize the GC mutex & suspend semaphore */
658 mutex_init(&mutex_gc);
659 threads_sem_init(&suspend_ack, 0, 0);
662 #if !defined(HAVE___THREAD)
663 result = pthread_key_create(&thread_current_key, NULL);
665 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
670 /* threads_mutex_gc_lock *******************************************************
672 Enter the global GC mutex.
674 *******************************************************************************/
676 #if defined(ENABLE_GC_CACAO)
677 void threads_mutex_gc_lock(void)
679 mutex_lock(&mutex_gc);
684 /* threads_mutex_gc_unlock *****************************************************
686 Leave the global GC mutex.
688 *******************************************************************************/
690 #if defined(ENABLE_GC_CACAO)
691 void threads_mutex_gc_unlock(void)
693 mutex_unlock(&mutex_gc);
697 /* threads_mutex_join_lock *****************************************************
699 Enter the join mutex.
701 *******************************************************************************/
703 void threads_mutex_join_lock(void)
705 mutex_lock(&mutex_join);
709 /* threads_mutex_join_unlock ***************************************************
711 Leave the join mutex.
713 *******************************************************************************/
715 void threads_mutex_join_unlock(void)
717 mutex_unlock(&mutex_join);
721 /* threads_impl_init ***********************************************************
723 Initializes the implementation specific bits.
725 *******************************************************************************/
727 void threads_impl_init(void)
732 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
734 /* Initialize the thread attribute object. */
736 result = pthread_attr_init(&attr);
739 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
741 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
744 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
748 /* threads_startup_thread ******************************************************
750 Thread startup function called by pthread_create.
752 Thread which have a startup.function != NULL are marked as internal
753 threads. All other threads are threated as normal Java threads.
755 NOTE: This function is not called directly by pthread_create. The Boehm GC
756 inserts its own GC_start_routine in between, which then calls
760 arg..........the argument passed to pthread_create, ie. a pointer to
761 a startupinfo struct. CAUTION: When the `psem` semaphore
762 is posted, the startupinfo struct becomes invalid! (It
763 is allocated on the stack of threads_start_thread.)
765 ******************************************************************************/
767 static void *threads_startup_thread(void *arg)
769 startupinfo *startup;
771 java_lang_Thread *object;
772 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
773 java_lang_VMThread *vmt;
779 functionptr function;
781 #if defined(ENABLE_GC_BOEHM)
782 # if !defined(__DARWIN__)
783 struct GC_stack_base sb;
788 #if defined(ENABLE_INTRP)
789 u1 *intrp_thread_stack;
792 #if defined(ENABLE_INTRP)
793 /* create interpreter stack */
796 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
797 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
800 intrp_thread_stack = NULL;
803 /* get passed startupinfo structure and the values in there */
808 function = startup->function;
809 psem = startup->psem;
811 /* Seems like we've encountered a situation where thread->tid was
812 not set by pthread_create. We alleviate this problem by waiting
813 for pthread_create to return. */
815 threads_sem_wait(startup->psem_first);
817 #if defined(__DARWIN__)
818 t->mach_thread = mach_thread_self();
821 /* Now that we are in the new thread, we can store the internal
822 thread data-structure in the TSD. */
824 thread_set_current(t);
826 #if defined(ENABLE_GC_BOEHM)
827 # if defined(__DARWIN__)
828 // This is currently not implemented in Boehm-GC. Just fail silently.
830 /* Register the thread with Boehm-GC. This must happen before the
831 thread allocates any memory from the GC heap.*/
833 result = GC_get_stack_base(&sb);
836 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
838 GC_register_my_thread(&sb);
842 /* get the java.lang.Thread object for this thread */
844 object = (java_lang_Thread *) thread_get_object(t);
846 /* set our priority */
848 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
850 /* Thread is completely initialized. */
852 thread_set_state_runnable(t);
854 /* tell threads_startup_thread that we registered ourselves */
855 /* CAUTION: *startup becomes invalid with this! */
858 threads_sem_post(psem);
860 #if defined(ENABLE_INTRP)
861 /* set interpreter stack */
864 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
867 #if defined(ENABLE_JVMTI)
868 /* fire thread start event */
871 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
874 DEBUGTHREADS("starting", t);
876 /* find and run the Thread.run()V method if no other function was passed */
878 if (function == NULL) {
879 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
880 /* We need to start the run method of
881 java.lang.VMThread. Since this is a final class, we can use
882 the class object directly. */
884 c = class_java_lang_VMThread;
885 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
886 LLNI_class_get(object, c);
888 # error unknown classpath configuration
891 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
894 vm_abort("threads_startup_thread: run() method not found in class");
896 /* set ThreadMXBean variables */
898 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
899 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
901 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
902 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
903 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
904 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
906 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
907 /* we need to start the run method of java.lang.VMThread */
909 LLNI_field_get_ref(object, vmThread, vmt);
910 o = (java_handle_t *) vmt;
912 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
913 o = (java_handle_t *) object;
915 # error unknown classpath configuration
918 /* Run the thread. */
920 (void) vm_call_method(m, o);
923 /* set ThreadMXBean variables */
925 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
926 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
928 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
929 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
930 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
931 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
933 /* call passed function, e.g. finalizer_thread */
938 DEBUGTHREADS("stopping", t);
940 #if defined(ENABLE_JVMTI)
941 /* fire thread end event */
944 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
947 /* We ignore the return value. */
949 (void) thread_detach_current_thread();
951 /* set ThreadMXBean variables */
953 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
959 /* threads_impl_thread_start ***************************************************
961 Start a thread in the JVM. Both (vm internal and java) thread
965 thread....the thread object
966 f.........function to run in the new thread. NULL means that the
967 "run" method of the object `t` should be called
969 ******************************************************************************/
971 void threads_impl_thread_start(threadobject *thread, functionptr f)
979 /* fill startupinfo structure passed by pthread_create to
980 * threads_startup_thread */
982 startup.thread = thread;
983 startup.function = f; /* maybe we don't call Thread.run()V */
985 startup.psem_first = &sem_first;
987 threads_sem_init(&sem, 0, 0);
988 threads_sem_init(&sem_first, 0, 0);
990 /* Initialize thread attributes. */
992 result = pthread_attr_init(&attr);
995 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
997 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1000 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1002 /* initialize thread stacksize */
1004 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1007 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1009 /* create the thread */
1011 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1014 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1016 /* destroy the thread attributes */
1018 result = pthread_attr_destroy(&attr);
1021 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1023 /* signal that pthread_create has returned, so thread->tid is valid */
1025 threads_sem_post(&sem_first);
1027 /* wait here until the thread has entered itself into the thread list */
1029 threads_sem_wait(&sem);
1034 sem_destroy(&sem_first);
1038 /* threads_set_thread_priority *************************************************
1040 Set the priority of the given thread.
1043 tid..........thread id
1044 priority.....priority to set
1046 ******************************************************************************/
1048 void threads_set_thread_priority(pthread_t tid, int priority)
1050 struct sched_param schedp;
1053 pthread_getschedparam(tid, &policy, &schedp);
1054 schedp.sched_priority = priority;
1055 pthread_setschedparam(tid, policy, &schedp);
1060 * Detaches the current thread from the VM.
1062 * @return true on success, false otherwise
1064 bool thread_detach_current_thread(void)
1068 java_lang_Thread *object;
1070 #if defined(ENABLE_JAVASE)
1071 java_lang_ThreadGroup *group;
1078 t = thread_get_current();
1084 /* If the given thread has already been detached, this operation
1087 result = thread_is_attached(t);
1089 if (result == false)
1092 DEBUGTHREADS("detaching", t);
1094 object = (java_lang_Thread *) thread_get_object(t);
1096 #if defined(ENABLE_JAVASE)
1097 LLNI_field_get_ref(object, group, group);
1099 /* If there's an uncaught exception, call uncaughtException on the
1100 thread's exception handler, or the thread's group if this is
1103 e = exceptions_get_and_clear_exception();
1106 /* We use the type void* for handler here, as it's not trivial
1107 to build the java_lang_Thread_UncaughtExceptionHandler
1108 header file with cacaoh. */
1110 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1111 LLNI_field_get_ref(object, exceptionHandler, handler);
1112 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1113 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1116 if (handler != NULL) {
1117 LLNI_class_get(handler, c);
1118 o = (java_handle_t *) handler;
1121 LLNI_class_get(group, c);
1122 o = (java_handle_t *) group;
1125 m = class_resolveclassmethod(c,
1126 utf_uncaughtException,
1127 utf_java_lang_Thread_java_lang_Throwable__V,
1134 (void) vm_call_method(m, o, object, e);
1136 if (exceptions_get_exception())
1140 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1142 /* Remove thread from the thread group. */
1144 if (group != NULL) {
1145 LLNI_class_get(group, c);
1147 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1148 m = class_resolveclassmethod(c,
1150 utf_java_lang_Thread__V,
1151 class_java_lang_ThreadGroup,
1153 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1154 m = class_resolveclassmethod(c,
1156 utf_java_lang_Thread__V,
1157 class_java_lang_ThreadGroup,
1160 # error unknown classpath configuration
1166 o = (java_handle_t *) group;
1168 (void) vm_call_method(m, o, object);
1170 if (exceptions_get_exception())
1173 /* Reset the threadgroup in the Java thread object (Mauve
1174 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1176 LLNI_field_set_ref(object, group, NULL);
1180 /* Thread has terminated. */
1182 thread_set_state_terminated(t);
1184 /* Notify all threads waiting on this thread. These are joining
1187 o = (java_handle_t *) object;
1189 /* XXX Care about exceptions? */
1190 (void) lock_monitor_enter(o);
1192 lock_notify_all_object(o);
1194 /* XXX Care about exceptions? */
1195 (void) lock_monitor_exit(o);
1197 /* Enter the join-mutex before calling thread_free, so
1198 threads_join_all_threads gets the correct number of non-daemon
1201 threads_mutex_join_lock();
1203 /* Free the internal thread data-structure. */
1207 /* Signal that this thread has finished and leave the mutex. */
1209 pthread_cond_signal(&cond_join);
1210 threads_mutex_join_unlock();
1216 /* threads_suspend_thread ******************************************************
1218 Suspend the passed thread. Execution stops until the thread
1219 is explicitly resumend again.
1222 reason.....Reason for suspending this thread.
1224 *******************************************************************************/
1226 bool threads_suspend_thread(threadobject *thread, s4 reason)
1228 /* acquire the suspendmutex */
1229 mutex_lock(&(thread->suspendmutex));
1231 if (thread->suspended) {
1232 mutex_unlock(&(thread->suspendmutex));
1236 /* set the reason for the suspension */
1237 thread->suspend_reason = reason;
1239 /* send the suspend signal to the thread */
1240 assert(thread != THREADOBJECT);
1241 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1242 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1245 /* REMEMBER: do not release the suspendmutex, this is done
1246 by the thread itself in threads_suspend_ack(). */
1252 /* threads_suspend_ack *********************************************************
1254 Acknowledges the suspension of the current thread.
1257 pc.....The PC where the thread suspended its execution.
1258 sp.....The SP before the thread suspended its execution.
1260 *******************************************************************************/
1262 #if defined(ENABLE_GC_CACAO)
1263 void threads_suspend_ack(u1* pc, u1* sp)
1265 threadobject *thread;
1267 thread = THREADOBJECT;
1269 assert(thread->suspend_reason != 0);
1271 /* TODO: remember dump memory size */
1273 /* inform the GC about the suspension */
1274 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1276 /* check if the GC wants to leave the thread running */
1277 if (!gc_suspend(thread, pc, sp)) {
1279 /* REMEMBER: we do not unlock the suspendmutex because the thread
1280 will suspend itself again at a later time */
1286 /* mark this thread as suspended and remember the PC */
1288 thread->suspended = true;
1290 /* if we are stopping the world, we should send a global ack */
1291 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1292 threads_sem_post(&suspend_ack);
1295 DEBUGTHREADS("suspending", thread);
1297 /* release the suspension mutex and wait till we are resumed */
1298 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1300 DEBUGTHREADS("resuming", thread);
1302 /* if we are stopping the world, we should send a global ack */
1303 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1304 threads_sem_post(&suspend_ack);
1307 /* TODO: free dump memory */
1309 /* release the suspendmutex */
1310 mutex_unlock(&(thread->suspendmutex));
1315 /* threads_resume_thread *******************************************************
1317 Resumes the execution of the passed thread.
1319 *******************************************************************************/
1321 #if defined(ENABLE_GC_CACAO)
1322 bool threads_resume_thread(threadobject *thread)
1324 /* acquire the suspendmutex */
1325 mutex_lock(&(thread->suspendmutex));
1327 if (!thread->suspended) {
1328 mutex_unlock(&(thread->suspendmutex));
1332 thread->suspended = false;
1334 /* tell everyone that the thread should resume */
1335 assert(thread != THREADOBJECT);
1336 pthread_cond_broadcast(&(thread->suspendcond));
1338 /* release the suspendmutex */
1339 mutex_unlock(&(thread->suspendmutex));
1346 /* threads_join_all_threads ****************************************************
1348 Join all non-daemon threads.
1350 *******************************************************************************/
1352 void threads_join_all_threads(void)
1356 /* get current thread */
1360 /* This thread is waiting for all non-daemon threads to exit. */
1362 thread_set_state_waiting(t);
1364 /* enter join mutex */
1366 threads_mutex_join_lock();
1368 /* Wait for condition as long as we have non-daemon threads. We
1369 compare against 1 because the current (main thread) is also a
1370 non-daemon thread. */
1372 while (threadlist_get_non_daemons() > 1)
1373 pthread_cond_wait(&cond_join, &mutex_join);
1375 /* leave join mutex */
1377 threads_mutex_join_unlock();
1381 /* threads_timespec_earlier ****************************************************
1383 Return true if timespec tv1 is earlier than timespec tv2.
1386 tv1..........first timespec
1387 tv2..........second timespec
1390 true, if the first timespec is earlier
1392 *******************************************************************************/
1394 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1395 const struct timespec *tv2)
1397 return (tv1->tv_sec < tv2->tv_sec)
1399 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1403 /* threads_current_time_is_earlier_than ****************************************
1405 Check if the current time is earlier than the given timespec.
1408 tv...........the timespec to compare against
1411 true, if the current time is earlier
1413 *******************************************************************************/
1415 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1417 struct timeval tvnow;
1418 struct timespec tsnow;
1420 /* get current time */
1422 if (gettimeofday(&tvnow, NULL) != 0)
1423 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1425 /* convert it to a timespec */
1427 tsnow.tv_sec = tvnow.tv_sec;
1428 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1430 /* compare current time with the given timespec */
1432 return threads_timespec_earlier(&tsnow, tv);
1436 /* threads_wait_with_timeout ***************************************************
1438 Wait until the given point in time on a monitor until either
1439 we are notified, we are interrupted, or the time is up.
1442 t............the current thread
1443 wakeupTime...absolute (latest) wakeup time
1444 If both tv_sec and tv_nsec are zero, this function
1445 waits for an unlimited amount of time.
1447 *******************************************************************************/
1449 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1451 /* acquire the waitmutex */
1453 mutex_lock(&t->waitmutex);
1455 /* wait on waitcond */
1457 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1459 while (!t->interrupted && !t->signaled
1460 && threads_current_time_is_earlier_than(wakeupTime))
1462 thread_set_state_timed_waiting(t);
1464 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1467 thread_set_state_runnable(t);
1472 while (!t->interrupted && !t->signaled) {
1473 thread_set_state_waiting(t);
1475 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1477 thread_set_state_runnable(t);
1481 /* release the waitmutex */
1483 mutex_unlock(&t->waitmutex);
1487 /* threads_wait_with_timeout_relative ******************************************
1489 Wait for the given maximum amount of time on a monitor until either
1490 we are notified, we are interrupted, or the time is up.
1493 t............the current thread
1494 millis.......milliseconds to wait
1495 nanos........nanoseconds to wait
1497 *******************************************************************************/
1499 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1502 struct timespec wakeupTime;
1504 /* calculate the the (latest) wakeup time */
1506 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1510 threads_wait_with_timeout(thread, &wakeupTime);
1514 /* threads_calc_absolute_time **************************************************
1516 Calculate the absolute point in time a given number of ms and ns from now.
1519 millis............milliseconds from now
1520 nanos.............nanoseconds from now
1523 *tm...............receives the timespec of the absolute point in time
1525 *******************************************************************************/
1527 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1529 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1532 gettimeofday(&tv, NULL);
1533 tv.tv_sec += millis / 1000;
1535 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1536 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1537 tm->tv_nsec = nsec % 1000000000;
1546 /* threads_thread_interrupt ****************************************************
1548 Interrupt the given thread.
1550 The thread gets the "waitcond" signal and
1551 its interrupted flag is set to true.
1554 thread............the thread to interrupt
1556 *******************************************************************************/
1558 void threads_thread_interrupt(threadobject *thread)
1560 #if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1561 /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
1562 int sig = (__SIGRTMAX - 2);
1566 /* Signal the thread a "waitcond" and tell it that it has been
1569 mutex_lock(&thread->waitmutex);
1571 DEBUGTHREADS("interrupted", thread);
1573 /* Interrupt blocking system call using a signal. */
1575 pthread_kill(thread->tid, sig);
1577 pthread_cond_signal(&thread->waitcond);
1579 thread->interrupted = true;
1581 mutex_unlock(&thread->waitmutex);
1585 /* threads_sleep ***************************************************************
1587 Sleep the current thread for the specified amount of time.
1589 *******************************************************************************/
1591 void threads_sleep(int64_t millis, int32_t nanos)
1594 struct timespec wakeupTime;
1598 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1599 exceptions_throw_illegalargumentexception();
1603 t = thread_get_current();
1605 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1606 /* Clear interrupted flag (Mauve test:
1607 gnu/testlet/java/lang/Thread/interrupt). */
1609 thread_set_interrupted(t, false);
1611 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1612 exceptions_throw_interruptedexception();
1616 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1618 threads_wait_with_timeout(t, &wakeupTime);
1620 interrupted = thread_is_interrupted(t);
1623 thread_set_interrupted(t, false);
1625 /* An other exception could have been thrown
1626 (e.g. ThreadDeathException). */
1628 if (!exceptions_get_exception())
1629 exceptions_throw_interruptedexception();
1634 /* threads_yield ***************************************************************
1636 Yield to the scheduler.
1638 *******************************************************************************/
1640 void threads_yield(void)
1647 * These are local overrides for various environment variables in Emacs.
1648 * Please do not remove this and leave it at the end of the file, where
1649 * Emacs will automagically detect them.
1650 * ---------------------------------------------------------------------
1653 * indent-tabs-mode: t
1657 * vim:noexpandtab:sw=4:ts=4: