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();
480 /* threads_impl_thread_clear ***************************************************
482 Clears all fields in threadobject the way an MZERO would have
483 done. MZERO cannot be used anymore because it would mess up the
487 t....the threadobject
489 *******************************************************************************/
491 void threads_impl_thread_clear(threadobject *t)
503 #if defined(__DARWIN__)
507 t->interrupted = false;
510 t->suspended = false;
511 t->suspend_reason = 0;
515 t->_exceptionptr = NULL;
516 t->_stackframeinfo = NULL;
517 t->_localref_table = NULL;
519 #if defined(ENABLE_INTRP)
520 t->_global_sp = NULL;
523 #if defined(ENABLE_GC_CACAO)
524 t->gc_critical = false;
530 MZERO(&t->dumpinfo, dumpinfo_t, 1);
533 /* threads_impl_thread_reuse ***************************************************
535 Resets some implementation fields in threadobject. This was
536 previously done in threads_impl_thread_new.
539 t....the threadobject
541 *******************************************************************************/
543 void threads_impl_thread_reuse(threadobject *t)
545 /* get the pthread id */
547 t->tid = pthread_self();
549 #if defined(ENABLE_DEBUG_FILTER)
550 /* Initialize filter counters */
551 t->filterverbosecallctr[0] = 0;
552 t->filterverbosecallctr[1] = 0;
556 t->tracejavacallindent = 0;
557 t->tracejavacallcount = 0;
564 /* not really needed */
565 t->flc_object = NULL;
569 /* threads_impl_thread_free ****************************************************
571 Cleanup thread stuff.
574 t....the threadobject
576 *******************************************************************************/
580 void threads_impl_thread_free(threadobject *t)
584 /* Destroy the mutex and the condition. */
586 Mutex_delete(t->flc_lock);
588 result = pthread_cond_destroy(&(t->flc_cond));
591 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
593 Mutex_delete(t->waitmutex);
595 result = pthread_cond_destroy(&(t->waitcond));
598 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
600 Mutex_delete(t->suspendmutex);
602 result = pthread_cond_destroy(&(t->suspendcond));
605 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
610 /* threads_impl_preinit ********************************************************
612 Do some early initialization of stuff required.
614 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
615 is called AFTER this function!
617 *******************************************************************************/
619 void threads_impl_preinit(void)
623 stopworldlock = Mutex_new();
625 /* initialize exit mutex and condition (on exit we join all
628 mutex_join = Mutex_new();
629 cond_join = Condition_new();
631 #if defined(ENABLE_GC_CACAO)
632 /* initialize the GC mutex & suspend semaphore */
634 mutex_gc = Mutex_new();
635 threads_sem_init(&suspend_ack, 0, 0);
638 #if !defined(HAVE___THREAD)
639 result = pthread_key_create(&thread_current_key, NULL);
641 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
646 /* threads_mutex_gc_lock *******************************************************
648 Enter the global GC mutex.
650 *******************************************************************************/
652 #if defined(ENABLE_GC_CACAO)
653 void threads_mutex_gc_lock(void)
655 Mutex_lock(mutex_gc);
660 /* threads_mutex_gc_unlock *****************************************************
662 Leave the global GC mutex.
664 *******************************************************************************/
666 #if defined(ENABLE_GC_CACAO)
667 void threads_mutex_gc_unlock(void)
669 Mutex_unlock(mutex_gc);
673 /* threads_mutex_join_lock *****************************************************
675 Enter the join mutex.
677 *******************************************************************************/
679 void threads_mutex_join_lock(void)
681 Mutex_lock(mutex_join);
685 /* threads_mutex_join_unlock ***************************************************
687 Leave the join mutex.
689 *******************************************************************************/
691 void threads_mutex_join_unlock(void)
693 Mutex_unlock(mutex_join);
697 /* threads_impl_init ***********************************************************
699 Initializes the implementation specific bits.
701 *******************************************************************************/
703 void threads_impl_init(void)
708 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
710 /* Initialize the thread attribute object. */
712 result = pthread_attr_init(&attr);
715 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
717 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
720 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
724 /* threads_startup_thread ******************************************************
726 Thread startup function called by pthread_create.
728 Thread which have a startup.function != NULL are marked as internal
729 threads. All other threads are threated as normal Java threads.
731 NOTE: This function is not called directly by pthread_create. The Boehm GC
732 inserts its own GC_start_routine in between, which then calls
736 arg..........the argument passed to pthread_create, ie. a pointer to
737 a startupinfo struct. CAUTION: When the `psem` semaphore
738 is posted, the startupinfo struct becomes invalid! (It
739 is allocated on the stack of threads_start_thread.)
741 ******************************************************************************/
743 static void *threads_startup_thread(void *arg)
745 startupinfo *startup;
747 java_lang_Thread *object;
748 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
749 java_lang_VMThread *vmt;
755 functionptr function;
757 #if defined(ENABLE_GC_BOEHM)
758 # if !defined(__DARWIN__)
759 struct GC_stack_base sb;
764 #if defined(ENABLE_INTRP)
765 u1 *intrp_thread_stack;
768 #if defined(ENABLE_INTRP)
769 /* create interpreter stack */
772 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
773 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
776 intrp_thread_stack = NULL;
779 /* get passed startupinfo structure and the values in there */
784 function = startup->function;
785 psem = startup->psem;
787 /* Seems like we've encountered a situation where thread->tid was
788 not set by pthread_create. We alleviate this problem by waiting
789 for pthread_create to return. */
791 threads_sem_wait(startup->psem_first);
793 #if defined(__DARWIN__)
794 t->mach_thread = mach_thread_self();
797 /* Now that we are in the new thread, we can store the internal
798 thread data-structure in the TSD. */
800 thread_set_current(t);
802 #if defined(ENABLE_GC_BOEHM)
803 # if defined(__DARWIN__)
804 // This is currently not implemented in Boehm-GC. Just fail silently.
806 /* Register the thread with Boehm-GC. This must happen before the
807 thread allocates any memory from the GC heap.*/
809 result = GC_get_stack_base(&sb);
812 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
814 GC_register_my_thread(&sb);
818 /* get the java.lang.Thread object for this thread */
820 object = (java_lang_Thread *) thread_get_object(t);
822 /* set our priority */
824 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
826 /* Thread is completely initialized. */
828 thread_set_state_runnable(t);
830 /* tell threads_startup_thread that we registered ourselves */
831 /* CAUTION: *startup becomes invalid with this! */
834 threads_sem_post(psem);
836 #if defined(ENABLE_INTRP)
837 /* set interpreter stack */
840 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
843 #if defined(ENABLE_JVMTI)
844 /* fire thread start event */
847 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
850 DEBUGTHREADS("starting", t);
852 /* find and run the Thread.run()V method if no other function was passed */
854 if (function == NULL) {
855 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
856 /* We need to start the run method of
857 java.lang.VMThread. Since this is a final class, we can use
858 the class object directly. */
860 c = class_java_lang_VMThread;
861 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
862 LLNI_class_get(object, c);
864 # error unknown classpath configuration
867 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
870 vm_abort("threads_startup_thread: run() method not found in class");
872 /* set ThreadMXBean variables */
874 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
875 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
877 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
878 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
879 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
880 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
882 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
883 /* we need to start the run method of java.lang.VMThread */
885 LLNI_field_get_ref(object, vmThread, vmt);
886 o = (java_handle_t *) vmt;
888 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
889 o = (java_handle_t *) object;
891 # error unknown classpath configuration
894 /* Run the thread. */
896 (void) vm_call_method(m, o);
899 /* set ThreadMXBean variables */
901 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
902 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
904 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
905 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
906 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
907 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
909 /* call passed function, e.g. finalizer_thread */
914 DEBUGTHREADS("stopping", t);
916 #if defined(ENABLE_JVMTI)
917 /* fire thread end event */
920 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
923 /* We ignore the return value. */
925 (void) thread_detach_current_thread();
927 /* set ThreadMXBean variables */
929 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
935 /* threads_impl_thread_start ***************************************************
937 Start a thread in the JVM. Both (vm internal and java) thread
941 thread....the thread object
942 f.........function to run in the new thread. NULL means that the
943 "run" method of the object `t` should be called
945 ******************************************************************************/
947 void threads_impl_thread_start(threadobject *thread, functionptr f)
955 /* fill startupinfo structure passed by pthread_create to
956 * threads_startup_thread */
958 startup.thread = thread;
959 startup.function = f; /* maybe we don't call Thread.run()V */
961 startup.psem_first = &sem_first;
963 threads_sem_init(&sem, 0, 0);
964 threads_sem_init(&sem_first, 0, 0);
966 /* Initialize thread attributes. */
968 result = pthread_attr_init(&attr);
971 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
973 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
976 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
978 /* initialize thread stacksize */
980 result = pthread_attr_setstacksize(&attr, opt_stacksize);
983 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
985 /* create the thread */
987 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
990 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
992 /* destroy the thread attributes */
994 result = pthread_attr_destroy(&attr);
997 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
999 /* signal that pthread_create has returned, so thread->tid is valid */
1001 threads_sem_post(&sem_first);
1003 /* wait here until the thread has entered itself into the thread list */
1005 threads_sem_wait(&sem);
1010 sem_destroy(&sem_first);
1014 /* threads_set_thread_priority *************************************************
1016 Set the priority of the given thread.
1019 tid..........thread id
1020 priority.....priority to set
1022 ******************************************************************************/
1024 void threads_set_thread_priority(pthread_t tid, int priority)
1026 struct sched_param schedp;
1029 pthread_getschedparam(tid, &policy, &schedp);
1030 schedp.sched_priority = priority;
1031 pthread_setschedparam(tid, policy, &schedp);
1036 * Detaches the current thread from the VM.
1038 * @return true on success, false otherwise
1040 bool thread_detach_current_thread(void)
1044 java_lang_Thread *object;
1046 #if defined(ENABLE_JAVASE)
1047 java_lang_ThreadGroup *group;
1054 t = thread_get_current();
1060 /* If the given thread has already been detached, this operation
1063 result = thread_is_attached(t);
1065 if (result == false)
1068 DEBUGTHREADS("detaching", t);
1070 object = (java_lang_Thread *) thread_get_object(t);
1072 #if defined(ENABLE_JAVASE)
1073 LLNI_field_get_ref(object, group, group);
1075 /* If there's an uncaught exception, call uncaughtException on the
1076 thread's exception handler, or the thread's group if this is
1079 e = exceptions_get_and_clear_exception();
1082 /* We use the type void* for handler here, as it's not trivial
1083 to build the java_lang_Thread_UncaughtExceptionHandler
1084 header file with cacaoh. */
1086 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1087 LLNI_field_get_ref(object, exceptionHandler, handler);
1088 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1089 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1092 if (handler != NULL) {
1093 LLNI_class_get(handler, c);
1094 o = (java_handle_t *) handler;
1097 LLNI_class_get(group, c);
1098 o = (java_handle_t *) group;
1101 m = class_resolveclassmethod(c,
1102 utf_uncaughtException,
1103 utf_java_lang_Thread_java_lang_Throwable__V,
1110 (void) vm_call_method(m, o, object, e);
1112 if (exceptions_get_exception())
1116 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1118 /* Remove thread from the thread group. */
1120 if (group != NULL) {
1121 LLNI_class_get(group, c);
1123 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1124 m = class_resolveclassmethod(c,
1126 utf_java_lang_Thread__V,
1127 class_java_lang_ThreadGroup,
1129 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1130 m = class_resolveclassmethod(c,
1132 utf_java_lang_Thread__V,
1133 class_java_lang_ThreadGroup,
1136 # error unknown classpath configuration
1142 o = (java_handle_t *) group;
1144 (void) vm_call_method(m, o, object);
1146 if (exceptions_get_exception())
1149 /* Reset the threadgroup in the Java thread object (Mauve
1150 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1152 LLNI_field_set_ref(object, group, NULL);
1156 /* Thread has terminated. */
1158 thread_set_state_terminated(t);
1160 /* Notify all threads waiting on this thread. These are joining
1163 o = (java_handle_t *) object;
1165 /* XXX Care about exceptions? */
1166 (void) lock_monitor_enter(o);
1168 lock_notify_all_object(o);
1170 /* XXX Care about exceptions? */
1171 (void) lock_monitor_exit(o);
1173 /* Enter the join-mutex before calling thread_free, so
1174 threads_join_all_threads gets the correct number of non-daemon
1177 threads_mutex_join_lock();
1179 /* Free the internal thread data-structure. */
1183 /* Signal that this thread has finished and leave the mutex. */
1185 Condition_signal(cond_join);
1186 threads_mutex_join_unlock();
1192 /* threads_suspend_thread ******************************************************
1194 Suspend the passed thread. Execution stops until the thread
1195 is explicitly resumend again.
1198 reason.....Reason for suspending this thread.
1200 *******************************************************************************/
1202 bool threads_suspend_thread(threadobject *thread, s4 reason)
1204 /* acquire the suspendmutex */
1205 Mutex_lock(thread->suspendmutex);
1207 if (thread->suspended) {
1208 Mutex_unlock(thread->suspendmutex);
1212 /* set the reason for the suspension */
1213 thread->suspend_reason = reason;
1215 /* send the suspend signal to the thread */
1216 assert(thread != THREADOBJECT);
1217 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1218 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1221 /* REMEMBER: do not release the suspendmutex, this is done
1222 by the thread itself in threads_suspend_ack(). */
1228 /* threads_suspend_ack *********************************************************
1230 Acknowledges the suspension of the current thread.
1233 pc.....The PC where the thread suspended its execution.
1234 sp.....The SP before the thread suspended its execution.
1236 *******************************************************************************/
1238 #if defined(ENABLE_GC_CACAO)
1239 void threads_suspend_ack(u1* pc, u1* sp)
1241 threadobject *thread;
1243 thread = THREADOBJECT;
1245 assert(thread->suspend_reason != 0);
1247 /* TODO: remember dump memory size */
1249 /* inform the GC about the suspension */
1250 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1252 /* check if the GC wants to leave the thread running */
1253 if (!gc_suspend(thread, pc, sp)) {
1255 /* REMEMBER: we do not unlock the suspendmutex because the thread
1256 will suspend itself again at a later time */
1262 /* mark this thread as suspended and remember the PC */
1264 thread->suspended = true;
1266 /* if we are stopping the world, we should send a global ack */
1267 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1268 threads_sem_post(&suspend_ack);
1271 DEBUGTHREADS("suspending", thread);
1273 /* release the suspension mutex and wait till we are resumed */
1274 Condition_wait(thread->suspendcond, thread->suspendmutex);
1276 DEBUGTHREADS("resuming", thread);
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 /* TODO: free dump memory */
1285 /* release the suspendmutex */
1286 Mutex_unlock(thread->suspendmutex);
1291 /* threads_resume_thread *******************************************************
1293 Resumes the execution of the passed thread.
1295 *******************************************************************************/
1297 #if defined(ENABLE_GC_CACAO)
1298 bool threads_resume_thread(threadobject *thread)
1300 /* acquire the suspendmutex */
1301 Mutex_lock(thread->suspendmutex);
1303 if (!thread->suspended) {
1304 Mutex_unlock(thread->suspendmutex);
1308 thread->suspended = false;
1310 /* tell everyone that the thread should resume */
1311 assert(thread != THREADOBJECT);
1312 Condition_broadcast(thread->suspendcond);
1314 /* release the suspendmutex */
1315 Mutex_unlock(thread->suspendmutex);
1322 /* threads_join_all_threads ****************************************************
1324 Join all non-daemon threads.
1326 *******************************************************************************/
1328 void threads_join_all_threads(void)
1332 /* get current thread */
1336 /* This thread is waiting for all non-daemon threads to exit. */
1338 thread_set_state_waiting(t);
1340 /* enter join mutex */
1342 threads_mutex_join_lock();
1344 /* Wait for condition as long as we have non-daemon threads. We
1345 compare against 1 because the current (main thread) is also a
1346 non-daemon thread. */
1348 while (threadlist_get_non_daemons() > 1)
1349 Condition_wait(cond_join, mutex_join);
1351 /* leave join mutex */
1353 threads_mutex_join_unlock();
1357 /* threads_timespec_earlier ****************************************************
1359 Return true if timespec tv1 is earlier than timespec tv2.
1362 tv1..........first timespec
1363 tv2..........second timespec
1366 true, if the first timespec is earlier
1368 *******************************************************************************/
1370 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1371 const struct timespec *tv2)
1373 return (tv1->tv_sec < tv2->tv_sec)
1375 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1379 /* threads_current_time_is_earlier_than ****************************************
1381 Check if the current time is earlier than the given timespec.
1384 tv...........the timespec to compare against
1387 true, if the current time is earlier
1389 *******************************************************************************/
1391 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1393 struct timeval tvnow;
1394 struct timespec tsnow;
1396 /* get current time */
1398 if (gettimeofday(&tvnow, NULL) != 0)
1399 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1401 /* convert it to a timespec */
1403 tsnow.tv_sec = tvnow.tv_sec;
1404 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1406 /* compare current time with the given timespec */
1408 return threads_timespec_earlier(&tsnow, tv);
1412 /* threads_wait_with_timeout ***************************************************
1414 Wait until the given point in time on a monitor until either
1415 we are notified, we are interrupted, or the time is up.
1418 t............the current thread
1419 wakeupTime...absolute (latest) wakeup time
1420 If both tv_sec and tv_nsec are zero, this function
1421 waits for an unlimited amount of time.
1423 *******************************************************************************/
1425 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1427 /* acquire the waitmutex */
1429 Mutex_lock(t->waitmutex);
1431 /* wait on waitcond */
1433 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1435 while (!t->interrupted && !t->signaled
1436 && threads_current_time_is_earlier_than(wakeupTime))
1438 thread_set_state_timed_waiting(t);
1440 Condition_timedwait(t->waitcond, t->waitmutex, wakeupTime);
1442 thread_set_state_runnable(t);
1447 while (!t->interrupted && !t->signaled) {
1448 thread_set_state_waiting(t);
1450 Condition_wait(t->waitcond, t->waitmutex);
1452 thread_set_state_runnable(t);
1456 /* release the waitmutex */
1458 Mutex_unlock(t->waitmutex);
1462 /* threads_wait_with_timeout_relative ******************************************
1464 Wait for the given maximum amount of time on a monitor until either
1465 we are notified, we are interrupted, or the time is up.
1468 t............the current thread
1469 millis.......milliseconds to wait
1470 nanos........nanoseconds to wait
1472 *******************************************************************************/
1474 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1477 struct timespec wakeupTime;
1479 /* calculate the the (latest) wakeup time */
1481 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1485 threads_wait_with_timeout(thread, &wakeupTime);
1489 /* threads_calc_absolute_time **************************************************
1491 Calculate the absolute point in time a given number of ms and ns from now.
1494 millis............milliseconds from now
1495 nanos.............nanoseconds from now
1498 *tm...............receives the timespec of the absolute point in time
1500 *******************************************************************************/
1502 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1504 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1507 gettimeofday(&tv, NULL);
1508 tv.tv_sec += millis / 1000;
1510 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1511 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1512 tm->tv_nsec = nsec % 1000000000;
1521 /* threads_thread_interrupt ****************************************************
1523 Interrupt the given thread.
1525 The thread gets the "waitcond" signal and
1526 its interrupted flag is set to true.
1529 thread............the thread to interrupt
1531 *******************************************************************************/
1533 void threads_thread_interrupt(threadobject *thread)
1535 #if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1536 /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
1537 int sig = (__SIGRTMAX - 2);
1541 /* Signal the thread a "waitcond" and tell it that it has been
1544 Mutex_lock(thread->waitmutex);
1546 DEBUGTHREADS("interrupted", thread);
1548 /* Interrupt blocking system call using a signal. */
1550 pthread_kill(thread->tid, sig);
1552 Condition_signal(thread->waitcond);
1554 thread->interrupted = true;
1556 Mutex_unlock(thread->waitmutex);
1560 /* threads_sleep ***************************************************************
1562 Sleep the current thread for the specified amount of time.
1564 *******************************************************************************/
1566 void threads_sleep(int64_t millis, int32_t nanos)
1569 struct timespec wakeupTime;
1573 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1574 exceptions_throw_illegalargumentexception();
1578 t = thread_get_current();
1580 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1581 /* Clear interrupted flag (Mauve test:
1582 gnu/testlet/java/lang/Thread/interrupt). */
1584 thread_set_interrupted(t, false);
1586 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1587 exceptions_throw_interruptedexception();
1591 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1593 threads_wait_with_timeout(t, &wakeupTime);
1595 interrupted = thread_is_interrupted(t);
1598 thread_set_interrupted(t, false);
1600 /* An other exception could have been thrown
1601 (e.g. ThreadDeathException). */
1603 if (!exceptions_get_exception())
1604 exceptions_throw_interruptedexception();
1609 /* threads_yield ***************************************************************
1611 Yield to the scheduler.
1613 *******************************************************************************/
1615 void threads_yield(void)
1622 * These are local overrides for various environment variables in Emacs.
1623 * Please do not remove this and leave it at the end of the file, where
1624 * Emacs will automagically detect them.
1625 * ---------------------------------------------------------------------
1628 * indent-tabs-mode: t
1632 * vim:noexpandtab:sw=4:ts=4: