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/condition.hpp"
77 #include "threads/lock-common.h"
78 #include "threads/mutex.hpp"
79 #include "threads/threadlist.h"
80 #include "threads/thread.h"
82 #include "toolbox/logging.h"
84 #include "vm/builtin.h"
85 #include "vm/exceptions.h"
86 #include "vm/global.h"
87 #include "vm/stringlocal.h"
90 #include "vm/jit/asmpart.h"
92 #include "vmcore/options.h"
94 #if defined(ENABLE_STATISTICS)
95 # include "vmcore/statistics.h"
98 #if !defined(__DARWIN__)
99 # include <semaphore.h>
102 #if defined(__LINUX__)
103 # define GC_LINUX_THREADS
104 #elif defined(__IRIX__)
105 # define GC_IRIX_THREADS
106 #elif defined(__DARWIN__)
107 # define GC_DARWIN_THREADS
110 #if defined(ENABLE_GC_BOEHM)
111 /* We need to include Boehm's gc.h here because it overrides
112 pthread_create and friends. */
113 # include "mm/boehm-gc/include/gc.h"
116 #if defined(ENABLE_JVMTI)
117 #include "native/jvmti/cacaodbg.h"
120 #if defined(__DARWIN__)
121 /* Darwin has no working semaphore implementation. This one is taken
125 This is a very simple semaphore implementation for darwin. It
126 is implemented in terms of pthreads calls so it isn't async signal
127 safe. This isn't a problem because signals aren't used to
128 suspend threads on darwin.
131 static int sem_init(sem_t *sem, int pshared, int value)
138 sem->mutex = Mutex_new();
140 if (pthread_cond_init(&sem->cond, NULL) < 0)
146 static int sem_post(sem_t *sem)
148 Mutex_lock(sem->mutex);
152 if (pthread_cond_signal(&sem->cond) < 0) {
153 Mutex_unlock(sem->mutex);
157 Mutex_unlock(sem->mutex);
162 static int sem_wait(sem_t *sem)
164 Mutex_lock(sem->mutex);
166 while (sem->value == 0) {
167 #error We cannot call pthread_cond_wait on a Mutex-class pointer.
168 pthread_cond_wait(&sem->cond, &sem->mutex);
173 Mutex_unlock(sem->mutex);
178 static int sem_destroy(sem_t *sem)
180 if (pthread_cond_destroy(&sem->cond) < 0)
183 Mutex_destroy(sem->mutex);
187 #endif /* defined(__DARWIN__) */
190 /* startupinfo *****************************************************************
192 Struct used to pass info from threads_start_thread to
193 threads_startup_thread.
195 ******************************************************************************/
198 threadobject *thread; /* threadobject for this thread */
199 functionptr function; /* function to run in the new thread */
200 sem_t *psem; /* signals when thread has been entered */
201 /* in the thread list */
202 sem_t *psem_first; /* signals when pthread_create has returned */
206 /* prototypes *****************************************************************/
208 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
211 /******************************************************************************/
212 /* GLOBAL VARIABLES */
213 /******************************************************************************/
215 /* the thread object of the current thread */
216 /* This is either a thread-local variable defined with __thread, or */
217 /* a thread-specific value stored with key threads_current_threadobject_key. */
218 #if defined(HAVE___THREAD)
219 __thread threadobject *thread_current;
221 pthread_key_t thread_current_key;
224 /* global mutex for stop-the-world */
225 static Mutex* stopworldlock;
227 #if defined(ENABLE_GC_CACAO)
228 /* global mutex for the GC */
229 static Mutex* mutex_gc;
232 /* global mutex and condition for joining threads on exit */
233 static Mutex* mutex_join;
234 static Condition* cond_join;
236 #if defined(ENABLE_GC_CACAO)
237 /* semaphore used for acknowleding thread suspension */
238 static sem_t suspend_ack;
241 /* mutexes used by the fake atomic instructions */
242 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
243 mutex_t _cas_lock = MUTEX_INITIALIZER;
244 mutex_t _mb_lock = MUTEX_INITIALIZER;
248 /* threads_sem_init ************************************************************
250 Initialize a semaphore. Checks against errors and interruptions.
253 sem..............the semaphore to initialize
254 shared...........true if this semaphore will be shared between processes
255 value............the initial value for the semaphore
257 *******************************************************************************/
259 void threads_sem_init(sem_t *sem, bool shared, int value)
266 r = sem_init(sem, shared, value);
269 } while (errno == EINTR);
271 vm_abort("sem_init failed: %s", strerror(errno));
275 /* threads_sem_wait ************************************************************
277 Wait for a semaphore, non-interruptible.
279 IMPORTANT: Always use this function instead of `sem_wait` directly, as
280 `sem_wait` may be interrupted by signals!
283 sem..............the semaphore to wait on
285 *******************************************************************************/
287 void threads_sem_wait(sem_t *sem)
297 } while (errno == EINTR);
299 vm_abort("sem_wait failed: %s", strerror(errno));
303 /* threads_sem_post ************************************************************
305 Increase the count of a semaphore. Checks for errors.
308 sem..............the semaphore to increase the count of
310 *******************************************************************************/
312 void threads_sem_post(sem_t *sem)
318 /* unlike sem_wait, sem_post is not interruptible */
324 vm_abort("sem_post failed: %s", strerror(errno));
328 /* threads_stopworld ***********************************************************
330 Stops the world from turning. All threads except the calling one
331 are suspended. The function returns as soon as all threads have
332 acknowledged their suspension.
334 *******************************************************************************/
336 #if defined(ENABLE_GC_CACAO)
337 void threads_stopworld(void)
339 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
346 Mutex_lock(stopworldlock);
348 /* lock the threads lists */
352 #if defined(__DARWIN__)
353 /*threads_cast_darwinstop();*/
355 #elif defined(__CYGWIN__)
361 DEBUGTHREADS("stops World", self);
365 /* suspend all running threads */
366 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
367 /* don't send the signal to ourself */
372 /* don't send the signal to NEW threads (because they are not
373 completely initialized) */
375 if (t->state == THREAD_STATE_NEW)
378 /* send the signal */
380 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
383 /* increase threads count */
388 /* wait for all threads signaled to suspend */
389 for (i = 0; i < count; i++)
390 threads_sem_wait(&suspend_ack);
393 /* ATTENTION: Don't unlock the threads-lists here so that
394 non-signaled NEW threads can't change their state and execute
400 /* threads_startworld **********************************************************
402 Starts the world again after it has previously been stopped.
404 *******************************************************************************/
406 #if defined(ENABLE_GC_CACAO)
407 void threads_startworld(void)
409 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
416 #if defined(__DARWIN__)
417 /*threads_cast_darwinresume();*/
419 #elif defined(__IRIX__)
420 threads_cast_irixresume();
421 #elif defined(__CYGWIN__)
427 DEBUGTHREADS("starts World", self);
431 /* resume all thread we haltet */
432 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
433 /* don't send the signal to ourself */
438 /* don't send the signal to NEW threads (because they are not
439 completely initialized) */
441 if (t->state == THREAD_STATE_NEW)
444 /* send the signal */
446 result = threads_resume_thread(t);
449 /* increase threads count */
454 /* wait for all threads signaled to suspend */
455 for (i = 0; i < count; i++)
456 threads_sem_wait(&suspend_ack);
460 /* unlock the threads lists */
464 Mutex_unlock(stopworldlock);
469 /* threads_impl_thread_init ****************************************************
471 Initialize OS-level locking constructs in threadobject.
474 t....the threadobject
476 *******************************************************************************/
478 void threads_impl_thread_init(threadobject *t)
480 /* initialize the mutex and the condition */
482 t->flc_lock = Mutex_new();
483 t->flc_cond = Condition_new();
485 t->waitmutex = Mutex_new();
486 t->waitcond = Condition_new();
488 t->suspendmutex = Mutex_new();
489 t->suspendcond = Condition_new();
492 /* threads_impl_thread_clear ***************************************************
494 Clears all fields in threadobject the way an MZERO would have
495 done. MZERO cannot be used anymore because it would mess up the
499 t....the threadobject
501 *******************************************************************************/
503 void threads_impl_thread_clear(threadobject *t)
515 #if defined(__DARWIN__)
519 t->interrupted = false;
522 t->suspended = false;
523 t->suspend_reason = 0;
527 t->_exceptionptr = NULL;
528 t->_stackframeinfo = NULL;
529 t->_localref_table = NULL;
531 #if defined(ENABLE_INTRP)
532 t->_global_sp = NULL;
535 #if defined(ENABLE_GC_CACAO)
536 t->gc_critical = false;
542 MZERO(&t->dumpinfo, dumpinfo_t, 1);
545 /* threads_impl_thread_reuse ***************************************************
547 Resets some implementation fields in threadobject. This was
548 previously done in threads_impl_thread_new.
551 t....the threadobject
553 *******************************************************************************/
555 void threads_impl_thread_reuse(threadobject *t)
557 /* get the pthread id */
559 t->tid = pthread_self();
561 #if defined(ENABLE_DEBUG_FILTER)
562 /* Initialize filter counters */
563 t->filterverbosecallctr[0] = 0;
564 t->filterverbosecallctr[1] = 0;
568 t->tracejavacallindent = 0;
569 t->tracejavacallcount = 0;
576 /* not really needed */
577 t->flc_object = NULL;
581 /* threads_impl_thread_free ****************************************************
583 Cleanup thread stuff.
586 t....the threadobject
588 *******************************************************************************/
592 void threads_impl_thread_free(threadobject *t)
596 /* Destroy the mutex and the condition. */
598 Mutex_delete(t->flc_lock);
600 result = pthread_cond_destroy(&(t->flc_cond));
603 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
605 Mutex_delete(t->waitmutex);
607 result = pthread_cond_destroy(&(t->waitcond));
610 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
612 Mutex_delete(t->suspendmutex);
614 result = pthread_cond_destroy(&(t->suspendcond));
617 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
622 /* threads_impl_preinit ********************************************************
624 Do some early initialization of stuff required.
626 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
627 is called AFTER this function!
629 *******************************************************************************/
631 void threads_impl_preinit(void)
635 stopworldlock = Mutex_new();
637 /* initialize exit mutex and condition (on exit we join all
640 mutex_join = Mutex_new();
641 cond_join = Condition_new();
643 #if defined(ENABLE_GC_CACAO)
644 /* initialize the GC mutex & suspend semaphore */
646 mutex_gc = Mutex_new();
647 threads_sem_init(&suspend_ack, 0, 0);
650 #if !defined(HAVE___THREAD)
651 result = pthread_key_create(&thread_current_key, NULL);
653 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
658 /* threads_mutex_gc_lock *******************************************************
660 Enter the global GC mutex.
662 *******************************************************************************/
664 #if defined(ENABLE_GC_CACAO)
665 void threads_mutex_gc_lock(void)
667 Mutex_lock(mutex_gc);
672 /* threads_mutex_gc_unlock *****************************************************
674 Leave the global GC mutex.
676 *******************************************************************************/
678 #if defined(ENABLE_GC_CACAO)
679 void threads_mutex_gc_unlock(void)
681 Mutex_unlock(mutex_gc);
685 /* threads_mutex_join_lock *****************************************************
687 Enter the join mutex.
689 *******************************************************************************/
691 void threads_mutex_join_lock(void)
693 Mutex_lock(mutex_join);
697 /* threads_mutex_join_unlock ***************************************************
699 Leave the join mutex.
701 *******************************************************************************/
703 void threads_mutex_join_unlock(void)
705 Mutex_unlock(mutex_join);
709 /* threads_impl_init ***********************************************************
711 Initializes the implementation specific bits.
713 *******************************************************************************/
715 void threads_impl_init(void)
720 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
722 /* Initialize the thread attribute object. */
724 result = pthread_attr_init(&attr);
727 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
729 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
732 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
736 /* threads_startup_thread ******************************************************
738 Thread startup function called by pthread_create.
740 Thread which have a startup.function != NULL are marked as internal
741 threads. All other threads are threated as normal Java threads.
743 NOTE: This function is not called directly by pthread_create. The Boehm GC
744 inserts its own GC_start_routine in between, which then calls
748 arg..........the argument passed to pthread_create, ie. a pointer to
749 a startupinfo struct. CAUTION: When the `psem` semaphore
750 is posted, the startupinfo struct becomes invalid! (It
751 is allocated on the stack of threads_start_thread.)
753 ******************************************************************************/
755 static void *threads_startup_thread(void *arg)
757 startupinfo *startup;
759 java_lang_Thread *object;
760 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
761 java_lang_VMThread *vmt;
767 functionptr function;
769 #if defined(ENABLE_GC_BOEHM)
770 # if !defined(__DARWIN__)
771 struct GC_stack_base sb;
776 #if defined(ENABLE_INTRP)
777 u1 *intrp_thread_stack;
780 #if defined(ENABLE_INTRP)
781 /* create interpreter stack */
784 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
785 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
788 intrp_thread_stack = NULL;
791 /* get passed startupinfo structure and the values in there */
796 function = startup->function;
797 psem = startup->psem;
799 /* Seems like we've encountered a situation where thread->tid was
800 not set by pthread_create. We alleviate this problem by waiting
801 for pthread_create to return. */
803 threads_sem_wait(startup->psem_first);
805 #if defined(__DARWIN__)
806 t->mach_thread = mach_thread_self();
809 /* Now that we are in the new thread, we can store the internal
810 thread data-structure in the TSD. */
812 thread_set_current(t);
814 #if defined(ENABLE_GC_BOEHM)
815 # if defined(__DARWIN__)
816 // This is currently not implemented in Boehm-GC. Just fail silently.
818 /* Register the thread with Boehm-GC. This must happen before the
819 thread allocates any memory from the GC heap.*/
821 result = GC_get_stack_base(&sb);
824 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
826 GC_register_my_thread(&sb);
830 /* get the java.lang.Thread object for this thread */
832 object = (java_lang_Thread *) thread_get_object(t);
834 /* set our priority */
836 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
838 /* Thread is completely initialized. */
840 thread_set_state_runnable(t);
842 /* tell threads_startup_thread that we registered ourselves */
843 /* CAUTION: *startup becomes invalid with this! */
846 threads_sem_post(psem);
848 #if defined(ENABLE_INTRP)
849 /* set interpreter stack */
852 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
855 #if defined(ENABLE_JVMTI)
856 /* fire thread start event */
859 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
862 DEBUGTHREADS("starting", t);
864 /* find and run the Thread.run()V method if no other function was passed */
866 if (function == NULL) {
867 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
868 /* We need to start the run method of
869 java.lang.VMThread. Since this is a final class, we can use
870 the class object directly. */
872 c = class_java_lang_VMThread;
873 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
874 LLNI_class_get(object, c);
876 # error unknown classpath configuration
879 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
882 vm_abort("threads_startup_thread: run() method not found in class");
884 /* set ThreadMXBean variables */
886 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
887 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
889 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
890 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
891 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
892 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
894 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
895 /* we need to start the run method of java.lang.VMThread */
897 LLNI_field_get_ref(object, vmThread, vmt);
898 o = (java_handle_t *) vmt;
900 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
901 o = (java_handle_t *) object;
903 # error unknown classpath configuration
906 /* Run the thread. */
908 (void) vm_call_method(m, o);
911 /* set ThreadMXBean variables */
913 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
914 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
916 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
917 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
918 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
919 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
921 /* call passed function, e.g. finalizer_thread */
926 DEBUGTHREADS("stopping", t);
928 #if defined(ENABLE_JVMTI)
929 /* fire thread end event */
932 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
935 /* We ignore the return value. */
937 (void) thread_detach_current_thread();
939 /* set ThreadMXBean variables */
941 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
947 /* threads_impl_thread_start ***************************************************
949 Start a thread in the JVM. Both (vm internal and java) thread
953 thread....the thread object
954 f.........function to run in the new thread. NULL means that the
955 "run" method of the object `t` should be called
957 ******************************************************************************/
959 void threads_impl_thread_start(threadobject *thread, functionptr f)
967 /* fill startupinfo structure passed by pthread_create to
968 * threads_startup_thread */
970 startup.thread = thread;
971 startup.function = f; /* maybe we don't call Thread.run()V */
973 startup.psem_first = &sem_first;
975 threads_sem_init(&sem, 0, 0);
976 threads_sem_init(&sem_first, 0, 0);
978 /* Initialize thread attributes. */
980 result = pthread_attr_init(&attr);
983 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
985 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
988 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
990 /* initialize thread stacksize */
992 result = pthread_attr_setstacksize(&attr, opt_stacksize);
995 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
997 /* create the thread */
999 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1002 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1004 /* destroy the thread attributes */
1006 result = pthread_attr_destroy(&attr);
1009 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1011 /* signal that pthread_create has returned, so thread->tid is valid */
1013 threads_sem_post(&sem_first);
1015 /* wait here until the thread has entered itself into the thread list */
1017 threads_sem_wait(&sem);
1022 sem_destroy(&sem_first);
1026 /* threads_set_thread_priority *************************************************
1028 Set the priority of the given thread.
1031 tid..........thread id
1032 priority.....priority to set
1034 ******************************************************************************/
1036 void threads_set_thread_priority(pthread_t tid, int priority)
1038 struct sched_param schedp;
1041 pthread_getschedparam(tid, &policy, &schedp);
1042 schedp.sched_priority = priority;
1043 pthread_setschedparam(tid, policy, &schedp);
1048 * Detaches the current thread from the VM.
1050 * @return true on success, false otherwise
1052 bool thread_detach_current_thread(void)
1056 java_lang_Thread *object;
1058 #if defined(ENABLE_JAVASE)
1059 java_lang_ThreadGroup *group;
1066 t = thread_get_current();
1072 /* If the given thread has already been detached, this operation
1075 result = thread_is_attached(t);
1077 if (result == false)
1080 DEBUGTHREADS("detaching", t);
1082 object = (java_lang_Thread *) thread_get_object(t);
1084 #if defined(ENABLE_JAVASE)
1085 LLNI_field_get_ref(object, group, group);
1087 /* If there's an uncaught exception, call uncaughtException on the
1088 thread's exception handler, or the thread's group if this is
1091 e = exceptions_get_and_clear_exception();
1094 /* We use the type void* for handler here, as it's not trivial
1095 to build the java_lang_Thread_UncaughtExceptionHandler
1096 header file with cacaoh. */
1098 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1099 LLNI_field_get_ref(object, exceptionHandler, handler);
1100 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1101 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1104 if (handler != NULL) {
1105 LLNI_class_get(handler, c);
1106 o = (java_handle_t *) handler;
1109 LLNI_class_get(group, c);
1110 o = (java_handle_t *) group;
1113 m = class_resolveclassmethod(c,
1114 utf_uncaughtException,
1115 utf_java_lang_Thread_java_lang_Throwable__V,
1122 (void) vm_call_method(m, o, object, e);
1124 if (exceptions_get_exception())
1128 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1130 /* Remove thread from the thread group. */
1132 if (group != NULL) {
1133 LLNI_class_get(group, c);
1135 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1136 m = class_resolveclassmethod(c,
1138 utf_java_lang_Thread__V,
1139 class_java_lang_ThreadGroup,
1141 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1142 m = class_resolveclassmethod(c,
1144 utf_java_lang_Thread__V,
1145 class_java_lang_ThreadGroup,
1148 # error unknown classpath configuration
1154 o = (java_handle_t *) group;
1156 (void) vm_call_method(m, o, object);
1158 if (exceptions_get_exception())
1161 /* Reset the threadgroup in the Java thread object (Mauve
1162 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1164 LLNI_field_set_ref(object, group, NULL);
1168 /* Thread has terminated. */
1170 thread_set_state_terminated(t);
1172 /* Notify all threads waiting on this thread. These are joining
1175 o = (java_handle_t *) object;
1177 /* XXX Care about exceptions? */
1178 (void) lock_monitor_enter(o);
1180 lock_notify_all_object(o);
1182 /* XXX Care about exceptions? */
1183 (void) lock_monitor_exit(o);
1185 /* Enter the join-mutex before calling thread_free, so
1186 threads_join_all_threads gets the correct number of non-daemon
1189 threads_mutex_join_lock();
1191 /* Free the internal thread data-structure. */
1195 /* Signal that this thread has finished and leave the mutex. */
1197 Condition_signal(cond_join);
1198 threads_mutex_join_unlock();
1204 /* threads_suspend_thread ******************************************************
1206 Suspend the passed thread. Execution stops until the thread
1207 is explicitly resumend again.
1210 reason.....Reason for suspending this thread.
1212 *******************************************************************************/
1214 bool threads_suspend_thread(threadobject *thread, s4 reason)
1216 /* acquire the suspendmutex */
1217 Mutex_lock(thread->suspendmutex);
1219 if (thread->suspended) {
1220 Mutex_unlock(thread->suspendmutex);
1224 /* set the reason for the suspension */
1225 thread->suspend_reason = reason;
1227 /* send the suspend signal to the thread */
1228 assert(thread != THREADOBJECT);
1229 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1230 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1233 /* REMEMBER: do not release the suspendmutex, this is done
1234 by the thread itself in threads_suspend_ack(). */
1240 /* threads_suspend_ack *********************************************************
1242 Acknowledges the suspension of the current thread.
1245 pc.....The PC where the thread suspended its execution.
1246 sp.....The SP before the thread suspended its execution.
1248 *******************************************************************************/
1250 #if defined(ENABLE_GC_CACAO)
1251 void threads_suspend_ack(u1* pc, u1* sp)
1253 threadobject *thread;
1255 thread = THREADOBJECT;
1257 assert(thread->suspend_reason != 0);
1259 /* TODO: remember dump memory size */
1261 /* inform the GC about the suspension */
1262 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1264 /* check if the GC wants to leave the thread running */
1265 if (!gc_suspend(thread, pc, sp)) {
1267 /* REMEMBER: we do not unlock the suspendmutex because the thread
1268 will suspend itself again at a later time */
1274 /* mark this thread as suspended and remember the PC */
1276 thread->suspended = true;
1278 /* if we are stopping the world, we should send a global ack */
1279 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1280 threads_sem_post(&suspend_ack);
1283 DEBUGTHREADS("suspending", thread);
1285 /* release the suspension mutex and wait till we are resumed */
1286 Condition_wait(thread->suspendcond, thread->suspendmutex);
1288 DEBUGTHREADS("resuming", thread);
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 /* TODO: free dump memory */
1297 /* release the suspendmutex */
1298 Mutex_unlock(thread->suspendmutex);
1303 /* threads_resume_thread *******************************************************
1305 Resumes the execution of the passed thread.
1307 *******************************************************************************/
1309 #if defined(ENABLE_GC_CACAO)
1310 bool threads_resume_thread(threadobject *thread)
1312 /* acquire the suspendmutex */
1313 Mutex_lock(thread->suspendmutex);
1315 if (!thread->suspended) {
1316 Mutex_unlock(thread->suspendmutex);
1320 thread->suspended = false;
1322 /* tell everyone that the thread should resume */
1323 assert(thread != THREADOBJECT);
1324 Condition_broadcast(thread->suspendcond);
1326 /* release the suspendmutex */
1327 Mutex_unlock(thread->suspendmutex);
1334 /* threads_join_all_threads ****************************************************
1336 Join all non-daemon threads.
1338 *******************************************************************************/
1340 void threads_join_all_threads(void)
1344 /* get current thread */
1348 /* This thread is waiting for all non-daemon threads to exit. */
1350 thread_set_state_waiting(t);
1352 /* enter join mutex */
1354 threads_mutex_join_lock();
1356 /* Wait for condition as long as we have non-daemon threads. We
1357 compare against 1 because the current (main thread) is also a
1358 non-daemon thread. */
1360 while (threadlist_get_non_daemons() > 1)
1361 Condition_wait(cond_join, mutex_join);
1363 /* leave join mutex */
1365 threads_mutex_join_unlock();
1369 /* threads_timespec_earlier ****************************************************
1371 Return true if timespec tv1 is earlier than timespec tv2.
1374 tv1..........first timespec
1375 tv2..........second timespec
1378 true, if the first timespec is earlier
1380 *******************************************************************************/
1382 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1383 const struct timespec *tv2)
1385 return (tv1->tv_sec < tv2->tv_sec)
1387 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1391 /* threads_current_time_is_earlier_than ****************************************
1393 Check if the current time is earlier than the given timespec.
1396 tv...........the timespec to compare against
1399 true, if the current time is earlier
1401 *******************************************************************************/
1403 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1405 struct timeval tvnow;
1406 struct timespec tsnow;
1408 /* get current time */
1410 if (gettimeofday(&tvnow, NULL) != 0)
1411 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1413 /* convert it to a timespec */
1415 tsnow.tv_sec = tvnow.tv_sec;
1416 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1418 /* compare current time with the given timespec */
1420 return threads_timespec_earlier(&tsnow, tv);
1424 /* threads_wait_with_timeout ***************************************************
1426 Wait until the given point in time on a monitor until either
1427 we are notified, we are interrupted, or the time is up.
1430 t............the current thread
1431 wakeupTime...absolute (latest) wakeup time
1432 If both tv_sec and tv_nsec are zero, this function
1433 waits for an unlimited amount of time.
1435 *******************************************************************************/
1437 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1439 /* acquire the waitmutex */
1441 Mutex_lock(t->waitmutex);
1443 /* wait on waitcond */
1445 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1447 while (!t->interrupted && !t->signaled
1448 && threads_current_time_is_earlier_than(wakeupTime))
1450 thread_set_state_timed_waiting(t);
1452 Condition_timedwait(t->waitcond, t->waitmutex, wakeupTime);
1454 thread_set_state_runnable(t);
1459 while (!t->interrupted && !t->signaled) {
1460 thread_set_state_waiting(t);
1462 Condition_wait(t->waitcond, t->waitmutex);
1464 thread_set_state_runnable(t);
1468 /* release the waitmutex */
1470 Mutex_unlock(t->waitmutex);
1474 /* threads_wait_with_timeout_relative ******************************************
1476 Wait for the given maximum amount of time on a monitor until either
1477 we are notified, we are interrupted, or the time is up.
1480 t............the current thread
1481 millis.......milliseconds to wait
1482 nanos........nanoseconds to wait
1484 *******************************************************************************/
1486 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1489 struct timespec wakeupTime;
1491 /* calculate the the (latest) wakeup time */
1493 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1497 threads_wait_with_timeout(thread, &wakeupTime);
1501 /* threads_calc_absolute_time **************************************************
1503 Calculate the absolute point in time a given number of ms and ns from now.
1506 millis............milliseconds from now
1507 nanos.............nanoseconds from now
1510 *tm...............receives the timespec of the absolute point in time
1512 *******************************************************************************/
1514 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1516 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1519 gettimeofday(&tv, NULL);
1520 tv.tv_sec += millis / 1000;
1522 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1523 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1524 tm->tv_nsec = nsec % 1000000000;
1533 /* threads_thread_interrupt ****************************************************
1535 Interrupt the given thread.
1537 The thread gets the "waitcond" signal and
1538 its interrupted flag is set to true.
1541 thread............the thread to interrupt
1543 *******************************************************************************/
1545 void threads_thread_interrupt(threadobject *thread)
1547 #if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1548 /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
1549 int sig = (__SIGRTMAX - 2);
1553 /* Signal the thread a "waitcond" and tell it that it has been
1556 Mutex_lock(thread->waitmutex);
1558 DEBUGTHREADS("interrupted", thread);
1560 /* Interrupt blocking system call using a signal. */
1562 pthread_kill(thread->tid, sig);
1564 Condition_signal(thread->waitcond);
1566 thread->interrupted = true;
1568 Mutex_unlock(thread->waitmutex);
1572 /* threads_sleep ***************************************************************
1574 Sleep the current thread for the specified amount of time.
1576 *******************************************************************************/
1578 void threads_sleep(int64_t millis, int32_t nanos)
1581 struct timespec wakeupTime;
1585 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1586 exceptions_throw_illegalargumentexception();
1590 t = thread_get_current();
1592 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1593 /* Clear interrupted flag (Mauve test:
1594 gnu/testlet/java/lang/Thread/interrupt). */
1596 thread_set_interrupted(t, false);
1598 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1599 exceptions_throw_interruptedexception();
1603 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1605 threads_wait_with_timeout(t, &wakeupTime);
1607 interrupted = thread_is_interrupted(t);
1610 thread_set_interrupted(t, false);
1612 /* An other exception could have been thrown
1613 (e.g. ThreadDeathException). */
1615 if (!exceptions_get_exception())
1616 exceptions_throw_interruptedexception();
1621 /* threads_yield ***************************************************************
1623 Yield to the scheduler.
1625 *******************************************************************************/
1627 void threads_yield(void)
1634 * These are local overrides for various environment variables in Emacs.
1635 * Please do not remove this and leave it at the end of the file, where
1636 * Emacs will automagically detect them.
1637 * ---------------------------------------------------------------------
1640 * indent-tabs-mode: t
1644 * vim:noexpandtab:sw=4:ts=4: