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 #include "mm/gc-common.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/options.h"
88 #if defined(ENABLE_STATISTICS)
89 # include "vmcore/statistics.h"
92 #if !defined(__DARWIN__)
93 # include <semaphore.h>
96 #if defined(__LINUX__)
97 # define GC_LINUX_THREADS
98 #elif defined(__IRIX__)
99 # define GC_IRIX_THREADS
100 #elif defined(__DARWIN__)
101 # define GC_DARWIN_THREADS
104 #if defined(ENABLE_GC_BOEHM)
105 /* We need to include Boehm's gc.h here because it overrides
106 pthread_create and friends. */
107 # include "mm/boehm-gc/include/gc.h"
110 #if defined(ENABLE_JVMTI)
111 #include "native/jvmti/cacaodbg.h"
114 #if defined(__DARWIN__)
115 /* Darwin has no working semaphore implementation. This one is taken
119 This is a very simple semaphore implementation for darwin. It
120 is implemented in terms of pthreads calls so it isn't async signal
121 safe. This isn't a problem because signals aren't used to
122 suspend threads on darwin.
125 static int sem_init(sem_t *sem, int pshared, int value)
132 sem->mutex = Mutex_new();
134 if (pthread_cond_init(&sem->cond, NULL) < 0)
140 static int sem_post(sem_t *sem)
142 Mutex_lock(sem->mutex);
146 if (pthread_cond_signal(&sem->cond) < 0) {
147 Mutex_unlock(sem->mutex);
151 Mutex_unlock(sem->mutex);
156 static int sem_wait(sem_t *sem)
158 Mutex_lock(sem->mutex);
160 while (sem->value == 0) {
161 #error We cannot call pthread_cond_wait on a Mutex-class pointer.
162 pthread_cond_wait(&sem->cond, &sem->mutex);
167 Mutex_unlock(sem->mutex);
172 static int sem_destroy(sem_t *sem)
174 if (pthread_cond_destroy(&sem->cond) < 0)
177 Mutex_destroy(sem->mutex);
181 #endif /* defined(__DARWIN__) */
184 /* startupinfo *****************************************************************
186 Struct used to pass info from threads_start_thread to
187 threads_startup_thread.
189 ******************************************************************************/
192 threadobject *thread; /* threadobject for this thread */
193 functionptr function; /* function to run in the new thread */
194 sem_t *psem; /* signals when thread has been entered */
195 /* in the thread list */
196 sem_t *psem_first; /* signals when pthread_create has returned */
200 /* prototypes *****************************************************************/
202 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
205 /******************************************************************************/
206 /* GLOBAL VARIABLES */
207 /******************************************************************************/
209 /* the thread object of the current thread */
210 /* This is either a thread-local variable defined with __thread, or */
211 /* a thread-specific value stored with key threads_current_threadobject_key. */
212 #if defined(HAVE___THREAD)
213 __thread threadobject *thread_current;
215 pthread_key_t thread_current_key;
218 /* global mutex for stop-the-world */
219 static Mutex* stopworldlock;
221 #if defined(ENABLE_GC_CACAO)
222 /* global mutex for the GC */
223 static Mutex* mutex_gc;
226 /* global mutex and condition for joining threads on exit */
227 static Mutex* mutex_join;
228 static Condition* cond_join;
230 #if defined(ENABLE_GC_CACAO)
231 /* semaphore used for acknowleding thread suspension */
232 static sem_t suspend_ack;
236 /* threads_sem_init ************************************************************
238 Initialize a semaphore. Checks against errors and interruptions.
241 sem..............the semaphore to initialize
242 shared...........true if this semaphore will be shared between processes
243 value............the initial value for the semaphore
245 *******************************************************************************/
247 void threads_sem_init(sem_t *sem, bool shared, int value)
254 r = sem_init(sem, shared, value);
257 } while (errno == EINTR);
259 vm_abort("sem_init failed: %s", strerror(errno));
263 /* threads_sem_wait ************************************************************
265 Wait for a semaphore, non-interruptible.
267 IMPORTANT: Always use this function instead of `sem_wait` directly, as
268 `sem_wait` may be interrupted by signals!
271 sem..............the semaphore to wait on
273 *******************************************************************************/
275 void threads_sem_wait(sem_t *sem)
285 } while (errno == EINTR);
287 vm_abort("sem_wait failed: %s", strerror(errno));
291 /* threads_sem_post ************************************************************
293 Increase the count of a semaphore. Checks for errors.
296 sem..............the semaphore to increase the count of
298 *******************************************************************************/
300 void threads_sem_post(sem_t *sem)
306 /* unlike sem_wait, sem_post is not interruptible */
312 vm_abort("sem_post failed: %s", strerror(errno));
316 /* threads_stopworld ***********************************************************
318 Stops the world from turning. All threads except the calling one
319 are suspended. The function returns as soon as all threads have
320 acknowledged their suspension.
322 *******************************************************************************/
324 #if defined(ENABLE_GC_CACAO)
325 void threads_stopworld(void)
327 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
334 Mutex_lock(stopworldlock);
336 /* lock the threads lists */
340 #if defined(__DARWIN__)
341 /*threads_cast_darwinstop();*/
343 #elif defined(__CYGWIN__)
349 DEBUGTHREADS("stops World", self);
353 /* suspend all running threads */
354 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
355 /* don't send the signal to ourself */
360 /* don't send the signal to NEW threads (because they are not
361 completely initialized) */
363 if (t->state == THREAD_STATE_NEW)
366 /* send the signal */
368 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
371 /* increase threads count */
376 /* wait for all threads signaled to suspend */
377 for (i = 0; i < count; i++)
378 threads_sem_wait(&suspend_ack);
381 /* ATTENTION: Don't unlock the threads-lists here so that
382 non-signaled NEW threads can't change their state and execute
388 /* threads_startworld **********************************************************
390 Starts the world again after it has previously been stopped.
392 *******************************************************************************/
394 #if defined(ENABLE_GC_CACAO)
395 void threads_startworld(void)
397 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
404 #if defined(__DARWIN__)
405 /*threads_cast_darwinresume();*/
407 #elif defined(__IRIX__)
408 threads_cast_irixresume();
409 #elif defined(__CYGWIN__)
415 DEBUGTHREADS("starts World", self);
419 /* resume all thread we haltet */
420 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
421 /* don't send the signal to ourself */
426 /* don't send the signal to NEW threads (because they are not
427 completely initialized) */
429 if (t->state == THREAD_STATE_NEW)
432 /* send the signal */
434 result = threads_resume_thread(t);
437 /* increase threads count */
442 /* wait for all threads signaled to suspend */
443 for (i = 0; i < count; i++)
444 threads_sem_wait(&suspend_ack);
448 /* unlock the threads lists */
452 Mutex_unlock(stopworldlock);
457 /* threads_impl_thread_init ****************************************************
459 Initialize OS-level locking constructs in threadobject.
462 t....the threadobject
464 *******************************************************************************/
466 void threads_impl_thread_init(threadobject *t)
468 /* initialize the mutex and the condition */
470 t->flc_lock = Mutex_new();
471 t->flc_cond = Condition_new();
473 t->waitmutex = Mutex_new();
474 t->waitcond = Condition_new();
476 t->suspendmutex = Mutex_new();
477 t->suspendcond = Condition_new();
479 #if defined(ENABLE_TLH)
484 /* threads_impl_thread_clear ***************************************************
486 Clears all fields in threadobject the way an MZERO would have
487 done. MZERO cannot be used anymore because it would mess up the
491 t....the threadobject
493 *******************************************************************************/
495 void threads_impl_thread_clear(threadobject *t)
507 #if defined(__DARWIN__)
511 t->interrupted = false;
514 t->suspended = false;
515 t->suspend_reason = 0;
519 t->_exceptionptr = NULL;
520 t->_stackframeinfo = NULL;
521 t->_localref_table = NULL;
523 #if defined(ENABLE_INTRP)
524 t->_global_sp = NULL;
527 #if defined(ENABLE_GC_CACAO)
528 t->gc_critical = false;
534 MZERO(&t->dumpinfo, dumpinfo_t, 1);
537 /* threads_impl_thread_reuse ***************************************************
539 Resets some implementation fields in threadobject. This was
540 previously done in threads_impl_thread_new.
543 t....the threadobject
545 *******************************************************************************/
547 void threads_impl_thread_reuse(threadobject *t)
549 /* get the pthread id */
551 t->tid = pthread_self();
553 #if defined(ENABLE_DEBUG_FILTER)
554 /* Initialize filter counters */
555 t->filterverbosecallctr[0] = 0;
556 t->filterverbosecallctr[1] = 0;
560 t->tracejavacallindent = 0;
561 t->tracejavacallcount = 0;
568 /* not really needed */
569 t->flc_object = NULL;
571 #if defined(ENABLE_TLH)
572 tlh_destroy(&(t->tlh));
578 /* threads_impl_thread_free ****************************************************
580 Cleanup thread stuff.
583 t....the threadobject
585 *******************************************************************************/
589 void threads_impl_thread_free(threadobject *t)
593 /* Destroy the mutex and the condition. */
595 Mutex_delete(t->flc_lock);
597 result = pthread_cond_destroy(&(t->flc_cond));
600 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
602 Mutex_delete(t->waitmutex);
604 result = pthread_cond_destroy(&(t->waitcond));
607 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
609 Mutex_delete(t->suspendmutex);
611 result = pthread_cond_destroy(&(t->suspendcond));
614 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
619 /* threads_impl_preinit ********************************************************
621 Do some early initialization of stuff required.
623 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
624 is called AFTER this function!
626 *******************************************************************************/
628 void threads_impl_preinit(void)
632 stopworldlock = Mutex_new();
634 /* initialize exit mutex and condition (on exit we join all
637 mutex_join = Mutex_new();
638 cond_join = Condition_new();
640 #if defined(ENABLE_GC_CACAO)
641 /* initialize the GC mutex & suspend semaphore */
643 mutex_gc = Mutex_new();
644 threads_sem_init(&suspend_ack, 0, 0);
647 #if !defined(HAVE___THREAD)
648 result = pthread_key_create(&thread_current_key, NULL);
650 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
655 /* threads_mutex_gc_lock *******************************************************
657 Enter the global GC mutex.
659 *******************************************************************************/
661 #if defined(ENABLE_GC_CACAO)
662 void threads_mutex_gc_lock(void)
664 Mutex_lock(mutex_gc);
669 /* threads_mutex_gc_unlock *****************************************************
671 Leave the global GC mutex.
673 *******************************************************************************/
675 #if defined(ENABLE_GC_CACAO)
676 void threads_mutex_gc_unlock(void)
678 Mutex_unlock(mutex_gc);
682 /* threads_mutex_join_lock *****************************************************
684 Enter the join mutex.
686 *******************************************************************************/
688 void threads_mutex_join_lock(void)
690 Mutex_lock(mutex_join);
694 /* threads_mutex_join_unlock ***************************************************
696 Leave the join mutex.
698 *******************************************************************************/
700 void threads_mutex_join_unlock(void)
702 Mutex_unlock(mutex_join);
706 /* threads_impl_init ***********************************************************
708 Initializes the implementation specific bits.
710 *******************************************************************************/
712 void threads_impl_init(void)
717 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
719 /* Initialize the thread attribute object. */
721 result = pthread_attr_init(&attr);
724 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
726 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
729 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
733 /* threads_startup_thread ******************************************************
735 Thread startup function called by pthread_create.
737 Thread which have a startup.function != NULL are marked as internal
738 threads. All other threads are threated as normal Java threads.
740 NOTE: This function is not called directly by pthread_create. The Boehm GC
741 inserts its own GC_start_routine in between, which then calls
745 arg..........the argument passed to pthread_create, ie. a pointer to
746 a startupinfo struct. CAUTION: When the `psem` semaphore
747 is posted, the startupinfo struct becomes invalid! (It
748 is allocated on the stack of threads_start_thread.)
750 ******************************************************************************/
752 static void *threads_startup_thread(void *arg)
754 startupinfo *startup;
756 java_lang_Thread *object;
757 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
758 java_lang_VMThread *vmt;
764 functionptr function;
766 #if defined(ENABLE_GC_BOEHM)
767 # if !defined(__DARWIN__)
768 struct GC_stack_base sb;
773 #if defined(ENABLE_INTRP)
774 u1 *intrp_thread_stack;
777 #if defined(ENABLE_INTRP)
778 /* create interpreter stack */
781 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
782 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
785 intrp_thread_stack = NULL;
788 /* get passed startupinfo structure and the values in there */
793 function = startup->function;
794 psem = startup->psem;
796 /* Seems like we've encountered a situation where thread->tid was
797 not set by pthread_create. We alleviate this problem by waiting
798 for pthread_create to return. */
800 threads_sem_wait(startup->psem_first);
802 #if defined(__DARWIN__)
803 t->mach_thread = mach_thread_self();
806 /* Now that we are in the new thread, we can store the internal
807 thread data-structure in the TSD. */
809 thread_set_current(t);
811 #if defined(ENABLE_GC_BOEHM)
812 # if defined(__DARWIN__)
813 // This is currently not implemented in Boehm-GC. Just fail silently.
815 /* Register the thread with Boehm-GC. This must happen before the
816 thread allocates any memory from the GC heap.*/
818 result = GC_get_stack_base(&sb);
821 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
823 GC_register_my_thread(&sb);
827 /* get the java.lang.Thread object for this thread */
829 object = (java_lang_Thread *) thread_get_object(t);
831 /* set our priority */
833 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
835 /* Thread is completely initialized. */
837 thread_set_state_runnable(t);
839 /* tell threads_startup_thread that we registered ourselves */
840 /* CAUTION: *startup becomes invalid with this! */
843 threads_sem_post(psem);
845 #if defined(ENABLE_INTRP)
846 /* set interpreter stack */
849 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
852 #if defined(ENABLE_JVMTI)
853 /* fire thread start event */
856 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
859 DEBUGTHREADS("starting", t);
861 /* find and run the Thread.run()V method if no other function was passed */
863 if (function == NULL) {
864 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
865 /* We need to start the run method of
866 java.lang.VMThread. Since this is a final class, we can use
867 the class object directly. */
869 c = class_java_lang_VMThread;
870 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
871 LLNI_class_get(object, c);
873 # error unknown classpath configuration
876 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
879 vm_abort("threads_startup_thread: run() method not found in class");
881 /* set ThreadMXBean variables */
883 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
884 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
886 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
887 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
888 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
889 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
891 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
892 /* we need to start the run method of java.lang.VMThread */
894 LLNI_field_get_ref(object, vmThread, vmt);
895 o = (java_handle_t *) vmt;
897 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
898 o = (java_handle_t *) object;
900 # error unknown classpath configuration
903 /* Run the thread. */
905 (void) vm_call_method(m, o);
908 /* set ThreadMXBean variables */
910 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
911 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
913 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
914 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
915 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
916 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
918 /* call passed function, e.g. finalizer_thread */
923 DEBUGTHREADS("stopping", t);
925 #if defined(ENABLE_JVMTI)
926 /* fire thread end event */
929 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
932 /* We ignore the return value. */
934 (void) thread_detach_current_thread();
936 /* set ThreadMXBean variables */
938 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
944 /* threads_impl_thread_start ***************************************************
946 Start a thread in the JVM. Both (vm internal and java) thread
950 thread....the thread object
951 f.........function to run in the new thread. NULL means that the
952 "run" method of the object `t` should be called
954 ******************************************************************************/
956 void threads_impl_thread_start(threadobject *thread, functionptr f)
964 /* fill startupinfo structure passed by pthread_create to
965 * threads_startup_thread */
967 startup.thread = thread;
968 startup.function = f; /* maybe we don't call Thread.run()V */
970 startup.psem_first = &sem_first;
972 threads_sem_init(&sem, 0, 0);
973 threads_sem_init(&sem_first, 0, 0);
975 /* Initialize thread attributes. */
977 result = pthread_attr_init(&attr);
980 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
982 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
985 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
987 /* initialize thread stacksize */
989 result = pthread_attr_setstacksize(&attr, opt_stacksize);
992 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
994 /* create the thread */
996 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
999 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1001 /* destroy the thread attributes */
1003 result = pthread_attr_destroy(&attr);
1006 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1008 /* signal that pthread_create has returned, so thread->tid is valid */
1010 threads_sem_post(&sem_first);
1012 /* wait here until the thread has entered itself into the thread list */
1014 threads_sem_wait(&sem);
1019 sem_destroy(&sem_first);
1023 /* threads_set_thread_priority *************************************************
1025 Set the priority of the given thread.
1028 tid..........thread id
1029 priority.....priority to set
1031 ******************************************************************************/
1033 void threads_set_thread_priority(pthread_t tid, int priority)
1035 struct sched_param schedp;
1038 pthread_getschedparam(tid, &policy, &schedp);
1039 schedp.sched_priority = priority;
1040 pthread_setschedparam(tid, policy, &schedp);
1045 * Detaches the current thread from the VM.
1047 * @return true on success, false otherwise
1049 bool thread_detach_current_thread(void)
1053 java_lang_Thread *object;
1055 #if defined(ENABLE_JAVASE)
1056 java_lang_ThreadGroup *group;
1063 t = thread_get_current();
1069 /* If the given thread has already been detached, this operation
1072 result = thread_is_attached(t);
1074 if (result == false)
1077 DEBUGTHREADS("detaching", t);
1079 object = (java_lang_Thread *) thread_get_object(t);
1081 #if defined(ENABLE_JAVASE)
1082 LLNI_field_get_ref(object, group, group);
1084 /* If there's an uncaught exception, call uncaughtException on the
1085 thread's exception handler, or the thread's group if this is
1088 e = exceptions_get_and_clear_exception();
1091 /* We use the type void* for handler here, as it's not trivial
1092 to build the java_lang_Thread_UncaughtExceptionHandler
1093 header file with cacaoh. */
1095 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1096 LLNI_field_get_ref(object, exceptionHandler, handler);
1097 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1098 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1101 if (handler != NULL) {
1102 LLNI_class_get(handler, c);
1103 o = (java_handle_t *) handler;
1106 LLNI_class_get(group, c);
1107 o = (java_handle_t *) group;
1110 m = class_resolveclassmethod(c,
1111 utf_uncaughtException,
1112 utf_java_lang_Thread_java_lang_Throwable__V,
1119 (void) vm_call_method(m, o, object, e);
1121 if (exceptions_get_exception())
1125 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1127 /* Remove thread from the thread group. */
1129 if (group != NULL) {
1130 LLNI_class_get(group, c);
1132 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1133 m = class_resolveclassmethod(c,
1135 utf_java_lang_Thread__V,
1136 class_java_lang_ThreadGroup,
1138 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1139 m = class_resolveclassmethod(c,
1141 utf_java_lang_Thread__V,
1142 class_java_lang_ThreadGroup,
1145 # error unknown classpath configuration
1151 o = (java_handle_t *) group;
1153 (void) vm_call_method(m, o, object);
1155 if (exceptions_get_exception())
1158 /* Reset the threadgroup in the Java thread object (Mauve
1159 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1161 LLNI_field_set_ref(object, group, NULL);
1165 /* Thread has terminated. */
1167 thread_set_state_terminated(t);
1169 /* Notify all threads waiting on this thread. These are joining
1172 o = (java_handle_t *) object;
1174 /* XXX Care about exceptions? */
1175 (void) lock_monitor_enter(o);
1177 lock_notify_all_object(o);
1179 /* XXX Care about exceptions? */
1180 (void) lock_monitor_exit(o);
1182 /* Enter the join-mutex before calling thread_free, so
1183 threads_join_all_threads gets the correct number of non-daemon
1186 threads_mutex_join_lock();
1188 /* Free the internal thread data-structure. */
1192 /* Signal that this thread has finished and leave the mutex. */
1194 Condition_signal(cond_join);
1195 threads_mutex_join_unlock();
1201 /* threads_suspend_thread ******************************************************
1203 Suspend the passed thread. Execution stops until the thread
1204 is explicitly resumend again.
1207 reason.....Reason for suspending this thread.
1209 *******************************************************************************/
1211 bool threads_suspend_thread(threadobject *thread, s4 reason)
1213 /* acquire the suspendmutex */
1214 Mutex_lock(thread->suspendmutex);
1216 if (thread->suspended) {
1217 Mutex_unlock(thread->suspendmutex);
1221 /* set the reason for the suspension */
1222 thread->suspend_reason = reason;
1224 /* send the suspend signal to the thread */
1225 assert(thread != THREADOBJECT);
1226 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1227 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1230 /* REMEMBER: do not release the suspendmutex, this is done
1231 by the thread itself in threads_suspend_ack(). */
1237 /* threads_suspend_ack *********************************************************
1239 Acknowledges the suspension of the current thread.
1242 pc.....The PC where the thread suspended its execution.
1243 sp.....The SP before the thread suspended its execution.
1245 *******************************************************************************/
1247 #if defined(ENABLE_GC_CACAO)
1248 void threads_suspend_ack(u1* pc, u1* sp)
1250 threadobject *thread;
1252 thread = THREADOBJECT;
1254 assert(thread->suspend_reason != 0);
1256 /* TODO: remember dump memory size */
1258 /* inform the GC about the suspension */
1259 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1261 /* check if the GC wants to leave the thread running */
1262 if (!gc_suspend(thread, pc, sp)) {
1264 /* REMEMBER: we do not unlock the suspendmutex because the thread
1265 will suspend itself again at a later time */
1271 /* mark this thread as suspended and remember the PC */
1273 thread->suspended = true;
1275 /* if we are stopping the world, we should send a global ack */
1276 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1277 threads_sem_post(&suspend_ack);
1280 DEBUGTHREADS("suspending", thread);
1282 /* release the suspension mutex and wait till we are resumed */
1283 Condition_wait(thread->suspendcond, thread->suspendmutex);
1285 DEBUGTHREADS("resuming", thread);
1287 /* if we are stopping the world, we should send a global ack */
1288 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1289 threads_sem_post(&suspend_ack);
1292 /* TODO: free dump memory */
1294 /* release the suspendmutex */
1295 Mutex_unlock(thread->suspendmutex);
1300 /* threads_resume_thread *******************************************************
1302 Resumes the execution of the passed thread.
1304 *******************************************************************************/
1306 #if defined(ENABLE_GC_CACAO)
1307 bool threads_resume_thread(threadobject *thread)
1309 /* acquire the suspendmutex */
1310 Mutex_lock(thread->suspendmutex);
1312 if (!thread->suspended) {
1313 Mutex_unlock(thread->suspendmutex);
1317 thread->suspended = false;
1319 /* tell everyone that the thread should resume */
1320 assert(thread != THREADOBJECT);
1321 Condition_broadcast(thread->suspendcond);
1323 /* release the suspendmutex */
1324 Mutex_unlock(thread->suspendmutex);
1331 /* threads_join_all_threads ****************************************************
1333 Join all non-daemon threads.
1335 *******************************************************************************/
1337 void threads_join_all_threads(void)
1341 /* get current thread */
1345 /* This thread is waiting for all non-daemon threads to exit. */
1347 thread_set_state_waiting(t);
1349 /* enter join mutex */
1351 threads_mutex_join_lock();
1353 /* Wait for condition as long as we have non-daemon threads. We
1354 compare against 1 because the current (main thread) is also a
1355 non-daemon thread. */
1357 while (threadlist_get_non_daemons() > 1)
1358 Condition_wait(cond_join, mutex_join);
1360 /* leave join mutex */
1362 threads_mutex_join_unlock();
1366 /* threads_timespec_earlier ****************************************************
1368 Return true if timespec tv1 is earlier than timespec tv2.
1371 tv1..........first timespec
1372 tv2..........second timespec
1375 true, if the first timespec is earlier
1377 *******************************************************************************/
1379 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1380 const struct timespec *tv2)
1382 return (tv1->tv_sec < tv2->tv_sec)
1384 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1388 /* threads_current_time_is_earlier_than ****************************************
1390 Check if the current time is earlier than the given timespec.
1393 tv...........the timespec to compare against
1396 true, if the current time is earlier
1398 *******************************************************************************/
1400 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1402 struct timeval tvnow;
1403 struct timespec tsnow;
1405 /* get current time */
1407 if (gettimeofday(&tvnow, NULL) != 0)
1408 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1410 /* convert it to a timespec */
1412 tsnow.tv_sec = tvnow.tv_sec;
1413 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1415 /* compare current time with the given timespec */
1417 return threads_timespec_earlier(&tsnow, tv);
1421 /* threads_wait_with_timeout ***************************************************
1423 Wait until the given point in time on a monitor until either
1424 we are notified, we are interrupted, or the time is up.
1427 t............the current thread
1428 wakeupTime...absolute (latest) wakeup time
1429 If both tv_sec and tv_nsec are zero, this function
1430 waits for an unlimited amount of time.
1432 *******************************************************************************/
1434 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1436 /* acquire the waitmutex */
1438 Mutex_lock(t->waitmutex);
1440 /* wait on waitcond */
1442 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1444 while (!t->interrupted && !t->signaled
1445 && threads_current_time_is_earlier_than(wakeupTime))
1447 thread_set_state_timed_waiting(t);
1449 Condition_timedwait(t->waitcond, t->waitmutex, wakeupTime);
1451 thread_set_state_runnable(t);
1456 while (!t->interrupted && !t->signaled) {
1457 thread_set_state_waiting(t);
1459 Condition_wait(t->waitcond, t->waitmutex);
1461 thread_set_state_runnable(t);
1465 /* release the waitmutex */
1467 Mutex_unlock(t->waitmutex);
1471 /* threads_wait_with_timeout_relative ******************************************
1473 Wait for the given maximum amount of time on a monitor until either
1474 we are notified, we are interrupted, or the time is up.
1477 t............the current thread
1478 millis.......milliseconds to wait
1479 nanos........nanoseconds to wait
1481 *******************************************************************************/
1483 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1486 struct timespec wakeupTime;
1488 /* calculate the the (latest) wakeup time */
1490 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1494 threads_wait_with_timeout(thread, &wakeupTime);
1498 /* threads_calc_absolute_time **************************************************
1500 Calculate the absolute point in time a given number of ms and ns from now.
1503 millis............milliseconds from now
1504 nanos.............nanoseconds from now
1507 *tm...............receives the timespec of the absolute point in time
1509 *******************************************************************************/
1511 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1513 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1516 gettimeofday(&tv, NULL);
1517 tv.tv_sec += millis / 1000;
1519 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1520 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1521 tm->tv_nsec = nsec % 1000000000;
1530 /* threads_thread_interrupt ****************************************************
1532 Interrupt the given thread.
1534 The thread gets the "waitcond" signal and
1535 its interrupted flag is set to true.
1538 thread............the thread to interrupt
1540 *******************************************************************************/
1542 void threads_thread_interrupt(threadobject *thread)
1544 #if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1545 /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
1546 int sig = (__SIGRTMAX - 2);
1550 /* Signal the thread a "waitcond" and tell it that it has been
1553 Mutex_lock(thread->waitmutex);
1555 DEBUGTHREADS("interrupted", thread);
1557 /* Interrupt blocking system call using a signal. */
1559 pthread_kill(thread->tid, sig);
1561 Condition_signal(thread->waitcond);
1563 thread->interrupted = true;
1565 Mutex_unlock(thread->waitmutex);
1569 /* threads_sleep ***************************************************************
1571 Sleep the current thread for the specified amount of time.
1573 *******************************************************************************/
1575 void threads_sleep(int64_t millis, int32_t nanos)
1578 struct timespec wakeupTime;
1582 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1583 exceptions_throw_illegalargumentexception();
1587 t = thread_get_current();
1589 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1590 /* Clear interrupted flag (Mauve test:
1591 gnu/testlet/java/lang/Thread/interrupt). */
1593 thread_set_interrupted(t, false);
1595 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1596 exceptions_throw_interruptedexception();
1600 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1602 threads_wait_with_timeout(t, &wakeupTime);
1604 interrupted = thread_is_interrupted(t);
1607 thread_set_interrupted(t, false);
1609 /* An other exception could have been thrown
1610 (e.g. ThreadDeathException). */
1612 if (!exceptions_get_exception())
1613 exceptions_throw_interruptedexception();
1618 /* threads_yield ***************************************************************
1620 Yield to the scheduler.
1622 *******************************************************************************/
1624 void threads_yield(void)
1629 #if defined(ENABLE_TLH)
1631 void threads_tlh_add_frame() {
1632 tlh_add_frame(&(THREADOBJECT->tlh));
1635 void threads_tlh_remove_frame() {
1636 tlh_remove_frame(&(THREADOBJECT->tlh));
1642 * These are local overrides for various environment variables in Emacs.
1643 * Please do not remove this and leave it at the end of the file, where
1644 * Emacs will automagically detect them.
1645 * ---------------------------------------------------------------------
1648 * indent-tabs-mode: t
1652 * vim:noexpandtab:sw=4:ts=4: