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/hook.hpp"
70 #include "vm/javaobjects.hpp"
71 #include "vm/options.h"
73 #include "vm/signallocal.hpp"
74 #include "vm/string.hpp"
77 #if defined(ENABLE_STATISTICS)
78 # include "vm/statistics.h"
81 #include "vm/jit/asmpart.h"
83 #if defined(__DARWIN__)
84 # include <mach/mach.h>
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"
111 #if defined(__DARWIN__)
112 /* Darwin has no working semaphore implementation. This one is taken
116 This is a very simple semaphore implementation for Darwin. It
117 is implemented in terms of pthreads calls so it isn't async signal
118 safe. This isn't a problem because signals aren't used to
119 suspend threads on Darwin.
122 static int sem_init(sem_t *sem, int pshared, int value)
127 sem->mutex = new Mutex();
128 sem->cond = new Condition();
134 static int sem_post(sem_t *sem)
139 sem->mutex->unlock();
144 static int sem_wait(sem_t *sem)
148 while (sem->value == 0) {
149 sem->cond->wait(sem->mutex);
153 sem->mutex->unlock();
158 static int sem_destroy(sem_t *sem)
165 #endif /* defined(__DARWIN__) */
168 /* startupinfo *****************************************************************
170 Struct used to pass info from threads_start_thread to
171 threads_startup_thread.
173 ******************************************************************************/
176 threadobject *thread; /* threadobject for this thread */
177 functionptr function; /* function to run in the new thread */
178 sem_t *psem; /* signals when thread has been entered */
179 /* in the thread list */
180 sem_t *psem_first; /* signals when pthread_create has returned */
184 /* prototypes *****************************************************************/
186 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
189 /******************************************************************************/
190 /* GLOBAL VARIABLES */
191 /******************************************************************************/
193 /* the thread object of the current thread */
194 /* This is either a thread-local variable defined with __thread, or */
195 /* a thread-specific value stored with key threads_current_threadobject_key. */
196 #if defined(HAVE___THREAD)
197 __thread threadobject *thread_current;
199 pthread_key_t thread_current_key;
202 /* global mutex for stop-the-world */
203 static Mutex* stopworldlock;
205 #if defined(ENABLE_GC_CACAO)
206 /* global mutex for the GC */
207 static Mutex* mutex_gc;
210 /* global mutex and condition for joining threads on exit */
211 static Mutex* mutex_join;
212 static Condition* cond_join;
214 #if defined(ENABLE_GC_CACAO)
215 /* semaphore used for acknowleding thread suspension */
216 static sem_t suspend_ack;
220 /* threads_sem_init ************************************************************
222 Initialize a semaphore. Checks against errors and interruptions.
225 sem..............the semaphore to initialize
226 shared...........true if this semaphore will be shared between processes
227 value............the initial value for the semaphore
229 *******************************************************************************/
231 void threads_sem_init(sem_t *sem, bool shared, int value)
238 r = sem_init(sem, shared, value);
241 } while (errno == EINTR);
243 vm_abort("sem_init failed: %s", strerror(errno));
247 /* threads_sem_wait ************************************************************
249 Wait for a semaphore, non-interruptible.
251 IMPORTANT: Always use this function instead of `sem_wait` directly, as
252 `sem_wait` may be interrupted by signals!
255 sem..............the semaphore to wait on
257 *******************************************************************************/
259 void threads_sem_wait(sem_t *sem)
269 } while (errno == EINTR);
271 vm_abort("sem_wait failed: %s", strerror(errno));
275 /* threads_sem_post ************************************************************
277 Increase the count of a semaphore. Checks for errors.
280 sem..............the semaphore to increase the count of
282 *******************************************************************************/
284 void threads_sem_post(sem_t *sem)
290 /* unlike sem_wait, sem_post is not interruptible */
296 vm_abort("sem_post failed: %s", strerror(errno));
300 /* threads_stopworld ***********************************************************
302 Stops the world from turning. All threads except the calling one
303 are suspended. The function returns as soon as all threads have
304 acknowledged their suspension.
306 *******************************************************************************/
308 #if defined(ENABLE_GC_CACAO)
309 void threads_stopworld(void)
311 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
318 stopworldlock->lock();
320 /* lock the threads lists */
324 #if defined(__DARWIN__)
325 /*threads_cast_darwinstop();*/
327 #elif defined(__CYGWIN__)
333 DEBUGTHREADS("stops World", self);
337 /* suspend all running threads */
338 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
339 /* don't send the signal to ourself */
344 /* don't send the signal to NEW threads (because they are not
345 completely initialized) */
347 if (t->state == THREAD_STATE_NEW)
350 /* send the signal */
352 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
355 /* increase threads count */
360 /* wait for all threads signaled to suspend */
361 for (i = 0; i < count; i++)
362 threads_sem_wait(&suspend_ack);
365 /* ATTENTION: Don't unlock the threads-lists here so that
366 non-signaled NEW threads can't change their state and execute
372 /* threads_startworld **********************************************************
374 Starts the world again after it has previously been stopped.
376 *******************************************************************************/
378 #if defined(ENABLE_GC_CACAO)
379 void threads_startworld(void)
381 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
388 #if defined(__DARWIN__)
389 /*threads_cast_darwinresume();*/
391 #elif defined(__IRIX__)
392 threads_cast_irixresume();
393 #elif defined(__CYGWIN__)
399 DEBUGTHREADS("starts World", self);
403 /* resume all thread we haltet */
404 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
405 /* don't send the signal to ourself */
410 /* don't send the signal to NEW threads (because they are not
411 completely initialized) */
413 if (t->state == THREAD_STATE_NEW)
416 /* send the signal */
418 result = threads_resume_thread(t);
421 /* increase threads count */
426 /* wait for all threads signaled to suspend */
427 for (i = 0; i < count; i++)
428 threads_sem_wait(&suspend_ack);
432 /* unlock the threads lists */
436 stopworldlock->unlock();
441 /* threads_impl_thread_clear ***************************************************
443 Clears all fields in threadobject the way an MZERO would have
444 done. MZERO cannot be used anymore because it would mess up the
448 t....the threadobject
450 *******************************************************************************/
452 void threads_impl_thread_clear(threadobject *t)
464 #if defined(__DARWIN__)
468 t->interrupted = false;
471 t->suspended = false;
472 t->suspend_reason = 0;
476 t->_exceptionptr = NULL;
477 t->_stackframeinfo = NULL;
478 t->_localref_table = NULL;
480 #if defined(ENABLE_INTRP)
481 t->_global_sp = NULL;
484 #if defined(ENABLE_GC_CACAO)
485 t->gc_critical = false;
491 // Simply reuse the existing dump memory.
494 /* threads_impl_thread_reuse ***************************************************
496 Resets some implementation fields in threadobject. This was
497 previously done in threads_impl_thread_new.
500 t....the threadobject
502 *******************************************************************************/
504 void threads_impl_thread_reuse(threadobject *t)
506 /* get the pthread id */
508 t->tid = pthread_self();
510 #if defined(ENABLE_DEBUG_FILTER)
511 /* Initialize filter counters */
512 t->filterverbosecallctr[0] = 0;
513 t->filterverbosecallctr[1] = 0;
517 t->tracejavacallindent = 0;
518 t->tracejavacallcount = 0;
525 /* not really needed */
526 t->flc_object = NULL;
528 #if defined(ENABLE_TLH)
529 tlh_destroy(&(t->tlh));
535 /* threads_impl_thread_free ****************************************************
537 Cleanup thread stuff.
540 t....the threadobject
542 *******************************************************************************/
546 void threads_impl_thread_free(threadobject *t)
550 /* Destroy the mutex and the condition. */
554 result = pthread_cond_destroy(&(t->flc_cond));
557 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
561 result = pthread_cond_destroy(&(t->waitcond));
564 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
566 delete t->suspendmutex;
568 result = pthread_cond_destroy(&(t->suspendcond));
571 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
576 /* threads_impl_preinit ********************************************************
578 Do some early initialization of stuff required.
580 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
581 is called AFTER this function!
583 *******************************************************************************/
585 void threads_impl_preinit(void)
589 stopworldlock = new Mutex();
591 /* initialize exit mutex and condition (on exit we join all
594 mutex_join = new Mutex();
595 cond_join = new Condition();
597 #if defined(ENABLE_GC_CACAO)
598 /* initialize the GC mutex & suspend semaphore */
600 mutex_gc = new Mutex();
601 threads_sem_init(&suspend_ack, 0, 0);
604 #if !defined(HAVE___THREAD)
605 result = pthread_key_create(&thread_current_key, NULL);
607 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
612 /* threads_mutex_gc_lock *******************************************************
614 Enter the global GC mutex.
616 *******************************************************************************/
618 #if defined(ENABLE_GC_CACAO)
619 void threads_mutex_gc_lock(void)
626 /* threads_mutex_gc_unlock *****************************************************
628 Leave the global GC mutex.
630 *******************************************************************************/
632 #if defined(ENABLE_GC_CACAO)
633 void threads_mutex_gc_unlock(void)
639 /* threads_mutex_join_lock *****************************************************
641 Enter the join mutex.
643 *******************************************************************************/
645 void threads_mutex_join_lock(void)
651 /* threads_mutex_join_unlock ***************************************************
653 Leave the join mutex.
655 *******************************************************************************/
657 void threads_mutex_join_unlock(void)
659 mutex_join->unlock();
663 /* threads_impl_init ***********************************************************
665 Initializes the implementation specific bits.
667 *******************************************************************************/
669 void threads_impl_init(void)
674 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
676 /* Initialize the thread attribute object. */
678 result = pthread_attr_init(&attr);
681 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
683 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
686 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
690 /* threads_startup_thread ******************************************************
692 Thread startup function called by pthread_create.
694 Thread which have a startup.function != NULL are marked as internal
695 threads. All other threads are threated as normal Java threads.
697 NOTE: This function is not called directly by pthread_create. The Boehm GC
698 inserts its own GC_start_routine in between, which then calls
702 arg..........the argument passed to pthread_create, ie. a pointer to
703 a startupinfo struct. CAUTION: When the `psem` semaphore
704 is posted, the startupinfo struct becomes invalid! (It
705 is allocated on the stack of threads_start_thread.)
707 ******************************************************************************/
709 static void *threads_startup_thread(void *arg)
711 startupinfo *startup;
716 functionptr function;
718 #if defined(ENABLE_GC_BOEHM)
719 # if !defined(__DARWIN__)
720 struct GC_stack_base sb;
725 #if defined(ENABLE_INTRP)
726 u1 *intrp_thread_stack;
729 #if defined(ENABLE_INTRP)
730 /* create interpreter stack */
733 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
734 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
737 intrp_thread_stack = NULL;
740 /* get passed startupinfo structure and the values in there */
742 startup = (startupinfo*) arg;
745 function = startup->function;
746 psem = startup->psem;
748 /* Seems like we've encountered a situation where thread->tid was
749 not set by pthread_create. We alleviate this problem by waiting
750 for pthread_create to return. */
752 threads_sem_wait(startup->psem_first);
754 #if defined(__DARWIN__)
755 t->mach_thread = mach_thread_self();
758 /* Now that we are in the new thread, we can store the internal
759 thread data-structure in the TSD. */
761 thread_set_current(t);
763 #if defined(ENABLE_GC_BOEHM)
764 # if defined(__DARWIN__)
765 // This is currently not implemented in Boehm-GC. Just fail silently.
767 /* Register the thread with Boehm-GC. This must happen before the
768 thread allocates any memory from the GC heap.*/
770 result = GC_get_stack_base(&sb);
773 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
775 GC_register_my_thread(&sb);
779 // Get the java.lang.Thread object for this thread.
780 java_handle_t* object = thread_get_object(t);
781 java_lang_Thread jlt(object);
783 /* set our priority */
785 threads_set_thread_priority(t->tid, jlt.get_priority());
787 /* Thread is completely initialized. */
789 thread_set_state_runnable(t);
791 /* tell threads_startup_thread that we registered ourselves */
792 /* CAUTION: *startup becomes invalid with this! */
795 threads_sem_post(psem);
797 #if defined(ENABLE_INTRP)
798 /* set interpreter stack */
801 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
804 // Hook point just before the threads initial method is executed.
805 Hook::thread_start(t);
807 DEBUGTHREADS("starting", t);
809 /* find and run the Thread.run()V method if no other function was passed */
811 if (function == NULL) {
812 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
813 /* We need to start the run method of
814 java.lang.VMThread. Since this is a final class, we can use
815 the class object directly. */
817 c = class_java_lang_VMThread;
818 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
819 LLNI_class_get(object, c);
821 # error unknown classpath configuration
824 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
827 vm_abort("threads_startup_thread: run() method not found in class");
829 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
831 // We need to start the run method of java.lang.VMThread.
832 java_lang_VMThread jlvmt(jlt.get_vmThread());
833 java_handle_t* h = jlvmt.get_handle();
835 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
837 java_handle_t* h = jlt.get_handle();
840 # error unknown classpath configuration
843 /* Run the thread. */
845 (void) vm_call_method(m, h);
848 /* call passed function, e.g. finalizer_thread */
853 DEBUGTHREADS("stopping", t);
855 // Hook point just after the threads initial method returned.
858 /* We ignore the return value. */
860 (void) thread_detach_current_thread();
866 /* threads_impl_thread_start ***************************************************
868 Start a thread in the JVM. Both (vm internal and java) thread
872 thread....the thread object
873 f.........function to run in the new thread. NULL means that the
874 "run" method of the object `t` should be called
876 ******************************************************************************/
878 void threads_impl_thread_start(threadobject *thread, functionptr f)
886 /* fill startupinfo structure passed by pthread_create to
887 * threads_startup_thread */
889 startup.thread = thread;
890 startup.function = f; /* maybe we don't call Thread.run()V */
892 startup.psem_first = &sem_first;
894 threads_sem_init(&sem, 0, 0);
895 threads_sem_init(&sem_first, 0, 0);
897 /* Initialize thread attributes. */
899 result = pthread_attr_init(&attr);
902 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
904 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
907 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
909 /* initialize thread stacksize */
911 result = pthread_attr_setstacksize(&attr, opt_stacksize);
914 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
916 /* create the thread */
918 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
921 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
923 /* destroy the thread attributes */
925 result = pthread_attr_destroy(&attr);
928 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
930 /* signal that pthread_create has returned, so thread->tid is valid */
932 threads_sem_post(&sem_first);
934 /* wait here until the thread has entered itself into the thread list */
936 threads_sem_wait(&sem);
941 sem_destroy(&sem_first);
945 /* threads_set_thread_priority *************************************************
947 Set the priority of the given thread.
950 tid..........thread id
951 priority.....priority to set
953 ******************************************************************************/
955 void threads_set_thread_priority(pthread_t tid, int priority)
957 struct sched_param schedp;
960 pthread_getschedparam(tid, &policy, &schedp);
961 schedp.sched_priority = priority;
962 pthread_setschedparam(tid, policy, &schedp);
967 * Detaches the current thread from the VM.
969 * @return true on success, false otherwise
971 bool thread_detach_current_thread(void)
973 threadobject* t = thread_get_current();
979 /* If the given thread has already been detached, this operation
982 if (thread_is_attached(t) == false)
985 DEBUGTHREADS("detaching", t);
987 java_handle_t* object = thread_get_object(t);
988 java_lang_Thread jlt(object);
990 #if defined(ENABLE_JAVASE)
991 java_handle_t* group = jlt.get_group();
993 /* If there's an uncaught exception, call uncaughtException on the
994 thread's exception handler, or the thread's group if this is
997 java_handle_t* e = exceptions_get_and_clear_exception();
1000 /* We use the type void* for handler here, as it's not trivial
1001 to build the java_lang_Thread_UncaughtExceptionHandler
1002 header file with cacaoh. */
1004 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1006 java_handle_t* handler = jlt.get_exceptionHandler();
1008 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1010 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
1017 if (handler != NULL) {
1018 LLNI_class_get(handler, c);
1019 h = (java_handle_t *) handler;
1022 LLNI_class_get(group, c);
1023 h = (java_handle_t *) group;
1026 methodinfo* m = class_resolveclassmethod(c,
1027 utf_uncaughtException,
1028 utf_java_lang_Thread_java_lang_Throwable__V,
1035 (void) vm_call_method(m, h, object, e);
1037 if (exceptions_get_exception())
1041 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1043 /* Remove thread from the thread group. */
1045 if (group != NULL) {
1047 LLNI_class_get(group, c);
1049 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1050 methodinfo* m = class_resolveclassmethod(c,
1052 utf_java_lang_Thread__V,
1053 class_java_lang_ThreadGroup,
1055 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1056 methodinfo* m = class_resolveclassmethod(c,
1058 utf_java_lang_Thread__V,
1059 class_java_lang_ThreadGroup,
1062 # error unknown classpath configuration
1068 (void) vm_call_method(m, group, object);
1070 if (exceptions_get_exception())
1073 // Clear the ThreadGroup in the Java thread object (Mauve
1074 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1075 jlt.set_group(NULL);
1079 /* Thread has terminated. */
1081 thread_set_state_terminated(t);
1083 /* Notify all threads waiting on this thread. These are joining
1086 /* XXX Care about exceptions? */
1087 (void) lock_monitor_enter(jlt.get_handle());
1089 lock_notify_all_object(jlt.get_handle());
1091 /* XXX Care about exceptions? */
1092 (void) lock_monitor_exit(jlt.get_handle());
1094 /* Enter the join-mutex before calling thread_free, so
1095 threads_join_all_threads gets the correct number of non-daemon
1098 threads_mutex_join_lock();
1100 /* Free the internal thread data-structure. */
1104 /* Signal that this thread has finished and leave the mutex. */
1106 cond_join->signal();
1107 threads_mutex_join_unlock();
1114 * Internal helper function which suspends the current thread. This is
1115 * the core method of the suspension mechanism actually blocking the
1116 * execution until the suspension reason is cleared again. Note that
1117 * the current thread needs to hold the suspension mutex while calling
1120 static void threads_suspend_self()
1122 threadobject* thread = THREADOBJECT;
1124 DEBUGTHREADS("suspending", thread);
1126 // Mark thread as suspended.
1127 assert(!thread->suspended);
1128 assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1129 thread->suspended = true;
1131 // Acknowledge the suspension.
1132 thread->suspendcond->broadcast();
1134 #if defined(ENABLE_GC_CACAO)
1135 // If we are stopping the world, we should send a global ack.
1136 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1137 threads_sem_post(&suspend_ack);
1140 // Release the suspension mutex and wait till we are resumed.
1141 thread->suspendcond->wait(thread->suspendmutex);
1143 #if defined(ENABLE_GC_CACAO)
1144 // XXX This is propably not ok!
1145 // If we are starting the world, we should send a global ack.
1146 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1147 threads_sem_post(&suspend_ack);
1150 // Mark thread as not suspended.
1151 assert(thread->suspended);
1152 assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1153 thread->suspended = false;
1155 DEBUGTHREADS("resuming", thread);
1160 * Suspend the passed thread. Execution of that thread stops until the thread
1161 * is explicitly resumend again.
1163 * @param thread The thread to be suspended.
1164 * @param reason Reason for suspending the given thread.
1165 * @return True of operation was successful, false otherwise.
1167 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1170 assert(reason != SUSPEND_REASON_NONE);
1172 // Guard this with the suspension mutex.
1173 MutexLocker ml(*thread->suspendmutex);
1175 // Check if thread is already suspended.
1176 if (thread->suspended)
1179 // Check if thread is in the process of suspending.
1180 if (thread->suspend_reason != SUSPEND_REASON_NONE)
1183 // Set the reason for suspending the thread.
1184 thread->suspend_reason = reason;
1186 if (thread == THREADOBJECT) {
1187 // We already hold the suspension mutex and can suspend ourselves
1188 // immediately without using signals at all.
1189 threads_suspend_self();
1192 // Send the suspend signal to the other thread.
1193 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1194 os::abort_errno("threads_suspend_thread: pthread_kill failed");
1196 // Wait for the thread to acknowledge the suspension.
1197 // XXX A possible optimization would be to not wait here, but you
1198 // better think this through twice before trying it!
1199 thread->suspendcond->wait(thread->suspendmutex);
1207 * Resumes execution of the passed thread.
1209 * @param thread The thread to be resumed.
1210 * @param reason Reason for suspending the given thread.
1211 * @return True of operation was successful, false otherwise.
1213 bool threads_resume_thread(threadobject *thread, int32_t reason)
1216 assert(thread != THREADOBJECT);
1217 assert(reason != SUSPEND_REASON_NONE);
1219 // Guard this with the suspension mutex.
1220 MutexLocker ml(*thread->suspendmutex);
1222 // Check if thread really is suspended.
1223 if (!thread->suspended)
1226 // Threads can only be resumed for the same reason they were suspended.
1227 if (thread->suspend_reason != reason)
1230 // Clear the reason for suspending the thread.
1231 thread->suspend_reason = SUSPEND_REASON_NONE;
1233 // Tell everyone that the thread should resume.
1234 thread->suspendcond->broadcast();
1241 * Acknowledges the suspension of the current thread.
1243 void threads_suspend_ack()
1245 threadobject* thread = THREADOBJECT;
1247 // Guard this with the suspension mutex.
1248 MutexLocker ml(*thread->suspendmutex);
1250 // Suspend ourselves while holding the suspension mutex.
1251 threads_suspend_self();
1255 /* threads_join_all_threads ****************************************************
1257 Join all non-daemon threads.
1259 *******************************************************************************/
1261 void threads_join_all_threads(void)
1265 /* get current thread */
1269 /* This thread is waiting for all non-daemon threads to exit. */
1271 thread_set_state_waiting(t);
1273 /* enter join mutex */
1275 threads_mutex_join_lock();
1277 /* Wait for condition as long as we have non-daemon threads. We
1278 compare against 1 because the current (main thread) is also a
1279 non-daemon thread. */
1281 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1282 cond_join->wait(mutex_join);
1284 /* leave join mutex */
1286 threads_mutex_join_unlock();
1290 /* threads_timespec_earlier ****************************************************
1292 Return true if timespec tv1 is earlier than timespec tv2.
1295 tv1..........first timespec
1296 tv2..........second timespec
1299 true, if the first timespec is earlier
1301 *******************************************************************************/
1303 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1304 const struct timespec *tv2)
1306 return (tv1->tv_sec < tv2->tv_sec)
1308 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1312 /* threads_current_time_is_earlier_than ****************************************
1314 Check if the current time is earlier than the given timespec.
1317 tv...........the timespec to compare against
1320 true, if the current time is earlier
1322 *******************************************************************************/
1324 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1326 struct timeval tvnow;
1327 struct timespec tsnow;
1329 /* get current time */
1331 if (gettimeofday(&tvnow, NULL) != 0)
1332 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1334 /* convert it to a timespec */
1336 tsnow.tv_sec = tvnow.tv_sec;
1337 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1339 /* compare current time with the given timespec */
1341 return threads_timespec_earlier(&tsnow, tv);
1345 /* threads_wait_with_timeout ***************************************************
1347 Wait until the given point in time on a monitor until either
1348 we are notified, we are interrupted, or the time is up.
1351 t............the current thread
1352 wakeupTime...absolute (latest) wakeup time
1353 If both tv_sec and tv_nsec are zero, this function
1354 waits for an unlimited amount of time.
1356 *******************************************************************************/
1358 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1360 // Acquire the waitmutex.
1361 t->waitmutex->lock();
1363 /* wait on waitcond */
1365 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1367 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1368 && threads_current_time_is_earlier_than(wakeupTime))
1371 thread_set_state_timed_parked(t);
1373 thread_set_state_timed_waiting(t);
1375 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1377 thread_set_state_runnable(t);
1382 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1384 thread_set_state_parked(t);
1386 thread_set_state_waiting(t);
1388 t->waitcond->wait(t->waitmutex);
1390 thread_set_state_runnable(t);
1395 t->park_permit = false;
1397 // Release the waitmutex.
1398 t->waitmutex->unlock();
1402 /* threads_wait_with_timeout_relative ******************************************
1404 Wait for the given maximum amount of time on a monitor until either
1405 we are notified, we are interrupted, or the time is up.
1408 t............the current thread
1409 millis.......milliseconds to wait
1410 nanos........nanoseconds to wait
1412 *******************************************************************************/
1414 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1417 struct timespec wakeupTime;
1419 /* calculate the the (latest) wakeup time */
1421 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1425 threads_wait_with_timeout(thread, &wakeupTime, false);
1429 /* threads_calc_absolute_time **************************************************
1431 Calculate the absolute point in time a given number of ms and ns from now.
1434 millis............milliseconds from now
1435 nanos.............nanoseconds from now
1438 *tm...............receives the timespec of the absolute point in time
1440 *******************************************************************************/
1442 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1444 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1446 if (!millis && !nanos)
1449 gettimeofday(&tv, NULL);
1450 s8 secs = tv.tv_sec + millis / 1000;
1451 if (secs > INT32_MAX) // integer overflow
1455 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1456 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1457 if (tm->tv_sec < tv.tv_sec) // integer overflow
1459 tm->tv_nsec = nsec % 1000000000;
1467 /* threads_thread_interrupt ****************************************************
1469 Interrupt the given thread.
1471 The thread gets the "waitcond" signal and
1472 its interrupted flag is set to true.
1475 thread............the thread to interrupt
1477 *******************************************************************************/
1479 void threads_thread_interrupt(threadobject *t)
1481 /* Signal the thread a "waitcond" and tell it that it has been
1484 t->waitmutex->lock();
1486 DEBUGTHREADS("interrupted", t);
1488 /* Interrupt blocking system call using a signal. */
1490 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1492 t->waitcond->signal();
1494 t->interrupted = true;
1496 t->waitmutex->unlock();
1501 * Sleep the current thread for the specified amount of time.
1503 * @param millis Milliseconds to sleep.
1504 * @param nanos Nanoseconds to sleep.
1506 void threads_sleep(int64_t millis, int32_t nanos)
1509 struct timespec wakeupTime;
1513 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1514 exceptions_throw_illegalargumentexception();
1518 t = thread_get_current();
1520 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1521 /* Clear interrupted flag (Mauve test:
1522 gnu/testlet/java/lang/Thread/interrupt). */
1524 thread_set_interrupted(t, false);
1526 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1527 exceptions_throw_interruptedexception();
1531 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1532 // Note: JDK treats a zero length sleep is like Thread.yield(),
1533 // without checking the interrupted status of the thread. It's
1534 // unclear if this is a bug in the implementation or the spec.
1535 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1536 if (millis == 0 && nanos == 0) {
1540 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1542 threads_wait_with_timeout(t, &wakeupTime, false);
1544 interrupted = thread_is_interrupted(t);
1547 thread_set_interrupted(t, false);
1549 // An other exception could have been thrown
1550 // (e.g. ThreadDeathException).
1551 if (!exceptions_get_exception())
1552 exceptions_throw_interruptedexception();
1558 * Park the current thread for the specified amount of time or until a
1559 * specified deadline.
1561 * @param absolute Is the time in nanos a deadline or a duration?
1562 * @param nanos Nanoseconds to park (absolute=false)
1563 * or deadline in milliseconds (absolute=true)
1565 void threads_park(bool absolute, int64_t nanos)
1568 struct timespec wakeupTime;
1570 t = thread_get_current();
1573 wakeupTime.tv_nsec = 0;
1574 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1577 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1579 threads_wait_with_timeout(t, &wakeupTime, true);
1583 * Unpark the specified thread.
1585 * @param t The thread to unpark.
1587 void threads_unpark(threadobject *t)
1589 t->waitmutex->lock();
1591 t->waitcond->signal();
1593 t->park_permit = true;
1595 t->waitmutex->unlock();
1599 /* threads_yield ***************************************************************
1601 Yield to the scheduler.
1603 *******************************************************************************/
1605 void threads_yield(void)
1610 #if defined(ENABLE_TLH)
1612 void threads_tlh_add_frame() {
1613 tlh_add_frame(&(THREADOBJECT->tlh));
1616 void threads_tlh_remove_frame() {
1617 tlh_remove_frame(&(THREADOBJECT->tlh));
1624 * These are local overrides for various environment variables in Emacs.
1625 * Please do not remove this and leave it at the end of the file, where
1626 * Emacs will automagically detect them.
1627 * ---------------------------------------------------------------------
1630 * indent-tabs-mode: t
1634 * vim:noexpandtab:sw=4:ts=4: