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>
47 #include "mm/memory.h"
49 #if defined(ENABLE_GC_CACAO)
50 # include "mm/cacao-gc/gc.h"
53 #include "native/jni.h"
54 #include "native/llni.h"
55 #include "native/native.h"
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_String.h"
59 #include "native/include/java_lang_Throwable.h"
60 #include "native/include/java_lang_Thread.h"
62 #if defined(ENABLE_JAVASE)
63 # include "native/include/java_lang_ThreadGroup.h"
66 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
67 # include "native/include/java_lang_VMThread.h"
70 #include "threads/condition.hpp"
71 #include "threads/lock-common.h"
72 #include "threads/mutex.hpp"
73 #include "threads/threadlist.h"
74 #include "threads/thread.h"
76 #include "toolbox/logging.h"
78 #include "vm/builtin.h"
79 #include "vm/exceptions.h"
80 #include "vm/global.h"
81 #include "vm/stringlocal.h"
84 #include "vm/jit/asmpart.h"
86 #include "vmcore/globals.hpp"
87 #include "vmcore/options.h"
89 #if defined(ENABLE_STATISTICS)
90 # include "vmcore/statistics.h"
93 #if !defined(__DARWIN__)
94 # include <semaphore.h>
97 #if defined(__LINUX__)
98 # define GC_LINUX_THREADS
99 #elif defined(__IRIX__)
100 # define GC_IRIX_THREADS
101 #elif defined(__DARWIN__)
102 # define GC_DARWIN_THREADS
105 #if defined(ENABLE_GC_BOEHM)
106 /* We need to include Boehm's gc.h here because it overrides
107 pthread_create and friends. */
108 # include "mm/boehm-gc/include/gc.h"
111 #if defined(ENABLE_JVMTI)
112 #include "native/jvmti/cacaodbg.h"
115 #if defined(__DARWIN__)
116 /* Darwin has no working semaphore implementation. This one is taken
120 This is a very simple semaphore implementation for darwin. It
121 is implemented in terms of pthreads calls so it isn't async signal
122 safe. This isn't a problem because signals aren't used to
123 suspend threads on darwin.
126 static int sem_init(sem_t *sem, int pshared, int value)
133 sem->mutex = Mutex_new();
135 if (pthread_cond_init(&sem->cond, NULL) < 0)
141 static int sem_post(sem_t *sem)
143 Mutex_lock(sem->mutex);
147 if (pthread_cond_signal(&sem->cond) < 0) {
148 Mutex_unlock(sem->mutex);
152 Mutex_unlock(sem->mutex);
157 static int sem_wait(sem_t *sem)
159 Mutex_lock(sem->mutex);
161 while (sem->value == 0) {
162 #error We cannot call pthread_cond_wait on a Mutex-class pointer.
163 pthread_cond_wait(&sem->cond, &sem->mutex);
168 Mutex_unlock(sem->mutex);
173 static int sem_destroy(sem_t *sem)
175 if (pthread_cond_destroy(&sem->cond) < 0)
178 Mutex_destroy(sem->mutex);
182 #endif /* defined(__DARWIN__) */
185 /* startupinfo *****************************************************************
187 Struct used to pass info from threads_start_thread to
188 threads_startup_thread.
190 ******************************************************************************/
193 threadobject *thread; /* threadobject for this thread */
194 functionptr function; /* function to run in the new thread */
195 sem_t *psem; /* signals when thread has been entered */
196 /* in the thread list */
197 sem_t *psem_first; /* signals when pthread_create has returned */
201 /* prototypes *****************************************************************/
203 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
206 /******************************************************************************/
207 /* GLOBAL VARIABLES */
208 /******************************************************************************/
210 /* the thread object of the current thread */
211 /* This is either a thread-local variable defined with __thread, or */
212 /* a thread-specific value stored with key threads_current_threadobject_key. */
213 #if defined(HAVE___THREAD)
214 __thread threadobject *thread_current;
216 pthread_key_t thread_current_key;
219 /* global mutex for stop-the-world */
220 static Mutex* stopworldlock;
222 #if defined(ENABLE_GC_CACAO)
223 /* global mutex for the GC */
224 static Mutex* mutex_gc;
227 /* global mutex and condition for joining threads on exit */
228 static Mutex* mutex_join;
229 static Condition* cond_join;
231 #if defined(ENABLE_GC_CACAO)
232 /* semaphore used for acknowleding thread suspension */
233 static sem_t suspend_ack;
237 /* threads_sem_init ************************************************************
239 Initialize a semaphore. Checks against errors and interruptions.
242 sem..............the semaphore to initialize
243 shared...........true if this semaphore will be shared between processes
244 value............the initial value for the semaphore
246 *******************************************************************************/
248 void threads_sem_init(sem_t *sem, bool shared, int value)
255 r = sem_init(sem, shared, value);
258 } while (errno == EINTR);
260 vm_abort("sem_init failed: %s", strerror(errno));
264 /* threads_sem_wait ************************************************************
266 Wait for a semaphore, non-interruptible.
268 IMPORTANT: Always use this function instead of `sem_wait` directly, as
269 `sem_wait` may be interrupted by signals!
272 sem..............the semaphore to wait on
274 *******************************************************************************/
276 void threads_sem_wait(sem_t *sem)
286 } while (errno == EINTR);
288 vm_abort("sem_wait failed: %s", strerror(errno));
292 /* threads_sem_post ************************************************************
294 Increase the count of a semaphore. Checks for errors.
297 sem..............the semaphore to increase the count of
299 *******************************************************************************/
301 void threads_sem_post(sem_t *sem)
307 /* unlike sem_wait, sem_post is not interruptible */
313 vm_abort("sem_post failed: %s", strerror(errno));
317 /* threads_stopworld ***********************************************************
319 Stops the world from turning. All threads except the calling one
320 are suspended. The function returns as soon as all threads have
321 acknowledged their suspension.
323 *******************************************************************************/
325 #if defined(ENABLE_GC_CACAO)
326 void threads_stopworld(void)
328 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
335 Mutex_lock(stopworldlock);
337 /* lock the threads lists */
341 #if defined(__DARWIN__)
342 /*threads_cast_darwinstop();*/
344 #elif defined(__CYGWIN__)
350 DEBUGTHREADS("stops World", self);
354 /* suspend all running threads */
355 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
356 /* don't send the signal to ourself */
361 /* don't send the signal to NEW threads (because they are not
362 completely initialized) */
364 if (t->state == THREAD_STATE_NEW)
367 /* send the signal */
369 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
372 /* increase threads count */
377 /* wait for all threads signaled to suspend */
378 for (i = 0; i < count; i++)
379 threads_sem_wait(&suspend_ack);
382 /* ATTENTION: Don't unlock the threads-lists here so that
383 non-signaled NEW threads can't change their state and execute
389 /* threads_startworld **********************************************************
391 Starts the world again after it has previously been stopped.
393 *******************************************************************************/
395 #if defined(ENABLE_GC_CACAO)
396 void threads_startworld(void)
398 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
405 #if defined(__DARWIN__)
406 /*threads_cast_darwinresume();*/
408 #elif defined(__IRIX__)
409 threads_cast_irixresume();
410 #elif defined(__CYGWIN__)
416 DEBUGTHREADS("starts World", self);
420 /* resume all thread we haltet */
421 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
422 /* don't send the signal to ourself */
427 /* don't send the signal to NEW threads (because they are not
428 completely initialized) */
430 if (t->state == THREAD_STATE_NEW)
433 /* send the signal */
435 result = threads_resume_thread(t);
438 /* increase threads count */
443 /* wait for all threads signaled to suspend */
444 for (i = 0; i < count; i++)
445 threads_sem_wait(&suspend_ack);
449 /* unlock the threads lists */
453 Mutex_unlock(stopworldlock);
458 /* threads_impl_thread_init ****************************************************
460 Initialize OS-level locking constructs in threadobject.
463 t....the threadobject
465 *******************************************************************************/
467 void threads_impl_thread_init(threadobject *t)
469 /* initialize the mutex and the condition */
471 t->flc_lock = Mutex_new();
472 t->flc_cond = Condition_new();
474 t->waitmutex = Mutex_new();
475 t->waitcond = Condition_new();
477 t->suspendmutex = Mutex_new();
478 t->suspendcond = Condition_new();
480 #if defined(ENABLE_TLH)
485 /* threads_impl_thread_clear ***************************************************
487 Clears all fields in threadobject the way an MZERO would have
488 done. MZERO cannot be used anymore because it would mess up the
492 t....the threadobject
494 *******************************************************************************/
496 void threads_impl_thread_clear(threadobject *t)
508 #if defined(__DARWIN__)
512 t->interrupted = false;
515 t->suspended = false;
516 t->suspend_reason = 0;
520 t->_exceptionptr = NULL;
521 t->_stackframeinfo = NULL;
522 t->_localref_table = NULL;
524 #if defined(ENABLE_INTRP)
525 t->_global_sp = NULL;
528 #if defined(ENABLE_GC_CACAO)
529 t->gc_critical = false;
535 MZERO(&t->dumpinfo, dumpinfo_t, 1);
538 /* threads_impl_thread_reuse ***************************************************
540 Resets some implementation fields in threadobject. This was
541 previously done in threads_impl_thread_new.
544 t....the threadobject
546 *******************************************************************************/
548 void threads_impl_thread_reuse(threadobject *t)
550 /* get the pthread id */
552 t->tid = pthread_self();
554 #if defined(ENABLE_DEBUG_FILTER)
555 /* Initialize filter counters */
556 t->filterverbosecallctr[0] = 0;
557 t->filterverbosecallctr[1] = 0;
561 t->tracejavacallindent = 0;
562 t->tracejavacallcount = 0;
569 /* not really needed */
570 t->flc_object = NULL;
572 #if defined(ENABLE_TLH)
573 tlh_destroy(&(t->tlh));
579 /* threads_impl_thread_free ****************************************************
581 Cleanup thread stuff.
584 t....the threadobject
586 *******************************************************************************/
590 void threads_impl_thread_free(threadobject *t)
594 /* Destroy the mutex and the condition. */
596 Mutex_delete(t->flc_lock);
598 result = pthread_cond_destroy(&(t->flc_cond));
601 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
603 Mutex_delete(t->waitmutex);
605 result = pthread_cond_destroy(&(t->waitcond));
608 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
610 Mutex_delete(t->suspendmutex);
612 result = pthread_cond_destroy(&(t->suspendcond));
615 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
620 /* threads_impl_preinit ********************************************************
622 Do some early initialization of stuff required.
624 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
625 is called AFTER this function!
627 *******************************************************************************/
629 void threads_impl_preinit(void)
633 stopworldlock = Mutex_new();
635 /* initialize exit mutex and condition (on exit we join all
638 mutex_join = Mutex_new();
639 cond_join = Condition_new();
641 #if defined(ENABLE_GC_CACAO)
642 /* initialize the GC mutex & suspend semaphore */
644 mutex_gc = Mutex_new();
645 threads_sem_init(&suspend_ack, 0, 0);
648 #if !defined(HAVE___THREAD)
649 result = pthread_key_create(&thread_current_key, NULL);
651 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
656 /* threads_mutex_gc_lock *******************************************************
658 Enter the global GC mutex.
660 *******************************************************************************/
662 #if defined(ENABLE_GC_CACAO)
663 void threads_mutex_gc_lock(void)
665 Mutex_lock(mutex_gc);
670 /* threads_mutex_gc_unlock *****************************************************
672 Leave the global GC mutex.
674 *******************************************************************************/
676 #if defined(ENABLE_GC_CACAO)
677 void threads_mutex_gc_unlock(void)
679 Mutex_unlock(mutex_gc);
683 /* threads_mutex_join_lock *****************************************************
685 Enter the join mutex.
687 *******************************************************************************/
689 void threads_mutex_join_lock(void)
691 Mutex_lock(mutex_join);
695 /* threads_mutex_join_unlock ***************************************************
697 Leave the join mutex.
699 *******************************************************************************/
701 void threads_mutex_join_unlock(void)
703 Mutex_unlock(mutex_join);
707 /* threads_impl_init ***********************************************************
709 Initializes the implementation specific bits.
711 *******************************************************************************/
713 void threads_impl_init(void)
718 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
720 /* Initialize the thread attribute object. */
722 result = pthread_attr_init(&attr);
725 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
727 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
730 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
734 /* threads_startup_thread ******************************************************
736 Thread startup function called by pthread_create.
738 Thread which have a startup.function != NULL are marked as internal
739 threads. All other threads are threated as normal Java threads.
741 NOTE: This function is not called directly by pthread_create. The Boehm GC
742 inserts its own GC_start_routine in between, which then calls
746 arg..........the argument passed to pthread_create, ie. a pointer to
747 a startupinfo struct. CAUTION: When the `psem` semaphore
748 is posted, the startupinfo struct becomes invalid! (It
749 is allocated on the stack of threads_start_thread.)
751 ******************************************************************************/
753 static void *threads_startup_thread(void *arg)
755 startupinfo *startup;
757 java_lang_Thread *object;
758 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
759 java_lang_VMThread *vmt;
765 functionptr function;
767 #if defined(ENABLE_GC_BOEHM)
768 # if !defined(__DARWIN__)
769 struct GC_stack_base sb;
774 #if defined(ENABLE_INTRP)
775 u1 *intrp_thread_stack;
778 #if defined(ENABLE_INTRP)
779 /* create interpreter stack */
782 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
783 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
786 intrp_thread_stack = NULL;
789 /* get passed startupinfo structure and the values in there */
794 function = startup->function;
795 psem = startup->psem;
797 /* Seems like we've encountered a situation where thread->tid was
798 not set by pthread_create. We alleviate this problem by waiting
799 for pthread_create to return. */
801 threads_sem_wait(startup->psem_first);
803 #if defined(__DARWIN__)
804 t->mach_thread = mach_thread_self();
807 /* Now that we are in the new thread, we can store the internal
808 thread data-structure in the TSD. */
810 thread_set_current(t);
812 #if defined(ENABLE_GC_BOEHM)
813 # if defined(__DARWIN__)
814 // This is currently not implemented in Boehm-GC. Just fail silently.
816 /* Register the thread with Boehm-GC. This must happen before the
817 thread allocates any memory from the GC heap.*/
819 result = GC_get_stack_base(&sb);
822 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
824 GC_register_my_thread(&sb);
828 /* get the java.lang.Thread object for this thread */
830 object = (java_lang_Thread *) thread_get_object(t);
832 /* set our priority */
834 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
836 /* Thread is completely initialized. */
838 thread_set_state_runnable(t);
840 /* tell threads_startup_thread that we registered ourselves */
841 /* CAUTION: *startup becomes invalid with this! */
844 threads_sem_post(psem);
846 #if defined(ENABLE_INTRP)
847 /* set interpreter stack */
850 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
853 #if defined(ENABLE_JVMTI)
854 /* fire thread start event */
857 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
860 DEBUGTHREADS("starting", t);
862 /* find and run the Thread.run()V method if no other function was passed */
864 if (function == NULL) {
865 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
866 /* We need to start the run method of
867 java.lang.VMThread. Since this is a final class, we can use
868 the class object directly. */
870 c = class_java_lang_VMThread;
871 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
872 LLNI_class_get(object, c);
874 # error unknown classpath configuration
877 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
880 vm_abort("threads_startup_thread: run() method not found in class");
882 /* set ThreadMXBean variables */
884 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
885 /* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
887 /* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
888 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
889 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
890 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
893 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
894 /* we need to start the run method of java.lang.VMThread */
896 LLNI_field_get_ref(object, vmThread, vmt);
897 o = (java_handle_t *) vmt;
899 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
900 o = (java_handle_t *) object;
902 # error unknown classpath configuration
905 /* Run the thread. */
907 (void) vm_call_method(m, o);
910 /* set ThreadMXBean variables */
912 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
913 /* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
915 /* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
916 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
917 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
918 /* _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--; */
948 /* threads_impl_thread_start ***************************************************
950 Start a thread in the JVM. Both (vm internal and java) thread
954 thread....the thread object
955 f.........function to run in the new thread. NULL means that the
956 "run" method of the object `t` should be called
958 ******************************************************************************/
960 void threads_impl_thread_start(threadobject *thread, functionptr f)
968 /* fill startupinfo structure passed by pthread_create to
969 * threads_startup_thread */
971 startup.thread = thread;
972 startup.function = f; /* maybe we don't call Thread.run()V */
974 startup.psem_first = &sem_first;
976 threads_sem_init(&sem, 0, 0);
977 threads_sem_init(&sem_first, 0, 0);
979 /* Initialize thread attributes. */
981 result = pthread_attr_init(&attr);
984 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
986 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
989 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
991 /* initialize thread stacksize */
993 result = pthread_attr_setstacksize(&attr, opt_stacksize);
996 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
998 /* create the thread */
1000 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1003 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1005 /* destroy the thread attributes */
1007 result = pthread_attr_destroy(&attr);
1010 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1012 /* signal that pthread_create has returned, so thread->tid is valid */
1014 threads_sem_post(&sem_first);
1016 /* wait here until the thread has entered itself into the thread list */
1018 threads_sem_wait(&sem);
1023 sem_destroy(&sem_first);
1027 /* threads_set_thread_priority *************************************************
1029 Set the priority of the given thread.
1032 tid..........thread id
1033 priority.....priority to set
1035 ******************************************************************************/
1037 void threads_set_thread_priority(pthread_t tid, int priority)
1039 struct sched_param schedp;
1042 pthread_getschedparam(tid, &policy, &schedp);
1043 schedp.sched_priority = priority;
1044 pthread_setschedparam(tid, policy, &schedp);
1049 * Detaches the current thread from the VM.
1051 * @return true on success, false otherwise
1053 bool thread_detach_current_thread(void)
1057 java_lang_Thread *object;
1059 #if defined(ENABLE_JAVASE)
1060 java_lang_ThreadGroup *group;
1067 t = thread_get_current();
1073 /* If the given thread has already been detached, this operation
1076 result = thread_is_attached(t);
1078 if (result == false)
1081 DEBUGTHREADS("detaching", t);
1083 object = (java_lang_Thread *) thread_get_object(t);
1085 #if defined(ENABLE_JAVASE)
1086 LLNI_field_get_ref(object, group, group);
1088 /* If there's an uncaught exception, call uncaughtException on the
1089 thread's exception handler, or the thread's group if this is
1092 e = exceptions_get_and_clear_exception();
1095 /* We use the type void* for handler here, as it's not trivial
1096 to build the java_lang_Thread_UncaughtExceptionHandler
1097 header file with cacaoh. */
1099 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1100 LLNI_field_get_ref(object, exceptionHandler, handler);
1101 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1102 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1105 if (handler != NULL) {
1106 LLNI_class_get(handler, c);
1107 o = (java_handle_t *) handler;
1110 LLNI_class_get(group, c);
1111 o = (java_handle_t *) group;
1114 m = class_resolveclassmethod(c,
1115 utf_uncaughtException,
1116 utf_java_lang_Thread_java_lang_Throwable__V,
1123 (void) vm_call_method(m, o, object, e);
1125 if (exceptions_get_exception())
1129 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1131 /* Remove thread from the thread group. */
1133 if (group != NULL) {
1134 LLNI_class_get(group, c);
1136 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1137 m = class_resolveclassmethod(c,
1139 utf_java_lang_Thread__V,
1140 class_java_lang_ThreadGroup,
1142 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1143 m = class_resolveclassmethod(c,
1145 utf_java_lang_Thread__V,
1146 class_java_lang_ThreadGroup,
1149 # error unknown classpath configuration
1155 o = (java_handle_t *) group;
1157 (void) vm_call_method(m, o, object);
1159 if (exceptions_get_exception())
1162 /* Reset the threadgroup in the Java thread object (Mauve
1163 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1165 LLNI_field_set_ref(object, group, NULL);
1169 /* Thread has terminated. */
1171 thread_set_state_terminated(t);
1173 /* Notify all threads waiting on this thread. These are joining
1176 o = (java_handle_t *) object;
1178 /* XXX Care about exceptions? */
1179 (void) lock_monitor_enter(o);
1181 lock_notify_all_object(o);
1183 /* XXX Care about exceptions? */
1184 (void) lock_monitor_exit(o);
1186 /* Enter the join-mutex before calling thread_free, so
1187 threads_join_all_threads gets the correct number of non-daemon
1190 threads_mutex_join_lock();
1192 /* Free the internal thread data-structure. */
1196 /* Signal that this thread has finished and leave the mutex. */
1198 Condition_signal(cond_join);
1199 threads_mutex_join_unlock();
1205 /* threads_suspend_thread ******************************************************
1207 Suspend the passed thread. Execution stops until the thread
1208 is explicitly resumend again.
1211 reason.....Reason for suspending this thread.
1213 *******************************************************************************/
1215 bool threads_suspend_thread(threadobject *thread, s4 reason)
1217 /* acquire the suspendmutex */
1218 Mutex_lock(thread->suspendmutex);
1220 if (thread->suspended) {
1221 Mutex_unlock(thread->suspendmutex);
1225 /* set the reason for the suspension */
1226 thread->suspend_reason = reason;
1228 /* send the suspend signal to the thread */
1229 assert(thread != THREADOBJECT);
1230 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1231 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1234 /* REMEMBER: do not release the suspendmutex, this is done
1235 by the thread itself in threads_suspend_ack(). */
1241 /* threads_suspend_ack *********************************************************
1243 Acknowledges the suspension of the current thread.
1246 pc.....The PC where the thread suspended its execution.
1247 sp.....The SP before the thread suspended its execution.
1249 *******************************************************************************/
1251 #if defined(ENABLE_GC_CACAO)
1252 void threads_suspend_ack(u1* pc, u1* sp)
1254 threadobject *thread;
1256 thread = THREADOBJECT;
1258 assert(thread->suspend_reason != 0);
1260 /* TODO: remember dump memory size */
1262 /* inform the GC about the suspension */
1263 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1265 /* check if the GC wants to leave the thread running */
1266 if (!gc_suspend(thread, pc, sp)) {
1268 /* REMEMBER: we do not unlock the suspendmutex because the thread
1269 will suspend itself again at a later time */
1275 /* mark this thread as suspended and remember the PC */
1277 thread->suspended = true;
1279 /* if we are stopping the world, we should send a global ack */
1280 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1281 threads_sem_post(&suspend_ack);
1284 DEBUGTHREADS("suspending", thread);
1286 /* release the suspension mutex and wait till we are resumed */
1287 Condition_wait(thread->suspendcond, thread->suspendmutex);
1289 DEBUGTHREADS("resuming", thread);
1291 /* if we are stopping the world, we should send a global ack */
1292 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1293 threads_sem_post(&suspend_ack);
1296 /* TODO: free dump memory */
1298 /* release the suspendmutex */
1299 Mutex_unlock(thread->suspendmutex);
1304 /* threads_resume_thread *******************************************************
1306 Resumes the execution of the passed thread.
1308 *******************************************************************************/
1310 #if defined(ENABLE_GC_CACAO)
1311 bool threads_resume_thread(threadobject *thread)
1313 /* acquire the suspendmutex */
1314 Mutex_lock(thread->suspendmutex);
1316 if (!thread->suspended) {
1317 Mutex_unlock(thread->suspendmutex);
1321 thread->suspended = false;
1323 /* tell everyone that the thread should resume */
1324 assert(thread != THREADOBJECT);
1325 Condition_broadcast(thread->suspendcond);
1327 /* release the suspendmutex */
1328 Mutex_unlock(thread->suspendmutex);
1335 /* threads_join_all_threads ****************************************************
1337 Join all non-daemon threads.
1339 *******************************************************************************/
1341 void threads_join_all_threads(void)
1345 /* get current thread */
1349 /* This thread is waiting for all non-daemon threads to exit. */
1351 thread_set_state_waiting(t);
1353 /* enter join mutex */
1355 threads_mutex_join_lock();
1357 /* Wait for condition as long as we have non-daemon threads. We
1358 compare against 1 because the current (main thread) is also a
1359 non-daemon thread. */
1361 while (threadlist_get_non_daemons() > 1)
1362 Condition_wait(cond_join, mutex_join);
1364 /* leave join mutex */
1366 threads_mutex_join_unlock();
1370 /* threads_timespec_earlier ****************************************************
1372 Return true if timespec tv1 is earlier than timespec tv2.
1375 tv1..........first timespec
1376 tv2..........second timespec
1379 true, if the first timespec is earlier
1381 *******************************************************************************/
1383 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1384 const struct timespec *tv2)
1386 return (tv1->tv_sec < tv2->tv_sec)
1388 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1392 /* threads_current_time_is_earlier_than ****************************************
1394 Check if the current time is earlier than the given timespec.
1397 tv...........the timespec to compare against
1400 true, if the current time is earlier
1402 *******************************************************************************/
1404 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1406 struct timeval tvnow;
1407 struct timespec tsnow;
1409 /* get current time */
1411 if (gettimeofday(&tvnow, NULL) != 0)
1412 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1414 /* convert it to a timespec */
1416 tsnow.tv_sec = tvnow.tv_sec;
1417 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1419 /* compare current time with the given timespec */
1421 return threads_timespec_earlier(&tsnow, tv);
1425 /* threads_wait_with_timeout ***************************************************
1427 Wait until the given point in time on a monitor until either
1428 we are notified, we are interrupted, or the time is up.
1431 t............the current thread
1432 wakeupTime...absolute (latest) wakeup time
1433 If both tv_sec and tv_nsec are zero, this function
1434 waits for an unlimited amount of time.
1436 *******************************************************************************/
1438 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1440 /* acquire the waitmutex */
1442 Mutex_lock(t->waitmutex);
1444 /* wait on waitcond */
1446 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1448 while (!t->interrupted && !t->signaled
1449 && threads_current_time_is_earlier_than(wakeupTime))
1451 thread_set_state_timed_waiting(t);
1453 Condition_timedwait(t->waitcond, t->waitmutex, wakeupTime);
1455 thread_set_state_runnable(t);
1460 while (!t->interrupted && !t->signaled) {
1461 thread_set_state_waiting(t);
1463 Condition_wait(t->waitcond, t->waitmutex);
1465 thread_set_state_runnable(t);
1469 /* release the waitmutex */
1471 Mutex_unlock(t->waitmutex);
1475 /* threads_wait_with_timeout_relative ******************************************
1477 Wait for the given maximum amount of time on a monitor until either
1478 we are notified, we are interrupted, or the time is up.
1481 t............the current thread
1482 millis.......milliseconds to wait
1483 nanos........nanoseconds to wait
1485 *******************************************************************************/
1487 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1490 struct timespec wakeupTime;
1492 /* calculate the the (latest) wakeup time */
1494 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1498 threads_wait_with_timeout(thread, &wakeupTime);
1502 /* threads_calc_absolute_time **************************************************
1504 Calculate the absolute point in time a given number of ms and ns from now.
1507 millis............milliseconds from now
1508 nanos.............nanoseconds from now
1511 *tm...............receives the timespec of the absolute point in time
1513 *******************************************************************************/
1515 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1517 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1520 gettimeofday(&tv, NULL);
1521 tv.tv_sec += millis / 1000;
1523 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1524 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1525 tm->tv_nsec = nsec % 1000000000;
1534 /* threads_thread_interrupt ****************************************************
1536 Interrupt the given thread.
1538 The thread gets the "waitcond" signal and
1539 its interrupted flag is set to true.
1542 thread............the thread to interrupt
1544 *******************************************************************************/
1546 void threads_thread_interrupt(threadobject *thread)
1548 #if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1549 /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
1550 int sig = (__SIGRTMAX - 2);
1554 /* Signal the thread a "waitcond" and tell it that it has been
1557 Mutex_lock(thread->waitmutex);
1559 DEBUGTHREADS("interrupted", thread);
1561 /* Interrupt blocking system call using a signal. */
1563 pthread_kill(thread->tid, sig);
1565 Condition_signal(thread->waitcond);
1567 thread->interrupted = true;
1569 Mutex_unlock(thread->waitmutex);
1573 /* threads_sleep ***************************************************************
1575 Sleep the current thread for the specified amount of time.
1577 *******************************************************************************/
1579 void threads_sleep(int64_t millis, int32_t nanos)
1582 struct timespec wakeupTime;
1586 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1587 exceptions_throw_illegalargumentexception();
1591 t = thread_get_current();
1593 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1594 /* Clear interrupted flag (Mauve test:
1595 gnu/testlet/java/lang/Thread/interrupt). */
1597 thread_set_interrupted(t, false);
1599 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1600 exceptions_throw_interruptedexception();
1604 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1606 threads_wait_with_timeout(t, &wakeupTime);
1608 interrupted = thread_is_interrupted(t);
1611 thread_set_interrupted(t, false);
1613 /* An other exception could have been thrown
1614 (e.g. ThreadDeathException). */
1616 if (!exceptions_get_exception())
1617 exceptions_throw_interruptedexception();
1622 /* threads_yield ***************************************************************
1624 Yield to the scheduler.
1626 *******************************************************************************/
1628 void threads_yield(void)
1633 #if defined(ENABLE_TLH)
1635 void threads_tlh_add_frame() {
1636 tlh_add_frame(&(THREADOBJECT->tlh));
1639 void threads_tlh_remove_frame() {
1640 tlh_remove_frame(&(THREADOBJECT->tlh));
1646 * These are local overrides for various environment variables in Emacs.
1647 * Please do not remove this and leave it at the end of the file, where
1648 * Emacs will automagically detect them.
1649 * ---------------------------------------------------------------------
1652 * indent-tabs-mode: t
1656 * vim:noexpandtab:sw=4:ts=4: