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 <semaphore.h>
87 #if defined(__LINUX__)
88 # define GC_LINUX_THREADS
89 #elif defined(__IRIX__)
90 # define GC_IRIX_THREADS
91 #elif defined(__DARWIN__)
92 # define GC_DARWIN_THREADS
95 #if defined(ENABLE_GC_BOEHM)
96 /* We need to include Boehm's gc.h here because it overrides
97 pthread_create and friends. */
98 # include "mm/boehm-gc/include/gc.h"
102 #if defined(__DARWIN__)
103 /* Darwin has no working semaphore implementation. This one is taken
107 This is a very simple semaphore implementation for Darwin. It
108 is implemented in terms of pthreads calls so it isn't async signal
109 safe. This isn't a problem because signals aren't used to
110 suspend threads on Darwin.
113 static int sem_init(sem_t *sem, int pshared, int value)
118 sem->mutex = new Mutex();
119 sem->cond = new Condition();
125 static int sem_post(sem_t *sem)
130 sem->mutex->unlock();
135 static int sem_wait(sem_t *sem)
139 while (sem->value == 0) {
140 sem->cond->wait(sem->mutex);
144 sem->mutex->unlock();
149 static int sem_destroy(sem_t *sem)
156 #endif /* defined(__DARWIN__) */
159 /* startupinfo *****************************************************************
161 Struct used to pass info from threads_start_thread to
162 threads_startup_thread.
164 ******************************************************************************/
167 threadobject *thread; /* threadobject for this thread */
168 functionptr function; /* function to run in the new thread */
169 sem_t *psem; /* signals when thread has been entered */
170 /* in the thread list */
171 sem_t *psem_first; /* signals when pthread_create has returned */
175 /* prototypes *****************************************************************/
177 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
180 /******************************************************************************/
181 /* GLOBAL VARIABLES */
182 /******************************************************************************/
184 /* the thread object of the current thread */
185 /* This is either a thread-local variable defined with __thread, or */
186 /* a thread-specific value stored with key threads_current_threadobject_key. */
187 #if defined(HAVE___THREAD)
188 __thread threadobject *thread_current;
190 pthread_key_t thread_current_key;
193 /* global mutex for stop-the-world */
194 static Mutex* stopworldlock;
196 #if defined(ENABLE_GC_CACAO)
197 /* global mutex for the GC */
198 static Mutex* mutex_gc;
201 /* global mutex and condition for joining threads on exit */
202 static Mutex* mutex_join;
203 static Condition* cond_join;
205 #if defined(ENABLE_GC_CACAO)
206 /* semaphore used for acknowleding thread suspension */
207 static sem_t suspend_ack;
211 /* threads_sem_init ************************************************************
213 Initialize a semaphore. Checks against errors and interruptions.
216 sem..............the semaphore to initialize
217 shared...........true if this semaphore will be shared between processes
218 value............the initial value for the semaphore
220 *******************************************************************************/
222 void threads_sem_init(sem_t *sem, bool shared, int value)
229 r = sem_init(sem, shared, value);
232 } while (errno == EINTR);
234 vm_abort("sem_init failed: %s", strerror(errno));
238 /* threads_sem_wait ************************************************************
240 Wait for a semaphore, non-interruptible.
242 IMPORTANT: Always use this function instead of `sem_wait` directly, as
243 `sem_wait` may be interrupted by signals!
246 sem..............the semaphore to wait on
248 *******************************************************************************/
250 void threads_sem_wait(sem_t *sem)
260 } while (errno == EINTR);
262 vm_abort("sem_wait failed: %s", strerror(errno));
266 /* threads_sem_post ************************************************************
268 Increase the count of a semaphore. Checks for errors.
271 sem..............the semaphore to increase the count of
273 *******************************************************************************/
275 void threads_sem_post(sem_t *sem)
281 /* unlike sem_wait, sem_post is not interruptible */
287 vm_abort("sem_post failed: %s", strerror(errno));
291 /* threads_stopworld ***********************************************************
293 Stops the world from turning. All threads except the calling one
294 are suspended. The function returns as soon as all threads have
295 acknowledged their suspension.
297 *******************************************************************************/
299 #if defined(ENABLE_GC_CACAO)
300 void threads_stopworld(void)
302 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
309 stopworldlock->lock();
311 /* lock the threads lists */
315 #if defined(__DARWIN__)
316 /*threads_cast_darwinstop();*/
318 #elif defined(__CYGWIN__)
324 DEBUGTHREADS("stops World", self);
328 /* suspend all running threads */
329 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
330 /* don't send the signal to ourself */
335 /* don't send the signal to NEW threads (because they are not
336 completely initialized) */
338 if (t->state == THREAD_STATE_NEW)
341 /* send the signal */
343 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
346 /* increase threads count */
351 /* wait for all threads signaled to suspend */
352 for (i = 0; i < count; i++)
353 threads_sem_wait(&suspend_ack);
356 /* ATTENTION: Don't unlock the threads-lists here so that
357 non-signaled NEW threads can't change their state and execute
363 /* threads_startworld **********************************************************
365 Starts the world again after it has previously been stopped.
367 *******************************************************************************/
369 #if defined(ENABLE_GC_CACAO)
370 void threads_startworld(void)
372 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
379 #if defined(__DARWIN__)
380 /*threads_cast_darwinresume();*/
382 #elif defined(__IRIX__)
383 threads_cast_irixresume();
384 #elif defined(__CYGWIN__)
390 DEBUGTHREADS("starts World", self);
394 /* resume all thread we haltet */
395 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
396 /* don't send the signal to ourself */
401 /* don't send the signal to NEW threads (because they are not
402 completely initialized) */
404 if (t->state == THREAD_STATE_NEW)
407 /* send the signal */
409 result = threads_resume_thread(t);
412 /* increase threads count */
417 /* wait for all threads signaled to suspend */
418 for (i = 0; i < count; i++)
419 threads_sem_wait(&suspend_ack);
423 /* unlock the threads lists */
427 stopworldlock->unlock();
432 /* threads_impl_thread_clear ***************************************************
434 Clears all fields in threadobject the way an MZERO would have
435 done. MZERO cannot be used anymore because it would mess up the
439 t....the threadobject
441 *******************************************************************************/
443 void threads_impl_thread_clear(threadobject *t)
455 #if defined(__DARWIN__)
459 t->interrupted = false;
462 t->suspended = false;
463 t->suspend_reason = 0;
467 t->_exceptionptr = NULL;
468 t->_stackframeinfo = NULL;
469 t->_localref_table = NULL;
471 #if defined(ENABLE_INTRP)
472 t->_global_sp = NULL;
475 #if defined(ENABLE_GC_CACAO)
476 t->gc_critical = false;
482 // Simply reuse the existing dump memory.
485 /* threads_impl_thread_reuse ***************************************************
487 Resets some implementation fields in threadobject. This was
488 previously done in threads_impl_thread_new.
491 t....the threadobject
493 *******************************************************************************/
495 void threads_impl_thread_reuse(threadobject *t)
497 /* get the pthread id */
499 t->tid = pthread_self();
501 #if defined(ENABLE_DEBUG_FILTER)
502 /* Initialize filter counters */
503 t->filterverbosecallctr[0] = 0;
504 t->filterverbosecallctr[1] = 0;
508 t->tracejavacallindent = 0;
509 t->tracejavacallcount = 0;
516 /* not really needed */
517 t->flc_object = NULL;
519 #if defined(ENABLE_TLH)
520 tlh_destroy(&(t->tlh));
526 /* threads_impl_thread_free ****************************************************
528 Cleanup thread stuff.
531 t....the threadobject
533 *******************************************************************************/
537 void threads_impl_thread_free(threadobject *t)
541 /* Destroy the mutex and the condition. */
545 result = pthread_cond_destroy(&(t->flc_cond));
548 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
552 result = pthread_cond_destroy(&(t->waitcond));
555 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
557 delete t->suspendmutex;
559 result = pthread_cond_destroy(&(t->suspendcond));
562 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
567 /* threads_impl_preinit ********************************************************
569 Do some early initialization of stuff required.
571 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
572 is called AFTER this function!
574 *******************************************************************************/
576 void threads_impl_preinit(void)
580 stopworldlock = new Mutex();
582 /* initialize exit mutex and condition (on exit we join all
585 mutex_join = new Mutex();
586 cond_join = new Condition();
588 #if defined(ENABLE_GC_CACAO)
589 /* initialize the GC mutex & suspend semaphore */
591 mutex_gc = new Mutex();
592 threads_sem_init(&suspend_ack, 0, 0);
595 #if !defined(HAVE___THREAD)
596 result = pthread_key_create(&thread_current_key, NULL);
598 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
603 /* threads_mutex_gc_lock *******************************************************
605 Enter the global GC mutex.
607 *******************************************************************************/
609 #if defined(ENABLE_GC_CACAO)
610 void threads_mutex_gc_lock(void)
617 /* threads_mutex_gc_unlock *****************************************************
619 Leave the global GC mutex.
621 *******************************************************************************/
623 #if defined(ENABLE_GC_CACAO)
624 void threads_mutex_gc_unlock(void)
630 /* threads_mutex_join_lock *****************************************************
632 Enter the join mutex.
634 *******************************************************************************/
636 void threads_mutex_join_lock(void)
642 /* threads_mutex_join_unlock ***************************************************
644 Leave the join mutex.
646 *******************************************************************************/
648 void threads_mutex_join_unlock(void)
650 mutex_join->unlock();
654 /* threads_impl_init ***********************************************************
656 Initializes the implementation specific bits.
658 *******************************************************************************/
660 void threads_impl_init(void)
665 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
667 /* Initialize the thread attribute object. */
669 result = pthread_attr_init(&attr);
672 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
674 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
677 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
681 /* threads_startup_thread ******************************************************
683 Thread startup function called by pthread_create.
685 Thread which have a startup.function != NULL are marked as internal
686 threads. All other threads are threated as normal Java threads.
688 NOTE: This function is not called directly by pthread_create. The Boehm GC
689 inserts its own GC_start_routine in between, which then calls
693 arg..........the argument passed to pthread_create, ie. a pointer to
694 a startupinfo struct. CAUTION: When the `psem` semaphore
695 is posted, the startupinfo struct becomes invalid! (It
696 is allocated on the stack of threads_start_thread.)
698 ******************************************************************************/
700 static void *threads_startup_thread(void *arg)
702 startupinfo *startup;
707 functionptr function;
709 #if defined(ENABLE_GC_BOEHM)
710 # if !defined(__DARWIN__)
711 struct GC_stack_base sb;
716 #if defined(ENABLE_INTRP)
717 u1 *intrp_thread_stack;
720 #if defined(ENABLE_INTRP)
721 /* create interpreter stack */
724 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
725 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
728 intrp_thread_stack = NULL;
731 /* get passed startupinfo structure and the values in there */
733 startup = (startupinfo*) arg;
736 function = startup->function;
737 psem = startup->psem;
739 /* Seems like we've encountered a situation where thread->tid was
740 not set by pthread_create. We alleviate this problem by waiting
741 for pthread_create to return. */
743 threads_sem_wait(startup->psem_first);
745 #if defined(__DARWIN__)
746 t->mach_thread = mach_thread_self();
749 /* Now that we are in the new thread, we can store the internal
750 thread data-structure in the TSD. */
752 thread_set_current(t);
754 #if defined(ENABLE_GC_BOEHM)
755 # if defined(__DARWIN__)
756 // This is currently not implemented in Boehm-GC. Just fail silently.
758 /* Register the thread with Boehm-GC. This must happen before the
759 thread allocates any memory from the GC heap.*/
761 result = GC_get_stack_base(&sb);
764 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
766 GC_register_my_thread(&sb);
770 // Get the java.lang.Thread object for this thread.
771 java_handle_t* object = thread_get_object(t);
772 java_lang_Thread jlt(object);
774 /* set our priority */
776 threads_set_thread_priority(t->tid, jlt.get_priority());
778 /* Thread is completely initialized. */
780 thread_set_state_runnable(t);
782 /* tell threads_startup_thread that we registered ourselves */
783 /* CAUTION: *startup becomes invalid with this! */
786 threads_sem_post(psem);
788 #if defined(ENABLE_INTRP)
789 /* set interpreter stack */
792 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
795 // Hook point just before the threads initial method is executed.
796 Hook::thread_start(t);
798 DEBUGTHREADS("starting", t);
800 /* find and run the Thread.run()V method if no other function was passed */
802 if (function == NULL) {
803 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
804 /* We need to start the run method of
805 java.lang.VMThread. Since this is a final class, we can use
806 the class object directly. */
808 c = class_java_lang_VMThread;
809 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
810 LLNI_class_get(object, c);
812 # error unknown classpath configuration
815 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
818 vm_abort("threads_startup_thread: run() method not found in class");
820 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
822 // We need to start the run method of java.lang.VMThread.
823 java_lang_VMThread jlvmt(jlt.get_vmThread());
824 java_handle_t* h = jlvmt.get_handle();
826 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
828 java_handle_t* h = jlt.get_handle();
831 # error unknown classpath configuration
834 /* Run the thread. */
836 (void) vm_call_method(m, h);
839 /* call passed function, e.g. finalizer_thread */
844 DEBUGTHREADS("stopping", t);
846 // Hook point just after the threads initial method returned.
849 /* We ignore the return value. */
851 (void) thread_detach_current_thread();
857 /* threads_impl_thread_start ***************************************************
859 Start a thread in the JVM. Both (vm internal and java) thread
863 thread....the thread object
864 f.........function to run in the new thread. NULL means that the
865 "run" method of the object `t` should be called
867 ******************************************************************************/
869 void threads_impl_thread_start(threadobject *thread, functionptr f)
877 /* fill startupinfo structure passed by pthread_create to
878 * threads_startup_thread */
880 startup.thread = thread;
881 startup.function = f; /* maybe we don't call Thread.run()V */
883 startup.psem_first = &sem_first;
885 threads_sem_init(&sem, 0, 0);
886 threads_sem_init(&sem_first, 0, 0);
888 /* Initialize thread attributes. */
890 result = pthread_attr_init(&attr);
893 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
895 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
898 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
900 /* initialize thread stacksize */
902 result = pthread_attr_setstacksize(&attr, opt_stacksize);
905 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
907 /* create the thread */
909 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
912 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
914 /* destroy the thread attributes */
916 result = pthread_attr_destroy(&attr);
919 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
921 /* signal that pthread_create has returned, so thread->tid is valid */
923 threads_sem_post(&sem_first);
925 /* wait here until the thread has entered itself into the thread list */
927 threads_sem_wait(&sem);
932 sem_destroy(&sem_first);
936 /* threads_set_thread_priority *************************************************
938 Set the priority of the given thread.
941 tid..........thread id
942 priority.....priority to set
944 ******************************************************************************/
946 void threads_set_thread_priority(pthread_t tid, int priority)
948 struct sched_param schedp;
951 pthread_getschedparam(tid, &policy, &schedp);
952 schedp.sched_priority = priority;
953 pthread_setschedparam(tid, policy, &schedp);
958 * Detaches the current thread from the VM.
960 * @return true on success, false otherwise
962 bool thread_detach_current_thread(void)
964 threadobject* t = thread_get_current();
970 /* If the given thread has already been detached, this operation
973 if (thread_is_attached(t) == false)
976 DEBUGTHREADS("detaching", t);
978 java_handle_t* object = thread_get_object(t);
979 java_lang_Thread jlt(object);
981 #if defined(ENABLE_JAVASE)
982 java_handle_t* group = jlt.get_group();
984 /* If there's an uncaught exception, call uncaughtException on the
985 thread's exception handler, or the thread's group if this is
988 java_handle_t* e = exceptions_get_and_clear_exception();
991 /* We use the type void* for handler here, as it's not trivial
992 to build the java_lang_Thread_UncaughtExceptionHandler
993 header file with cacaoh. */
995 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
997 java_handle_t* handler = jlt.get_exceptionHandler();
999 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1001 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
1008 if (handler != NULL) {
1009 LLNI_class_get(handler, c);
1010 h = (java_handle_t *) handler;
1013 LLNI_class_get(group, c);
1014 h = (java_handle_t *) group;
1017 methodinfo* m = class_resolveclassmethod(c,
1018 utf_uncaughtException,
1019 utf_java_lang_Thread_java_lang_Throwable__V,
1026 (void) vm_call_method(m, h, object, e);
1028 if (exceptions_get_exception())
1032 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1034 /* Remove thread from the thread group. */
1036 if (group != NULL) {
1038 LLNI_class_get(group, c);
1040 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1041 methodinfo* m = class_resolveclassmethod(c,
1043 utf_java_lang_Thread__V,
1044 class_java_lang_ThreadGroup,
1046 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1047 methodinfo* m = class_resolveclassmethod(c,
1049 utf_java_lang_Thread__V,
1050 class_java_lang_ThreadGroup,
1053 # error unknown classpath configuration
1059 (void) vm_call_method(m, group, object);
1061 if (exceptions_get_exception())
1064 // Clear the ThreadGroup in the Java thread object (Mauve
1065 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1066 jlt.set_group(NULL);
1070 /* Thread has terminated. */
1072 thread_set_state_terminated(t);
1074 /* Notify all threads waiting on this thread. These are joining
1077 /* XXX Care about exceptions? */
1078 (void) lock_monitor_enter(jlt.get_handle());
1080 lock_notify_all_object(jlt.get_handle());
1082 /* XXX Care about exceptions? */
1083 (void) lock_monitor_exit(jlt.get_handle());
1085 /* Enter the join-mutex before calling thread_free, so
1086 threads_join_all_threads gets the correct number of non-daemon
1089 threads_mutex_join_lock();
1091 /* Free the internal thread data-structure. */
1095 /* Signal that this thread has finished and leave the mutex. */
1097 cond_join->signal();
1098 threads_mutex_join_unlock();
1105 * Internal helper function which suspends the current thread. This is
1106 * the core method of the suspension mechanism actually blocking the
1107 * execution until the suspension reason is cleared again. Note that
1108 * the current thread needs to hold the suspension mutex while calling
1111 static void threads_suspend_self()
1113 threadobject* thread = THREADOBJECT;
1115 DEBUGTHREADS("suspending", thread);
1117 // Mark thread as suspended.
1118 assert(!thread->suspended);
1119 assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1120 thread->suspended = true;
1122 // Acknowledge the suspension.
1123 thread->suspendcond->broadcast();
1125 #if defined(ENABLE_GC_CACAO)
1126 // If we are stopping the world, we should send a global ack.
1127 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1128 threads_sem_post(&suspend_ack);
1131 // Release the suspension mutex and wait till we are resumed.
1132 thread->suspendcond->wait(thread->suspendmutex);
1134 #if defined(ENABLE_GC_CACAO)
1135 // XXX This is propably not ok!
1136 // If we are starting the world, we should send a global ack.
1137 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1138 threads_sem_post(&suspend_ack);
1141 // Mark thread as not suspended.
1142 assert(thread->suspended);
1143 assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1144 thread->suspended = false;
1146 DEBUGTHREADS("resuming", thread);
1151 * Suspend the passed thread. Execution of that thread stops until the thread
1152 * is explicitly resumend again.
1154 * @param thread The thread to be suspended.
1155 * @param reason Reason for suspending the given thread.
1156 * @return True of operation was successful, false otherwise.
1158 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1161 assert(reason != SUSPEND_REASON_NONE);
1163 // Guard this with the suspension mutex.
1164 MutexLocker ml(*thread->suspendmutex);
1166 // Check if thread is already suspended.
1167 if (thread->suspended)
1170 // Check if thread is in the process of suspending.
1171 if (thread->suspend_reason != SUSPEND_REASON_NONE)
1174 // Set the reason for suspending the thread.
1175 thread->suspend_reason = reason;
1177 if (thread == THREADOBJECT) {
1178 // We already hold the suspension mutex and can suspend ourselves
1179 // immediately without using signals at all.
1180 threads_suspend_self();
1183 // Send the suspend signal to the other thread.
1184 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1185 os::abort_errno("threads_suspend_thread: pthread_kill failed");
1187 // Wait for the thread to acknowledge the suspension.
1188 // XXX A possible optimization would be to not wait here, but you
1189 // better think this through twice before trying it!
1190 thread->suspendcond->wait(thread->suspendmutex);
1198 * Resumes execution of the passed thread.
1200 * @param thread The thread to be resumed.
1201 * @param reason Reason for suspending the given thread.
1202 * @return True of operation was successful, false otherwise.
1204 bool threads_resume_thread(threadobject *thread, int32_t reason)
1207 assert(thread != THREADOBJECT);
1208 assert(reason != SUSPEND_REASON_NONE);
1210 // Guard this with the suspension mutex.
1211 MutexLocker ml(*thread->suspendmutex);
1213 // Check if thread really is suspended.
1214 if (!thread->suspended)
1217 // Threads can only be resumed for the same reason they were suspended.
1218 if (thread->suspend_reason != reason)
1221 // Clear the reason for suspending the thread.
1222 thread->suspend_reason = SUSPEND_REASON_NONE;
1224 // Tell everyone that the thread should resume.
1225 thread->suspendcond->broadcast();
1232 * Acknowledges the suspension of the current thread.
1234 void threads_suspend_ack()
1236 threadobject* thread = THREADOBJECT;
1238 // Guard this with the suspension mutex.
1239 MutexLocker ml(*thread->suspendmutex);
1241 // Suspend ourselves while holding the suspension mutex.
1242 threads_suspend_self();
1246 /* threads_join_all_threads ****************************************************
1248 Join all non-daemon threads.
1250 *******************************************************************************/
1252 void threads_join_all_threads(void)
1256 /* get current thread */
1260 /* This thread is waiting for all non-daemon threads to exit. */
1262 thread_set_state_waiting(t);
1264 /* enter join mutex */
1266 threads_mutex_join_lock();
1268 /* Wait for condition as long as we have non-daemon threads. We
1269 compare against 1 because the current (main thread) is also a
1270 non-daemon thread. */
1272 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1273 cond_join->wait(mutex_join);
1275 /* leave join mutex */
1277 threads_mutex_join_unlock();
1281 /* threads_timespec_earlier ****************************************************
1283 Return true if timespec tv1 is earlier than timespec tv2.
1286 tv1..........first timespec
1287 tv2..........second timespec
1290 true, if the first timespec is earlier
1292 *******************************************************************************/
1294 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1295 const struct timespec *tv2)
1297 return (tv1->tv_sec < tv2->tv_sec)
1299 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1303 /* threads_current_time_is_earlier_than ****************************************
1305 Check if the current time is earlier than the given timespec.
1308 tv...........the timespec to compare against
1311 true, if the current time is earlier
1313 *******************************************************************************/
1315 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1317 struct timeval tvnow;
1318 struct timespec tsnow;
1320 /* get current time */
1322 if (gettimeofday(&tvnow, NULL) != 0)
1323 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1325 /* convert it to a timespec */
1327 tsnow.tv_sec = tvnow.tv_sec;
1328 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1330 /* compare current time with the given timespec */
1332 return threads_timespec_earlier(&tsnow, tv);
1336 /* threads_wait_with_timeout ***************************************************
1338 Wait until the given point in time on a monitor until either
1339 we are notified, we are interrupted, or the time is up.
1342 t............the current thread
1343 wakeupTime...absolute (latest) wakeup time
1344 If both tv_sec and tv_nsec are zero, this function
1345 waits for an unlimited amount of time.
1347 *******************************************************************************/
1349 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1351 // Acquire the waitmutex.
1352 t->waitmutex->lock();
1354 /* wait on waitcond */
1356 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1358 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1359 && threads_current_time_is_earlier_than(wakeupTime))
1362 thread_set_state_timed_parked(t);
1364 thread_set_state_timed_waiting(t);
1366 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1368 thread_set_state_runnable(t);
1373 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1375 thread_set_state_parked(t);
1377 thread_set_state_waiting(t);
1379 t->waitcond->wait(t->waitmutex);
1381 thread_set_state_runnable(t);
1386 t->park_permit = false;
1388 // Release the waitmutex.
1389 t->waitmutex->unlock();
1393 /* threads_wait_with_timeout_relative ******************************************
1395 Wait for the given maximum amount of time on a monitor until either
1396 we are notified, we are interrupted, or the time is up.
1399 t............the current thread
1400 millis.......milliseconds to wait
1401 nanos........nanoseconds to wait
1403 *******************************************************************************/
1405 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1408 struct timespec wakeupTime;
1410 /* calculate the the (latest) wakeup time */
1412 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1416 threads_wait_with_timeout(thread, &wakeupTime, false);
1420 /* threads_calc_absolute_time **************************************************
1422 Calculate the absolute point in time a given number of ms and ns from now.
1425 millis............milliseconds from now
1426 nanos.............nanoseconds from now
1429 *tm...............receives the timespec of the absolute point in time
1431 *******************************************************************************/
1433 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1435 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1437 if (!millis && !nanos)
1440 gettimeofday(&tv, NULL);
1441 s8 secs = tv.tv_sec + millis / 1000;
1442 if (secs > INT32_MAX) // integer overflow
1446 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1447 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1448 if (tm->tv_sec < tv.tv_sec) // integer overflow
1450 tm->tv_nsec = nsec % 1000000000;
1458 /* threads_thread_interrupt ****************************************************
1460 Interrupt the given thread.
1462 The thread gets the "waitcond" signal and
1463 its interrupted flag is set to true.
1466 thread............the thread to interrupt
1468 *******************************************************************************/
1470 void threads_thread_interrupt(threadobject *t)
1472 /* Signal the thread a "waitcond" and tell it that it has been
1475 t->waitmutex->lock();
1477 DEBUGTHREADS("interrupted", t);
1479 /* Interrupt blocking system call using a signal. */
1481 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1483 t->waitcond->signal();
1485 t->interrupted = true;
1487 t->waitmutex->unlock();
1492 * Sleep the current thread for the specified amount of time.
1494 * @param millis Milliseconds to sleep.
1495 * @param nanos Nanoseconds to sleep.
1497 void threads_sleep(int64_t millis, int32_t nanos)
1500 struct timespec wakeupTime;
1504 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1505 exceptions_throw_illegalargumentexception();
1509 t = thread_get_current();
1511 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1512 /* Clear interrupted flag (Mauve test:
1513 gnu/testlet/java/lang/Thread/interrupt). */
1515 thread_set_interrupted(t, false);
1517 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1518 exceptions_throw_interruptedexception();
1522 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1523 // Note: JDK treats a zero length sleep is like Thread.yield(),
1524 // without checking the interrupted status of the thread. It's
1525 // unclear if this is a bug in the implementation or the spec.
1526 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1527 if (millis == 0 && nanos == 0) {
1531 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1533 threads_wait_with_timeout(t, &wakeupTime, false);
1535 interrupted = thread_is_interrupted(t);
1538 thread_set_interrupted(t, false);
1540 // An other exception could have been thrown
1541 // (e.g. ThreadDeathException).
1542 if (!exceptions_get_exception())
1543 exceptions_throw_interruptedexception();
1549 * Park the current thread for the specified amount of time or until a
1550 * specified deadline.
1552 * @param absolute Is the time in nanos a deadline or a duration?
1553 * @param nanos Nanoseconds to park (absolute=false)
1554 * or deadline in milliseconds (absolute=true)
1556 void threads_park(bool absolute, int64_t nanos)
1559 struct timespec wakeupTime;
1561 t = thread_get_current();
1564 wakeupTime.tv_nsec = 0;
1565 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1568 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1570 threads_wait_with_timeout(t, &wakeupTime, true);
1574 * Unpark the specified thread.
1576 * @param t The thread to unpark.
1578 void threads_unpark(threadobject *t)
1580 t->waitmutex->lock();
1582 t->waitcond->signal();
1584 t->park_permit = true;
1586 t->waitmutex->unlock();
1590 /* threads_yield ***************************************************************
1592 Yield to the scheduler.
1594 *******************************************************************************/
1596 void threads_yield(void)
1601 #if defined(ENABLE_TLH)
1603 void threads_tlh_add_frame() {
1604 tlh_add_frame(&(THREADOBJECT->tlh));
1607 void threads_tlh_remove_frame() {
1608 tlh_remove_frame(&(THREADOBJECT->tlh));
1615 * These are local overrides for various environment variables in Emacs.
1616 * Please do not remove this and leave it at the end of the file, where
1617 * Emacs will automagically detect them.
1618 * ---------------------------------------------------------------------
1621 * indent-tabs-mode: t
1625 * vim:noexpandtab:sw=4:ts=4: