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"
71 #include "vm/signallocal.hpp"
72 #include "vm/string.hpp"
75 #if defined(ENABLE_STATISTICS)
76 # include "vm/statistics.h"
79 #include "vm/jit/asmpart.h"
81 #if !defined(__DARWIN__)
82 # include <semaphore.h>
85 #if defined(__LINUX__)
86 # define GC_LINUX_THREADS
87 #elif defined(__IRIX__)
88 # define GC_IRIX_THREADS
89 #elif defined(__DARWIN__)
90 # define GC_DARWIN_THREADS
93 #if defined(ENABLE_GC_BOEHM)
94 /* We need to include Boehm's gc.h here because it overrides
95 pthread_create and friends. */
96 # include "mm/boehm-gc/include/gc.h"
99 #if defined(ENABLE_JVMTI)
100 #include "native/jvmti/cacaodbg.h"
104 #if defined(__DARWIN__)
105 /* Darwin has no working semaphore implementation. This one is taken
109 This is a very simple semaphore implementation for Darwin. It
110 is implemented in terms of pthreads calls so it isn't async signal
111 safe. This isn't a problem because signals aren't used to
112 suspend threads on Darwin.
115 static int sem_init(sem_t *sem, int pshared, int value)
120 sem->mutex = new Mutex();
121 sem->cond = new Condition();
127 static int sem_post(sem_t *sem)
132 sem->mutex->unlock();
137 static int sem_wait(sem_t *sem)
141 while (sem->value == 0) {
142 sem->cond->wait(sem->mutex);
146 sem->mutex->unlock();
151 static int sem_destroy(sem_t *sem)
158 #endif /* defined(__DARWIN__) */
161 /* startupinfo *****************************************************************
163 Struct used to pass info from threads_start_thread to
164 threads_startup_thread.
166 ******************************************************************************/
169 threadobject *thread; /* threadobject for this thread */
170 functionptr function; /* function to run in the new thread */
171 sem_t *psem; /* signals when thread has been entered */
172 /* in the thread list */
173 sem_t *psem_first; /* signals when pthread_create has returned */
177 /* prototypes *****************************************************************/
179 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
182 /******************************************************************************/
183 /* GLOBAL VARIABLES */
184 /******************************************************************************/
186 /* the thread object of the current thread */
187 /* This is either a thread-local variable defined with __thread, or */
188 /* a thread-specific value stored with key threads_current_threadobject_key. */
189 #if defined(HAVE___THREAD)
190 __thread threadobject *thread_current;
192 pthread_key_t thread_current_key;
195 /* global mutex for stop-the-world */
196 static Mutex* stopworldlock;
198 #if defined(ENABLE_GC_CACAO)
199 /* global mutex for the GC */
200 static Mutex* mutex_gc;
203 /* global mutex and condition for joining threads on exit */
204 static Mutex* mutex_join;
205 static Condition* cond_join;
207 #if defined(ENABLE_GC_CACAO)
208 /* semaphore used for acknowleding thread suspension */
209 static sem_t suspend_ack;
213 /* threads_sem_init ************************************************************
215 Initialize a semaphore. Checks against errors and interruptions.
218 sem..............the semaphore to initialize
219 shared...........true if this semaphore will be shared between processes
220 value............the initial value for the semaphore
222 *******************************************************************************/
224 void threads_sem_init(sem_t *sem, bool shared, int value)
231 r = sem_init(sem, shared, value);
234 } while (errno == EINTR);
236 vm_abort("sem_init failed: %s", strerror(errno));
240 /* threads_sem_wait ************************************************************
242 Wait for a semaphore, non-interruptible.
244 IMPORTANT: Always use this function instead of `sem_wait` directly, as
245 `sem_wait` may be interrupted by signals!
248 sem..............the semaphore to wait on
250 *******************************************************************************/
252 void threads_sem_wait(sem_t *sem)
262 } while (errno == EINTR);
264 vm_abort("sem_wait failed: %s", strerror(errno));
268 /* threads_sem_post ************************************************************
270 Increase the count of a semaphore. Checks for errors.
273 sem..............the semaphore to increase the count of
275 *******************************************************************************/
277 void threads_sem_post(sem_t *sem)
283 /* unlike sem_wait, sem_post is not interruptible */
289 vm_abort("sem_post failed: %s", strerror(errno));
293 /* threads_stopworld ***********************************************************
295 Stops the world from turning. All threads except the calling one
296 are suspended. The function returns as soon as all threads have
297 acknowledged their suspension.
299 *******************************************************************************/
301 #if defined(ENABLE_GC_CACAO)
302 void threads_stopworld(void)
304 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
311 stopworldlock->lock();
313 /* lock the threads lists */
317 #if defined(__DARWIN__)
318 /*threads_cast_darwinstop();*/
320 #elif defined(__CYGWIN__)
326 DEBUGTHREADS("stops World", self);
330 /* suspend all running threads */
331 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
332 /* don't send the signal to ourself */
337 /* don't send the signal to NEW threads (because they are not
338 completely initialized) */
340 if (t->state == THREAD_STATE_NEW)
343 /* send the signal */
345 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
348 /* increase threads count */
353 /* wait for all threads signaled to suspend */
354 for (i = 0; i < count; i++)
355 threads_sem_wait(&suspend_ack);
358 /* ATTENTION: Don't unlock the threads-lists here so that
359 non-signaled NEW threads can't change their state and execute
365 /* threads_startworld **********************************************************
367 Starts the world again after it has previously been stopped.
369 *******************************************************************************/
371 #if defined(ENABLE_GC_CACAO)
372 void threads_startworld(void)
374 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
381 #if defined(__DARWIN__)
382 /*threads_cast_darwinresume();*/
384 #elif defined(__IRIX__)
385 threads_cast_irixresume();
386 #elif defined(__CYGWIN__)
392 DEBUGTHREADS("starts World", self);
396 /* resume all thread we haltet */
397 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
398 /* don't send the signal to ourself */
403 /* don't send the signal to NEW threads (because they are not
404 completely initialized) */
406 if (t->state == THREAD_STATE_NEW)
409 /* send the signal */
411 result = threads_resume_thread(t);
414 /* increase threads count */
419 /* wait for all threads signaled to suspend */
420 for (i = 0; i < count; i++)
421 threads_sem_wait(&suspend_ack);
425 /* unlock the threads lists */
429 stopworldlock->unlock();
434 /* threads_impl_thread_clear ***************************************************
436 Clears all fields in threadobject the way an MZERO would have
437 done. MZERO cannot be used anymore because it would mess up the
441 t....the threadobject
443 *******************************************************************************/
445 void threads_impl_thread_clear(threadobject *t)
457 #if defined(__DARWIN__)
461 t->interrupted = false;
464 t->suspended = false;
465 t->suspend_reason = 0;
469 t->_exceptionptr = NULL;
470 t->_stackframeinfo = NULL;
471 t->_localref_table = NULL;
473 #if defined(ENABLE_INTRP)
474 t->_global_sp = NULL;
477 #if defined(ENABLE_GC_CACAO)
478 t->gc_critical = false;
484 // Simply reuse the existing dump memory.
487 /* threads_impl_thread_reuse ***************************************************
489 Resets some implementation fields in threadobject. This was
490 previously done in threads_impl_thread_new.
493 t....the threadobject
495 *******************************************************************************/
497 void threads_impl_thread_reuse(threadobject *t)
499 /* get the pthread id */
501 t->tid = pthread_self();
503 #if defined(ENABLE_DEBUG_FILTER)
504 /* Initialize filter counters */
505 t->filterverbosecallctr[0] = 0;
506 t->filterverbosecallctr[1] = 0;
510 t->tracejavacallindent = 0;
511 t->tracejavacallcount = 0;
518 /* not really needed */
519 t->flc_object = NULL;
521 #if defined(ENABLE_TLH)
522 tlh_destroy(&(t->tlh));
528 /* threads_impl_thread_free ****************************************************
530 Cleanup thread stuff.
533 t....the threadobject
535 *******************************************************************************/
539 void threads_impl_thread_free(threadobject *t)
543 /* Destroy the mutex and the condition. */
547 result = pthread_cond_destroy(&(t->flc_cond));
550 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
554 result = pthread_cond_destroy(&(t->waitcond));
557 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
559 delete t->suspendmutex;
561 result = pthread_cond_destroy(&(t->suspendcond));
564 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
569 /* threads_impl_preinit ********************************************************
571 Do some early initialization of stuff required.
573 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
574 is called AFTER this function!
576 *******************************************************************************/
578 void threads_impl_preinit(void)
582 stopworldlock = new Mutex();
584 /* initialize exit mutex and condition (on exit we join all
587 mutex_join = new Mutex();
588 cond_join = new Condition();
590 #if defined(ENABLE_GC_CACAO)
591 /* initialize the GC mutex & suspend semaphore */
593 mutex_gc = new Mutex();
594 threads_sem_init(&suspend_ack, 0, 0);
597 #if !defined(HAVE___THREAD)
598 result = pthread_key_create(&thread_current_key, NULL);
600 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
605 /* threads_mutex_gc_lock *******************************************************
607 Enter the global GC mutex.
609 *******************************************************************************/
611 #if defined(ENABLE_GC_CACAO)
612 void threads_mutex_gc_lock(void)
619 /* threads_mutex_gc_unlock *****************************************************
621 Leave the global GC mutex.
623 *******************************************************************************/
625 #if defined(ENABLE_GC_CACAO)
626 void threads_mutex_gc_unlock(void)
632 /* threads_mutex_join_lock *****************************************************
634 Enter the join mutex.
636 *******************************************************************************/
638 void threads_mutex_join_lock(void)
644 /* threads_mutex_join_unlock ***************************************************
646 Leave the join mutex.
648 *******************************************************************************/
650 void threads_mutex_join_unlock(void)
652 mutex_join->unlock();
656 /* threads_impl_init ***********************************************************
658 Initializes the implementation specific bits.
660 *******************************************************************************/
662 void threads_impl_init(void)
667 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
669 /* Initialize the thread attribute object. */
671 result = pthread_attr_init(&attr);
674 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
676 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
679 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
683 /* threads_startup_thread ******************************************************
685 Thread startup function called by pthread_create.
687 Thread which have a startup.function != NULL are marked as internal
688 threads. All other threads are threated as normal Java threads.
690 NOTE: This function is not called directly by pthread_create. The Boehm GC
691 inserts its own GC_start_routine in between, which then calls
695 arg..........the argument passed to pthread_create, ie. a pointer to
696 a startupinfo struct. CAUTION: When the `psem` semaphore
697 is posted, the startupinfo struct becomes invalid! (It
698 is allocated on the stack of threads_start_thread.)
700 ******************************************************************************/
702 static void *threads_startup_thread(void *arg)
704 startupinfo *startup;
709 functionptr function;
711 #if defined(ENABLE_GC_BOEHM)
712 # if !defined(__DARWIN__)
713 struct GC_stack_base sb;
718 #if defined(ENABLE_INTRP)
719 u1 *intrp_thread_stack;
722 #if defined(ENABLE_INTRP)
723 /* create interpreter stack */
726 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
727 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
730 intrp_thread_stack = NULL;
733 /* get passed startupinfo structure and the values in there */
735 startup = (startupinfo*) arg;
738 function = startup->function;
739 psem = startup->psem;
741 /* Seems like we've encountered a situation where thread->tid was
742 not set by pthread_create. We alleviate this problem by waiting
743 for pthread_create to return. */
745 threads_sem_wait(startup->psem_first);
747 #if defined(__DARWIN__)
748 t->mach_thread = mach_thread_self();
751 /* Now that we are in the new thread, we can store the internal
752 thread data-structure in the TSD. */
754 thread_set_current(t);
756 #if defined(ENABLE_GC_BOEHM)
757 # if defined(__DARWIN__)
758 // This is currently not implemented in Boehm-GC. Just fail silently.
760 /* Register the thread with Boehm-GC. This must happen before the
761 thread allocates any memory from the GC heap.*/
763 result = GC_get_stack_base(&sb);
766 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
768 GC_register_my_thread(&sb);
772 // Get the java.lang.Thread object for this thread.
773 java_handle_t* object = thread_get_object(t);
774 java_lang_Thread jlt(object);
776 /* set our priority */
778 threads_set_thread_priority(t->tid, jlt.get_priority());
780 /* Thread is completely initialized. */
782 thread_set_state_runnable(t);
784 /* tell threads_startup_thread that we registered ourselves */
785 /* CAUTION: *startup becomes invalid with this! */
788 threads_sem_post(psem);
790 #if defined(ENABLE_INTRP)
791 /* set interpreter stack */
794 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
797 #if defined(ENABLE_JVMTI)
798 /* fire thread start event */
801 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
804 DEBUGTHREADS("starting", t);
806 /* find and run the Thread.run()V method if no other function was passed */
808 if (function == NULL) {
809 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
810 /* We need to start the run method of
811 java.lang.VMThread. Since this is a final class, we can use
812 the class object directly. */
814 c = class_java_lang_VMThread;
815 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
816 LLNI_class_get(object, c);
818 # error unknown classpath configuration
821 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
824 vm_abort("threads_startup_thread: run() method not found in class");
826 /* set ThreadMXBean variables */
828 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
829 /* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
831 /* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
832 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
833 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
834 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
837 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
839 // We need to start the run method of java.lang.VMThread.
840 java_lang_VMThread jlvmt(jlt.get_vmThread());
841 java_handle_t* h = jlvmt.get_handle();
843 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
845 java_handle_t* h = jlt.get_handle();
848 # error unknown classpath configuration
851 /* Run the thread. */
853 (void) vm_call_method(m, h);
856 /* set ThreadMXBean variables */
858 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++; */
859 /* _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++; */
861 /* if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount > */
862 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount) */
863 /* _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount = */
864 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount; */
867 /* call passed function, e.g. finalizer_thread */
872 DEBUGTHREADS("stopping", t);
874 #if defined(ENABLE_JVMTI)
875 /* fire thread end event */
878 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
881 /* We ignore the return value. */
883 (void) thread_detach_current_thread();
885 /* set ThreadMXBean variables */
887 /* _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--; */
894 /* threads_impl_thread_start ***************************************************
896 Start a thread in the JVM. Both (vm internal and java) thread
900 thread....the thread object
901 f.........function to run in the new thread. NULL means that the
902 "run" method of the object `t` should be called
904 ******************************************************************************/
906 void threads_impl_thread_start(threadobject *thread, functionptr f)
914 /* fill startupinfo structure passed by pthread_create to
915 * threads_startup_thread */
917 startup.thread = thread;
918 startup.function = f; /* maybe we don't call Thread.run()V */
920 startup.psem_first = &sem_first;
922 threads_sem_init(&sem, 0, 0);
923 threads_sem_init(&sem_first, 0, 0);
925 /* Initialize thread attributes. */
927 result = pthread_attr_init(&attr);
930 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
932 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
935 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
937 /* initialize thread stacksize */
939 result = pthread_attr_setstacksize(&attr, opt_stacksize);
942 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
944 /* create the thread */
946 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
949 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
951 /* destroy the thread attributes */
953 result = pthread_attr_destroy(&attr);
956 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
958 /* signal that pthread_create has returned, so thread->tid is valid */
960 threads_sem_post(&sem_first);
962 /* wait here until the thread has entered itself into the thread list */
964 threads_sem_wait(&sem);
969 sem_destroy(&sem_first);
973 /* threads_set_thread_priority *************************************************
975 Set the priority of the given thread.
978 tid..........thread id
979 priority.....priority to set
981 ******************************************************************************/
983 void threads_set_thread_priority(pthread_t tid, int priority)
985 struct sched_param schedp;
988 pthread_getschedparam(tid, &policy, &schedp);
989 schedp.sched_priority = priority;
990 pthread_setschedparam(tid, policy, &schedp);
995 * Detaches the current thread from the VM.
997 * @return true on success, false otherwise
999 bool thread_detach_current_thread(void)
1001 threadobject* t = thread_get_current();
1007 /* If the given thread has already been detached, this operation
1010 if (thread_is_attached(t) == false)
1013 DEBUGTHREADS("detaching", t);
1015 java_handle_t* object = thread_get_object(t);
1016 java_lang_Thread jlt(object);
1018 #if defined(ENABLE_JAVASE)
1019 java_handle_t* group = jlt.get_group();
1021 /* If there's an uncaught exception, call uncaughtException on the
1022 thread's exception handler, or the thread's group if this is
1025 java_handle_t* e = exceptions_get_and_clear_exception();
1028 /* We use the type void* for handler here, as it's not trivial
1029 to build the java_lang_Thread_UncaughtExceptionHandler
1030 header file with cacaoh. */
1032 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1034 java_handle_t* handler = jlt.get_exceptionHandler();
1036 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1038 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
1045 if (handler != NULL) {
1046 LLNI_class_get(handler, c);
1047 h = (java_handle_t *) handler;
1050 LLNI_class_get(group, c);
1051 h = (java_handle_t *) group;
1054 methodinfo* m = class_resolveclassmethod(c,
1055 utf_uncaughtException,
1056 utf_java_lang_Thread_java_lang_Throwable__V,
1063 (void) vm_call_method(m, h, object, e);
1065 if (exceptions_get_exception())
1069 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1071 /* Remove thread from the thread group. */
1073 if (group != NULL) {
1075 LLNI_class_get(group, c);
1077 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1078 methodinfo* m = class_resolveclassmethod(c,
1080 utf_java_lang_Thread__V,
1081 class_java_lang_ThreadGroup,
1083 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1084 methodinfo* m = class_resolveclassmethod(c,
1086 utf_java_lang_Thread__V,
1087 class_java_lang_ThreadGroup,
1090 # error unknown classpath configuration
1096 (void) vm_call_method(m, group, object);
1098 if (exceptions_get_exception())
1101 // Clear the ThreadGroup in the Java thread object (Mauve
1102 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1103 jlt.set_group(NULL);
1107 /* Thread has terminated. */
1109 thread_set_state_terminated(t);
1111 /* Notify all threads waiting on this thread. These are joining
1114 /* XXX Care about exceptions? */
1115 (void) lock_monitor_enter(jlt.get_handle());
1117 lock_notify_all_object(jlt.get_handle());
1119 /* XXX Care about exceptions? */
1120 (void) lock_monitor_exit(jlt.get_handle());
1122 /* Enter the join-mutex before calling thread_free, so
1123 threads_join_all_threads gets the correct number of non-daemon
1126 threads_mutex_join_lock();
1128 /* Free the internal thread data-structure. */
1132 /* Signal that this thread has finished and leave the mutex. */
1134 cond_join->signal();
1135 threads_mutex_join_unlock();
1141 /* threads_suspend_thread ******************************************************
1143 Suspend the passed thread. Execution stops until the thread
1144 is explicitly resumend again.
1147 reason.....Reason for suspending this thread.
1149 *******************************************************************************/
1151 bool threads_suspend_thread(threadobject *thread, s4 reason)
1153 /* acquire the suspendmutex */
1154 thread->suspendmutex->lock();
1156 if (thread->suspended) {
1157 thread->suspendmutex->unlock();
1161 /* set the reason for the suspension */
1162 thread->suspend_reason = reason;
1164 /* send the suspend signal to the thread */
1165 assert(thread != THREADOBJECT);
1166 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1167 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1170 /* REMEMBER: do not release the suspendmutex, this is done
1171 by the thread itself in threads_suspend_ack(). */
1177 /* threads_suspend_ack *********************************************************
1179 Acknowledges the suspension of the current thread.
1182 pc.....The PC where the thread suspended its execution.
1183 sp.....The SP before the thread suspended its execution.
1185 *******************************************************************************/
1187 #if defined(ENABLE_GC_CACAO)
1188 void threads_suspend_ack(u1* pc, u1* sp)
1190 threadobject *thread;
1192 thread = THREADOBJECT;
1194 assert(thread->suspend_reason != 0);
1196 /* TODO: remember dump memory size */
1198 /* inform the GC about the suspension */
1199 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1201 /* check if the GC wants to leave the thread running */
1202 if (!gc_suspend(thread, pc, sp)) {
1204 /* REMEMBER: we do not unlock the suspendmutex because the thread
1205 will suspend itself again at a later time */
1211 /* mark this thread as suspended and remember the PC */
1213 thread->suspended = true;
1215 /* if we are stopping the world, we should send a global ack */
1216 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1217 threads_sem_post(&suspend_ack);
1220 DEBUGTHREADS("suspending", thread);
1222 /* release the suspension mutex and wait till we are resumed */
1223 thread->suspendcond->wait(thread->suspendmutex);
1225 DEBUGTHREADS("resuming", thread);
1227 /* if we are stopping the world, we should send a global ack */
1228 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1229 threads_sem_post(&suspend_ack);
1232 /* TODO: free dump memory */
1234 /* release the suspendmutex */
1235 thread->suspendmutex->unlock();
1240 /* threads_resume_thread *******************************************************
1242 Resumes the execution of the passed thread.
1244 *******************************************************************************/
1246 #if defined(ENABLE_GC_CACAO)
1247 bool threads_resume_thread(threadobject *thread)
1249 /* acquire the suspendmutex */
1250 thread->suspendmutex->lock();
1252 if (!thread->suspended) {
1253 thread->suspendmutex->unlock();
1257 thread->suspended = false;
1259 /* tell everyone that the thread should resume */
1260 assert(thread != THREADOBJECT);
1261 thread->suspendcond->broadcast();
1263 /* release the suspendmutex */
1264 thread->suspendmutex->unlock();
1271 /* threads_join_all_threads ****************************************************
1273 Join all non-daemon threads.
1275 *******************************************************************************/
1277 void threads_join_all_threads(void)
1281 /* get current thread */
1285 /* This thread is waiting for all non-daemon threads to exit. */
1287 thread_set_state_waiting(t);
1289 /* enter join mutex */
1291 threads_mutex_join_lock();
1293 /* Wait for condition as long as we have non-daemon threads. We
1294 compare against 1 because the current (main thread) is also a
1295 non-daemon thread. */
1297 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1298 cond_join->wait(mutex_join);
1300 /* leave join mutex */
1302 threads_mutex_join_unlock();
1306 /* threads_timespec_earlier ****************************************************
1308 Return true if timespec tv1 is earlier than timespec tv2.
1311 tv1..........first timespec
1312 tv2..........second timespec
1315 true, if the first timespec is earlier
1317 *******************************************************************************/
1319 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1320 const struct timespec *tv2)
1322 return (tv1->tv_sec < tv2->tv_sec)
1324 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1328 /* threads_current_time_is_earlier_than ****************************************
1330 Check if the current time is earlier than the given timespec.
1333 tv...........the timespec to compare against
1336 true, if the current time is earlier
1338 *******************************************************************************/
1340 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1342 struct timeval tvnow;
1343 struct timespec tsnow;
1345 /* get current time */
1347 if (gettimeofday(&tvnow, NULL) != 0)
1348 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1350 /* convert it to a timespec */
1352 tsnow.tv_sec = tvnow.tv_sec;
1353 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1355 /* compare current time with the given timespec */
1357 return threads_timespec_earlier(&tsnow, tv);
1361 /* threads_wait_with_timeout ***************************************************
1363 Wait until the given point in time on a monitor until either
1364 we are notified, we are interrupted, or the time is up.
1367 t............the current thread
1368 wakeupTime...absolute (latest) wakeup time
1369 If both tv_sec and tv_nsec are zero, this function
1370 waits for an unlimited amount of time.
1372 *******************************************************************************/
1374 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1376 // Acquire the waitmutex.
1377 t->waitmutex->lock();
1379 /* wait on waitcond */
1381 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1383 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1384 && threads_current_time_is_earlier_than(wakeupTime))
1387 thread_set_state_timed_parked(t);
1389 thread_set_state_timed_waiting(t);
1391 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1393 thread_set_state_runnable(t);
1398 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1400 thread_set_state_parked(t);
1402 thread_set_state_waiting(t);
1404 t->waitcond->wait(t->waitmutex);
1406 thread_set_state_runnable(t);
1411 t->park_permit = false;
1413 // Release the waitmutex.
1414 t->waitmutex->unlock();
1418 /* threads_wait_with_timeout_relative ******************************************
1420 Wait for the given maximum amount of time on a monitor until either
1421 we are notified, we are interrupted, or the time is up.
1424 t............the current thread
1425 millis.......milliseconds to wait
1426 nanos........nanoseconds to wait
1428 *******************************************************************************/
1430 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1433 struct timespec wakeupTime;
1435 /* calculate the the (latest) wakeup time */
1437 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1441 threads_wait_with_timeout(thread, &wakeupTime, false);
1445 /* threads_calc_absolute_time **************************************************
1447 Calculate the absolute point in time a given number of ms and ns from now.
1450 millis............milliseconds from now
1451 nanos.............nanoseconds from now
1454 *tm...............receives the timespec of the absolute point in time
1456 *******************************************************************************/
1458 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1460 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1462 if (!millis && !nanos)
1465 gettimeofday(&tv, NULL);
1466 s8 secs = tv.tv_sec + millis / 1000;
1467 if (secs > INT32_MAX) // integer overflow
1471 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1472 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1473 if (tm->tv_sec < tv.tv_sec) // integer overflow
1475 tm->tv_nsec = nsec % 1000000000;
1483 /* threads_thread_interrupt ****************************************************
1485 Interrupt the given thread.
1487 The thread gets the "waitcond" signal and
1488 its interrupted flag is set to true.
1491 thread............the thread to interrupt
1493 *******************************************************************************/
1495 void threads_thread_interrupt(threadobject *t)
1497 /* Signal the thread a "waitcond" and tell it that it has been
1500 t->waitmutex->lock();
1502 DEBUGTHREADS("interrupted", t);
1504 /* Interrupt blocking system call using a signal. */
1506 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1508 t->waitcond->signal();
1510 t->interrupted = true;
1512 t->waitmutex->unlock();
1517 * Sleep the current thread for the specified amount of time.
1519 * @param millis Milliseconds to sleep.
1520 * @param nanos Nanoseconds to sleep.
1522 void threads_sleep(int64_t millis, int32_t nanos)
1525 struct timespec wakeupTime;
1529 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1530 exceptions_throw_illegalargumentexception();
1534 t = thread_get_current();
1536 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1537 /* Clear interrupted flag (Mauve test:
1538 gnu/testlet/java/lang/Thread/interrupt). */
1540 thread_set_interrupted(t, false);
1542 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1543 exceptions_throw_interruptedexception();
1547 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1548 // Note: JDK treats a zero length sleep is like Thread.yield(),
1549 // without checking the interrupted status of the thread. It's
1550 // unclear if this is a bug in the implementation or the spec.
1551 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1552 if (millis == 0 && nanos == 0) {
1556 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1558 threads_wait_with_timeout(t, &wakeupTime, false);
1560 interrupted = thread_is_interrupted(t);
1563 thread_set_interrupted(t, false);
1565 // An other exception could have been thrown
1566 // (e.g. ThreadDeathException).
1567 if (!exceptions_get_exception())
1568 exceptions_throw_interruptedexception();
1574 * Park the current thread for the specified amount of time or until a
1575 * specified deadline.
1577 * @param absolute Is the time in nanos a deadline or a duration?
1578 * @param nanos Nanoseconds to park (absolute=false)
1579 * or deadline in milliseconds (absolute=true)
1581 void threads_park(bool absolute, int64_t nanos)
1584 struct timespec wakeupTime;
1586 t = thread_get_current();
1589 wakeupTime.tv_nsec = 0;
1590 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1593 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1595 threads_wait_with_timeout(t, &wakeupTime, true);
1599 * Unpark the specified thread.
1601 * @param t The thread to unpark.
1603 void threads_unpark(threadobject *t)
1605 t->waitmutex->lock();
1607 t->waitcond->signal();
1609 t->park_permit = true;
1611 t->waitmutex->unlock();
1615 /* threads_yield ***************************************************************
1617 Yield to the scheduler.
1619 *******************************************************************************/
1621 void threads_yield(void)
1626 #if defined(ENABLE_TLH)
1628 void threads_tlh_add_frame() {
1629 tlh_add_frame(&(THREADOBJECT->tlh));
1632 void threads_tlh_remove_frame() {
1633 tlh_remove_frame(&(THREADOBJECT->tlh));
1640 * These are local overrides for various environment variables in Emacs.
1641 * Please do not remove this and leave it at the end of the file, where
1642 * Emacs will automagically detect them.
1643 * ---------------------------------------------------------------------
1646 * indent-tabs-mode: t
1650 * vim:noexpandtab:sw=4:ts=4: