1 /* src/threads/posix/thread-posix.cpp - 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 */
30 #define __STDC_LIMIT_MACROS
35 #include <sys/types.h>
48 #include "mm/memory.hpp"
50 #if defined(ENABLE_GC_CACAO)
51 # include "mm/cacao-gc/gc.h"
54 #include "native/llni.h"
55 #include "native/native.hpp"
57 #include "threads/condition.hpp"
58 #include "threads/lock.hpp"
59 #include "threads/mutex.hpp"
60 #include "threads/threadlist.hpp"
61 #include "threads/thread.hpp"
63 #include "toolbox/logging.hpp"
65 #include "vm/jit/builtin.hpp"
66 #include "vm/exceptions.hpp"
67 #include "vm/global.h"
68 #include "vm/globals.hpp"
69 #include "vm/javaobjects.hpp"
70 #include "vm/options.h"
72 #include "vm/signallocal.hpp"
73 #include "vm/string.hpp"
76 #if defined(ENABLE_STATISTICS)
77 # include "vm/statistics.h"
80 #include "vm/jit/asmpart.h"
82 #if !defined(__DARWIN__)
83 # include <semaphore.h>
86 #if defined(__LINUX__)
87 # define GC_LINUX_THREADS
88 #elif defined(__IRIX__)
89 # define GC_IRIX_THREADS
90 #elif defined(__DARWIN__)
91 # define GC_DARWIN_THREADS
94 #if defined(ENABLE_GC_BOEHM)
95 /* We need to include Boehm's gc.h here because it overrides
96 pthread_create and friends. */
97 # include "mm/boehm-gc/include/gc.h"
100 #if defined(ENABLE_JVMTI)
101 #include "native/jvmti/cacaodbg.h"
105 #if defined(__DARWIN__)
106 /* Darwin has no working semaphore implementation. This one is taken
110 This is a very simple semaphore implementation for Darwin. It
111 is implemented in terms of pthreads calls so it isn't async signal
112 safe. This isn't a problem because signals aren't used to
113 suspend threads on Darwin.
116 static int sem_init(sem_t *sem, int pshared, int value)
121 sem->mutex = new Mutex();
122 sem->cond = new Condition();
128 static int sem_post(sem_t *sem)
133 sem->mutex->unlock();
138 static int sem_wait(sem_t *sem)
142 while (sem->value == 0) {
143 sem->cond->wait(sem->mutex);
147 sem->mutex->unlock();
152 static int sem_destroy(sem_t *sem)
159 #endif /* defined(__DARWIN__) */
162 /* startupinfo *****************************************************************
164 Struct used to pass info from threads_start_thread to
165 threads_startup_thread.
167 ******************************************************************************/
170 threadobject *thread; /* threadobject for this thread */
171 functionptr function; /* function to run in the new thread */
172 sem_t *psem; /* signals when thread has been entered */
173 /* in the thread list */
174 sem_t *psem_first; /* signals when pthread_create has returned */
178 /* prototypes *****************************************************************/
180 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
183 /******************************************************************************/
184 /* GLOBAL VARIABLES */
185 /******************************************************************************/
187 /* the thread object of the current thread */
188 /* This is either a thread-local variable defined with __thread, or */
189 /* a thread-specific value stored with key threads_current_threadobject_key. */
190 #if defined(HAVE___THREAD)
191 __thread threadobject *thread_current;
193 pthread_key_t thread_current_key;
196 /* global mutex for stop-the-world */
197 static Mutex* stopworldlock;
199 #if defined(ENABLE_GC_CACAO)
200 /* global mutex for the GC */
201 static Mutex* mutex_gc;
204 /* global mutex and condition for joining threads on exit */
205 static Mutex* mutex_join;
206 static Condition* cond_join;
208 #if defined(ENABLE_GC_CACAO)
209 /* semaphore used for acknowleding thread suspension */
210 static sem_t suspend_ack;
214 /* threads_sem_init ************************************************************
216 Initialize a semaphore. Checks against errors and interruptions.
219 sem..............the semaphore to initialize
220 shared...........true if this semaphore will be shared between processes
221 value............the initial value for the semaphore
223 *******************************************************************************/
225 void threads_sem_init(sem_t *sem, bool shared, int value)
232 r = sem_init(sem, shared, value);
235 } while (errno == EINTR);
237 vm_abort("sem_init failed: %s", strerror(errno));
241 /* threads_sem_wait ************************************************************
243 Wait for a semaphore, non-interruptible.
245 IMPORTANT: Always use this function instead of `sem_wait` directly, as
246 `sem_wait` may be interrupted by signals!
249 sem..............the semaphore to wait on
251 *******************************************************************************/
253 void threads_sem_wait(sem_t *sem)
263 } while (errno == EINTR);
265 vm_abort("sem_wait failed: %s", strerror(errno));
269 /* threads_sem_post ************************************************************
271 Increase the count of a semaphore. Checks for errors.
274 sem..............the semaphore to increase the count of
276 *******************************************************************************/
278 void threads_sem_post(sem_t *sem)
284 /* unlike sem_wait, sem_post is not interruptible */
290 vm_abort("sem_post failed: %s", strerror(errno));
294 /* threads_stopworld ***********************************************************
296 Stops the world from turning. All threads except the calling one
297 are suspended. The function returns as soon as all threads have
298 acknowledged their suspension.
300 *******************************************************************************/
302 #if defined(ENABLE_GC_CACAO)
303 void threads_stopworld(void)
305 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
312 stopworldlock->lock();
314 /* lock the threads lists */
318 #if defined(__DARWIN__)
319 /*threads_cast_darwinstop();*/
321 #elif defined(__CYGWIN__)
327 DEBUGTHREADS("stops World", self);
331 /* suspend all running threads */
332 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
333 /* don't send the signal to ourself */
338 /* don't send the signal to NEW threads (because they are not
339 completely initialized) */
341 if (t->state == THREAD_STATE_NEW)
344 /* send the signal */
346 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
349 /* increase threads count */
354 /* wait for all threads signaled to suspend */
355 for (i = 0; i < count; i++)
356 threads_sem_wait(&suspend_ack);
359 /* ATTENTION: Don't unlock the threads-lists here so that
360 non-signaled NEW threads can't change their state and execute
366 /* threads_startworld **********************************************************
368 Starts the world again after it has previously been stopped.
370 *******************************************************************************/
372 #if defined(ENABLE_GC_CACAO)
373 void threads_startworld(void)
375 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
382 #if defined(__DARWIN__)
383 /*threads_cast_darwinresume();*/
385 #elif defined(__IRIX__)
386 threads_cast_irixresume();
387 #elif defined(__CYGWIN__)
393 DEBUGTHREADS("starts World", self);
397 /* resume all thread we haltet */
398 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
399 /* don't send the signal to ourself */
404 /* don't send the signal to NEW threads (because they are not
405 completely initialized) */
407 if (t->state == THREAD_STATE_NEW)
410 /* send the signal */
412 result = threads_resume_thread(t);
415 /* increase threads count */
420 /* wait for all threads signaled to suspend */
421 for (i = 0; i < count; i++)
422 threads_sem_wait(&suspend_ack);
426 /* unlock the threads lists */
430 stopworldlock->unlock();
435 /* threads_impl_thread_clear ***************************************************
437 Clears all fields in threadobject the way an MZERO would have
438 done. MZERO cannot be used anymore because it would mess up the
442 t....the threadobject
444 *******************************************************************************/
446 void threads_impl_thread_clear(threadobject *t)
458 #if defined(__DARWIN__)
462 t->interrupted = false;
465 t->suspended = false;
466 t->suspend_reason = 0;
470 t->_exceptionptr = NULL;
471 t->_stackframeinfo = NULL;
472 t->_localref_table = NULL;
474 #if defined(ENABLE_INTRP)
475 t->_global_sp = NULL;
478 #if defined(ENABLE_GC_CACAO)
479 t->gc_critical = false;
485 // Simply reuse the existing dump memory.
488 /* threads_impl_thread_reuse ***************************************************
490 Resets some implementation fields in threadobject. This was
491 previously done in threads_impl_thread_new.
494 t....the threadobject
496 *******************************************************************************/
498 void threads_impl_thread_reuse(threadobject *t)
500 /* get the pthread id */
502 t->tid = pthread_self();
504 #if defined(ENABLE_DEBUG_FILTER)
505 /* Initialize filter counters */
506 t->filterverbosecallctr[0] = 0;
507 t->filterverbosecallctr[1] = 0;
511 t->tracejavacallindent = 0;
512 t->tracejavacallcount = 0;
519 /* not really needed */
520 t->flc_object = NULL;
522 #if defined(ENABLE_TLH)
523 tlh_destroy(&(t->tlh));
529 /* threads_impl_thread_free ****************************************************
531 Cleanup thread stuff.
534 t....the threadobject
536 *******************************************************************************/
540 void threads_impl_thread_free(threadobject *t)
544 /* Destroy the mutex and the condition. */
548 result = pthread_cond_destroy(&(t->flc_cond));
551 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
555 result = pthread_cond_destroy(&(t->waitcond));
558 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
560 delete t->suspendmutex;
562 result = pthread_cond_destroy(&(t->suspendcond));
565 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
570 /* threads_impl_preinit ********************************************************
572 Do some early initialization of stuff required.
574 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
575 is called AFTER this function!
577 *******************************************************************************/
579 void threads_impl_preinit(void)
583 stopworldlock = new Mutex();
585 /* initialize exit mutex and condition (on exit we join all
588 mutex_join = new Mutex();
589 cond_join = new Condition();
591 #if defined(ENABLE_GC_CACAO)
592 /* initialize the GC mutex & suspend semaphore */
594 mutex_gc = new Mutex();
595 threads_sem_init(&suspend_ack, 0, 0);
598 #if !defined(HAVE___THREAD)
599 result = pthread_key_create(&thread_current_key, NULL);
601 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
606 /* threads_mutex_gc_lock *******************************************************
608 Enter the global GC mutex.
610 *******************************************************************************/
612 #if defined(ENABLE_GC_CACAO)
613 void threads_mutex_gc_lock(void)
620 /* threads_mutex_gc_unlock *****************************************************
622 Leave the global GC mutex.
624 *******************************************************************************/
626 #if defined(ENABLE_GC_CACAO)
627 void threads_mutex_gc_unlock(void)
633 /* threads_mutex_join_lock *****************************************************
635 Enter the join mutex.
637 *******************************************************************************/
639 void threads_mutex_join_lock(void)
645 /* threads_mutex_join_unlock ***************************************************
647 Leave the join mutex.
649 *******************************************************************************/
651 void threads_mutex_join_unlock(void)
653 mutex_join->unlock();
657 /* threads_impl_init ***********************************************************
659 Initializes the implementation specific bits.
661 *******************************************************************************/
663 void threads_impl_init(void)
668 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
670 /* Initialize the thread attribute object. */
672 result = pthread_attr_init(&attr);
675 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
677 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
680 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
684 /* threads_startup_thread ******************************************************
686 Thread startup function called by pthread_create.
688 Thread which have a startup.function != NULL are marked as internal
689 threads. All other threads are threated as normal Java threads.
691 NOTE: This function is not called directly by pthread_create. The Boehm GC
692 inserts its own GC_start_routine in between, which then calls
696 arg..........the argument passed to pthread_create, ie. a pointer to
697 a startupinfo struct. CAUTION: When the `psem` semaphore
698 is posted, the startupinfo struct becomes invalid! (It
699 is allocated on the stack of threads_start_thread.)
701 ******************************************************************************/
703 static void *threads_startup_thread(void *arg)
705 startupinfo *startup;
710 functionptr function;
712 #if defined(ENABLE_GC_BOEHM)
713 # if !defined(__DARWIN__)
714 struct GC_stack_base sb;
719 #if defined(ENABLE_INTRP)
720 u1 *intrp_thread_stack;
723 #if defined(ENABLE_INTRP)
724 /* create interpreter stack */
727 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
728 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
731 intrp_thread_stack = NULL;
734 /* get passed startupinfo structure and the values in there */
736 startup = (startupinfo*) arg;
739 function = startup->function;
740 psem = startup->psem;
742 /* Seems like we've encountered a situation where thread->tid was
743 not set by pthread_create. We alleviate this problem by waiting
744 for pthread_create to return. */
746 threads_sem_wait(startup->psem_first);
748 #if defined(__DARWIN__)
749 t->mach_thread = mach_thread_self();
752 /* Now that we are in the new thread, we can store the internal
753 thread data-structure in the TSD. */
755 thread_set_current(t);
757 #if defined(ENABLE_GC_BOEHM)
758 # if defined(__DARWIN__)
759 // This is currently not implemented in Boehm-GC. Just fail silently.
761 /* Register the thread with Boehm-GC. This must happen before the
762 thread allocates any memory from the GC heap.*/
764 result = GC_get_stack_base(&sb);
767 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
769 GC_register_my_thread(&sb);
773 // Get the java.lang.Thread object for this thread.
774 java_handle_t* object = thread_get_object(t);
775 java_lang_Thread jlt(object);
777 /* set our priority */
779 threads_set_thread_priority(t->tid, jlt.get_priority());
781 /* Thread is completely initialized. */
783 thread_set_state_runnable(t);
785 /* tell threads_startup_thread that we registered ourselves */
786 /* CAUTION: *startup becomes invalid with this! */
789 threads_sem_post(psem);
791 #if defined(ENABLE_INTRP)
792 /* set interpreter stack */
795 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
798 #if defined(ENABLE_JVMTI)
799 /* fire thread start event */
802 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
805 DEBUGTHREADS("starting", t);
807 /* find and run the Thread.run()V method if no other function was passed */
809 if (function == NULL) {
810 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
811 /* We need to start the run method of
812 java.lang.VMThread. Since this is a final class, we can use
813 the class object directly. */
815 c = class_java_lang_VMThread;
816 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
817 LLNI_class_get(object, c);
819 # error unknown classpath configuration
822 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
825 vm_abort("threads_startup_thread: run() method not found in class");
827 /* set ThreadMXBean variables */
829 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
830 /* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
832 /* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
833 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
834 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
835 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
838 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
840 // We need to start the run method of java.lang.VMThread.
841 java_lang_VMThread jlvmt(jlt.get_vmThread());
842 java_handle_t* h = jlvmt.get_handle();
844 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
846 java_handle_t* h = jlt.get_handle();
849 # error unknown classpath configuration
852 /* Run the thread. */
854 (void) vm_call_method(m, h);
857 /* set ThreadMXBean variables */
859 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
860 /* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
862 /* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
863 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
864 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
865 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
868 /* call passed function, e.g. finalizer_thread */
873 DEBUGTHREADS("stopping", t);
875 #if defined(ENABLE_JVMTI)
876 /* fire thread end event */
879 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
882 /* We ignore the return value. */
884 (void) thread_detach_current_thread();
886 /* set ThreadMXBean variables */
888 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--; */
895 /* threads_impl_thread_start ***************************************************
897 Start a thread in the JVM. Both (vm internal and java) thread
901 thread....the thread object
902 f.........function to run in the new thread. NULL means that the
903 "run" method of the object `t` should be called
905 ******************************************************************************/
907 void threads_impl_thread_start(threadobject *thread, functionptr f)
915 /* fill startupinfo structure passed by pthread_create to
916 * threads_startup_thread */
918 startup.thread = thread;
919 startup.function = f; /* maybe we don't call Thread.run()V */
921 startup.psem_first = &sem_first;
923 threads_sem_init(&sem, 0, 0);
924 threads_sem_init(&sem_first, 0, 0);
926 /* Initialize thread attributes. */
928 result = pthread_attr_init(&attr);
931 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
933 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
936 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
938 /* initialize thread stacksize */
940 result = pthread_attr_setstacksize(&attr, opt_stacksize);
943 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
945 /* create the thread */
947 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
950 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
952 /* destroy the thread attributes */
954 result = pthread_attr_destroy(&attr);
957 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
959 /* signal that pthread_create has returned, so thread->tid is valid */
961 threads_sem_post(&sem_first);
963 /* wait here until the thread has entered itself into the thread list */
965 threads_sem_wait(&sem);
970 sem_destroy(&sem_first);
974 /* threads_set_thread_priority *************************************************
976 Set the priority of the given thread.
979 tid..........thread id
980 priority.....priority to set
982 ******************************************************************************/
984 void threads_set_thread_priority(pthread_t tid, int priority)
986 struct sched_param schedp;
989 pthread_getschedparam(tid, &policy, &schedp);
990 schedp.sched_priority = priority;
991 pthread_setschedparam(tid, policy, &schedp);
996 * Detaches the current thread from the VM.
998 * @return true on success, false otherwise
1000 bool thread_detach_current_thread(void)
1002 threadobject* t = thread_get_current();
1008 /* If the given thread has already been detached, this operation
1011 if (thread_is_attached(t) == false)
1014 DEBUGTHREADS("detaching", t);
1016 java_handle_t* object = thread_get_object(t);
1017 java_lang_Thread jlt(object);
1019 #if defined(ENABLE_JAVASE)
1020 java_handle_t* group = jlt.get_group();
1022 /* If there's an uncaught exception, call uncaughtException on the
1023 thread's exception handler, or the thread's group if this is
1026 java_handle_t* e = exceptions_get_and_clear_exception();
1029 /* We use the type void* for handler here, as it's not trivial
1030 to build the java_lang_Thread_UncaughtExceptionHandler
1031 header file with cacaoh. */
1033 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1035 java_handle_t* handler = jlt.get_exceptionHandler();
1037 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1039 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
1046 if (handler != NULL) {
1047 LLNI_class_get(handler, c);
1048 h = (java_handle_t *) handler;
1051 LLNI_class_get(group, c);
1052 h = (java_handle_t *) group;
1055 methodinfo* m = class_resolveclassmethod(c,
1056 utf_uncaughtException,
1057 utf_java_lang_Thread_java_lang_Throwable__V,
1064 (void) vm_call_method(m, h, object, e);
1066 if (exceptions_get_exception())
1070 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1072 /* Remove thread from the thread group. */
1074 if (group != NULL) {
1076 LLNI_class_get(group, c);
1078 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1079 methodinfo* m = class_resolveclassmethod(c,
1081 utf_java_lang_Thread__V,
1082 class_java_lang_ThreadGroup,
1084 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1085 methodinfo* m = class_resolveclassmethod(c,
1087 utf_java_lang_Thread__V,
1088 class_java_lang_ThreadGroup,
1091 # error unknown classpath configuration
1097 (void) vm_call_method(m, group, object);
1099 if (exceptions_get_exception())
1102 // Clear the ThreadGroup in the Java thread object (Mauve
1103 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1104 jlt.set_group(NULL);
1108 /* Thread has terminated. */
1110 thread_set_state_terminated(t);
1112 /* Notify all threads waiting on this thread. These are joining
1115 /* XXX Care about exceptions? */
1116 (void) lock_monitor_enter(jlt.get_handle());
1118 lock_notify_all_object(jlt.get_handle());
1120 /* XXX Care about exceptions? */
1121 (void) lock_monitor_exit(jlt.get_handle());
1123 /* Enter the join-mutex before calling thread_free, so
1124 threads_join_all_threads gets the correct number of non-daemon
1127 threads_mutex_join_lock();
1129 /* Free the internal thread data-structure. */
1133 /* Signal that this thread has finished and leave the mutex. */
1135 cond_join->signal();
1136 threads_mutex_join_unlock();
1142 /* threads_suspend_thread ******************************************************
1144 Suspend the passed thread. Execution stops until the thread
1145 is explicitly resumend again.
1148 reason.....Reason for suspending this thread.
1150 *******************************************************************************/
1152 bool threads_suspend_thread(threadobject *thread, s4 reason)
1154 /* acquire the suspendmutex */
1155 thread->suspendmutex->lock();
1157 if (thread->suspended) {
1158 thread->suspendmutex->unlock();
1162 /* set the reason for the suspension */
1163 thread->suspend_reason = reason;
1165 /* send the suspend signal to the thread */
1166 assert(thread != THREADOBJECT);
1167 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1168 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1171 /* REMEMBER: do not release the suspendmutex, this is done
1172 by the thread itself in threads_suspend_ack(). */
1178 /* threads_suspend_ack *********************************************************
1180 Acknowledges the suspension of the current thread.
1183 pc.....The PC where the thread suspended its execution.
1184 sp.....The SP before the thread suspended its execution.
1186 *******************************************************************************/
1188 #if defined(ENABLE_GC_CACAO)
1189 void threads_suspend_ack(u1* pc, u1* sp)
1191 threadobject *thread;
1193 thread = THREADOBJECT;
1195 assert(thread->suspend_reason != 0);
1197 /* TODO: remember dump memory size */
1199 /* inform the GC about the suspension */
1200 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1202 /* check if the GC wants to leave the thread running */
1203 if (!gc_suspend(thread, pc, sp)) {
1205 /* REMEMBER: we do not unlock the suspendmutex because the thread
1206 will suspend itself again at a later time */
1212 /* mark this thread as suspended and remember the PC */
1214 thread->suspended = true;
1216 /* if we are stopping the world, we should send a global ack */
1217 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1218 threads_sem_post(&suspend_ack);
1221 DEBUGTHREADS("suspending", thread);
1223 /* release the suspension mutex and wait till we are resumed */
1224 thread->suspendcond->wait(thread->suspendmutex);
1226 DEBUGTHREADS("resuming", thread);
1228 /* if we are stopping the world, we should send a global ack */
1229 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1230 threads_sem_post(&suspend_ack);
1233 /* TODO: free dump memory */
1235 /* release the suspendmutex */
1236 thread->suspendmutex->unlock();
1241 /* threads_resume_thread *******************************************************
1243 Resumes the execution of the passed thread.
1245 *******************************************************************************/
1247 #if defined(ENABLE_GC_CACAO)
1248 bool threads_resume_thread(threadobject *thread)
1250 /* acquire the suspendmutex */
1251 thread->suspendmutex->lock();
1253 if (!thread->suspended) {
1254 thread->suspendmutex->unlock();
1258 thread->suspended = false;
1260 /* tell everyone that the thread should resume */
1261 assert(thread != THREADOBJECT);
1262 thread->suspendcond->broadcast();
1264 /* release the suspendmutex */
1265 thread->suspendmutex->unlock();
1272 /* threads_join_all_threads ****************************************************
1274 Join all non-daemon threads.
1276 *******************************************************************************/
1278 void threads_join_all_threads(void)
1282 /* get current thread */
1286 /* This thread is waiting for all non-daemon threads to exit. */
1288 thread_set_state_waiting(t);
1290 /* enter join mutex */
1292 threads_mutex_join_lock();
1294 /* Wait for condition as long as we have non-daemon threads. We
1295 compare against 1 because the current (main thread) is also a
1296 non-daemon thread. */
1298 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1299 cond_join->wait(mutex_join);
1301 /* leave join mutex */
1303 threads_mutex_join_unlock();
1307 /* threads_timespec_earlier ****************************************************
1309 Return true if timespec tv1 is earlier than timespec tv2.
1312 tv1..........first timespec
1313 tv2..........second timespec
1316 true, if the first timespec is earlier
1318 *******************************************************************************/
1320 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1321 const struct timespec *tv2)
1323 return (tv1->tv_sec < tv2->tv_sec)
1325 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1329 /* threads_current_time_is_earlier_than ****************************************
1331 Check if the current time is earlier than the given timespec.
1334 tv...........the timespec to compare against
1337 true, if the current time is earlier
1339 *******************************************************************************/
1341 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1343 struct timeval tvnow;
1344 struct timespec tsnow;
1346 /* get current time */
1348 if (gettimeofday(&tvnow, NULL) != 0)
1349 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1351 /* convert it to a timespec */
1353 tsnow.tv_sec = tvnow.tv_sec;
1354 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1356 /* compare current time with the given timespec */
1358 return threads_timespec_earlier(&tsnow, tv);
1362 /* threads_wait_with_timeout ***************************************************
1364 Wait until the given point in time on a monitor until either
1365 we are notified, we are interrupted, or the time is up.
1368 t............the current thread
1369 wakeupTime...absolute (latest) wakeup time
1370 If both tv_sec and tv_nsec are zero, this function
1371 waits for an unlimited amount of time.
1373 *******************************************************************************/
1375 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1377 // Acquire the waitmutex.
1378 t->waitmutex->lock();
1380 /* wait on waitcond */
1382 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1384 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1385 && threads_current_time_is_earlier_than(wakeupTime))
1388 thread_set_state_timed_parked(t);
1390 thread_set_state_timed_waiting(t);
1392 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1394 thread_set_state_runnable(t);
1399 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1401 thread_set_state_parked(t);
1403 thread_set_state_waiting(t);
1405 t->waitcond->wait(t->waitmutex);
1407 thread_set_state_runnable(t);
1412 t->park_permit = false;
1414 // Release the waitmutex.
1415 t->waitmutex->unlock();
1419 /* threads_wait_with_timeout_relative ******************************************
1421 Wait for the given maximum amount of time on a monitor until either
1422 we are notified, we are interrupted, or the time is up.
1425 t............the current thread
1426 millis.......milliseconds to wait
1427 nanos........nanoseconds to wait
1429 *******************************************************************************/
1431 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1434 struct timespec wakeupTime;
1436 /* calculate the the (latest) wakeup time */
1438 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1442 threads_wait_with_timeout(thread, &wakeupTime, false);
1446 /* threads_calc_absolute_time **************************************************
1448 Calculate the absolute point in time a given number of ms and ns from now.
1451 millis............milliseconds from now
1452 nanos.............nanoseconds from now
1455 *tm...............receives the timespec of the absolute point in time
1457 *******************************************************************************/
1459 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1461 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1463 if (!millis && !nanos)
1466 gettimeofday(&tv, NULL);
1467 s8 secs = tv.tv_sec + millis / 1000;
1468 if (secs > INT32_MAX) // integer overflow
1472 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1473 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1474 if (tm->tv_sec < tv.tv_sec) // integer overflow
1476 tm->tv_nsec = nsec % 1000000000;
1484 /* threads_thread_interrupt ****************************************************
1486 Interrupt the given thread.
1488 The thread gets the "waitcond" signal and
1489 its interrupted flag is set to true.
1492 thread............the thread to interrupt
1494 *******************************************************************************/
1496 void threads_thread_interrupt(threadobject *t)
1498 /* Signal the thread a "waitcond" and tell it that it has been
1501 t->waitmutex->lock();
1503 DEBUGTHREADS("interrupted", t);
1505 /* Interrupt blocking system call using a signal. */
1507 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1509 t->waitcond->signal();
1511 t->interrupted = true;
1513 t->waitmutex->unlock();
1518 * Sleep the current thread for the specified amount of time.
1520 * @param millis Milliseconds to sleep.
1521 * @param nanos Nanoseconds to sleep.
1523 void threads_sleep(int64_t millis, int32_t nanos)
1526 struct timespec wakeupTime;
1530 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1531 exceptions_throw_illegalargumentexception();
1535 t = thread_get_current();
1537 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1538 /* Clear interrupted flag (Mauve test:
1539 gnu/testlet/java/lang/Thread/interrupt). */
1541 thread_set_interrupted(t, false);
1543 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1544 exceptions_throw_interruptedexception();
1548 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1549 // Note: JDK treats a zero length sleep is like Thread.yield(),
1550 // without checking the interrupted status of the thread. It's
1551 // unclear if this is a bug in the implementation or the spec.
1552 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1553 if (millis == 0 && nanos == 0) {
1557 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1559 threads_wait_with_timeout(t, &wakeupTime, false);
1561 interrupted = thread_is_interrupted(t);
1564 thread_set_interrupted(t, false);
1566 // An other exception could have been thrown
1567 // (e.g. ThreadDeathException).
1568 if (!exceptions_get_exception())
1569 exceptions_throw_interruptedexception();
1575 * Park the current thread for the specified amount of time or until a
1576 * specified deadline.
1578 * @param absolute Is the time in nanos a deadline or a duration?
1579 * @param nanos Nanoseconds to park (absolute=false)
1580 * or deadline in milliseconds (absolute=true)
1582 void threads_park(bool absolute, int64_t nanos)
1585 struct timespec wakeupTime;
1587 t = thread_get_current();
1590 wakeupTime.tv_nsec = 0;
1591 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1594 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1596 threads_wait_with_timeout(t, &wakeupTime, true);
1600 * Unpark the specified thread.
1602 * @param t The thread to unpark.
1604 void threads_unpark(threadobject *t)
1606 t->waitmutex->lock();
1608 t->waitcond->signal();
1610 t->park_permit = true;
1612 t->waitmutex->unlock();
1616 /* threads_yield ***************************************************************
1618 Yield to the scheduler.
1620 *******************************************************************************/
1622 void threads_yield(void)
1627 #if defined(ENABLE_TLH)
1629 void threads_tlh_add_frame() {
1630 tlh_add_frame(&(THREADOBJECT->tlh));
1633 void threads_tlh_remove_frame() {
1634 tlh_remove_frame(&(THREADOBJECT->tlh));
1641 * These are local overrides for various environment variables in Emacs.
1642 * Please do not remove this and leave it at the end of the file, where
1643 * Emacs will automagically detect them.
1644 * ---------------------------------------------------------------------
1647 * indent-tabs-mode: t
1651 * vim:noexpandtab:sw=4:ts=4: