1 /* src/threads/posix/thread-posix.cpp - POSIX thread functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2010
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__)
92 # include <semaphore.h>
95 #if defined(__LINUX__)
96 # define GC_LINUX_THREADS
97 #elif defined(__IRIX__)
98 # define GC_IRIX_THREADS
99 #elif defined(__DARWIN__)
100 # define GC_DARWIN_THREADS
101 #elif defined(__SOLARIS__)
102 # define GC_SOLARIS_THREADS
105 #if defined(ENABLE_GC_BOEHM)
106 /* We need to include Boehm's gc.h here because it overrides
107 pthread_create and friends. */
108 # include "mm/boehm-gc/include/gc.h"
112 #if defined(__DARWIN__)
113 /* Darwin has no working semaphore implementation. This one is taken
117 This is a very simple semaphore implementation for Darwin. It
118 is implemented in terms of pthreads calls so it isn't async signal
119 safe. This isn't a problem because signals aren't used to
120 suspend threads on Darwin.
123 static int sem_init(sem_t *sem, int pshared, int value)
128 sem->mutex = new Mutex();
129 sem->cond = new Condition();
135 static int sem_post(sem_t *sem)
140 sem->mutex->unlock();
145 static int sem_wait(sem_t *sem)
149 while (sem->value == 0) {
150 sem->cond->wait(sem->mutex);
154 sem->mutex->unlock();
159 static int sem_destroy(sem_t *sem)
166 #endif /* defined(__DARWIN__) */
169 /* startupinfo *****************************************************************
171 Struct used to pass info from threads_start_thread to
172 threads_startup_thread.
174 ******************************************************************************/
177 threadobject *thread; /* threadobject for this thread */
178 functionptr function; /* function to run in the new thread */
179 sem_t *psem; /* signals when thread has been entered */
180 /* in the thread list */
181 sem_t *psem_first; /* signals when pthread_create has returned */
185 /* prototypes *****************************************************************/
187 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
190 /******************************************************************************/
191 /* GLOBAL VARIABLES */
192 /******************************************************************************/
194 /* the thread object of the current thread */
195 /* This is either a thread-local variable defined with __thread, or */
196 /* a thread-specific value stored with key threads_current_threadobject_key. */
197 #if defined(HAVE___THREAD)
198 __thread threadobject *thread_current;
200 pthread_key_t thread_current_key;
203 /* global mutex for stop-the-world */
204 static Mutex* stopworldlock;
206 #if defined(ENABLE_GC_CACAO)
207 /* global mutex for the GC */
208 static Mutex* mutex_gc;
211 /* global mutex and condition for joining threads on exit */
212 static Mutex* mutex_join;
213 static Condition* cond_join;
215 #if defined(ENABLE_GC_CACAO)
216 /* semaphore used for acknowleding thread suspension */
217 static sem_t suspend_ack;
221 /* threads_sem_init ************************************************************
223 Initialize a semaphore. Checks against errors and interruptions.
226 sem..............the semaphore to initialize
227 shared...........true if this semaphore will be shared between processes
228 value............the initial value for the semaphore
230 *******************************************************************************/
232 void threads_sem_init(sem_t *sem, bool shared, int value)
239 r = sem_init(sem, shared, value);
242 } while (errno == EINTR);
244 vm_abort("sem_init failed: %s", strerror(errno));
248 /* threads_sem_wait ************************************************************
250 Wait for a semaphore, non-interruptible.
252 IMPORTANT: Always use this function instead of `sem_wait` directly, as
253 `sem_wait` may be interrupted by signals!
256 sem..............the semaphore to wait on
258 *******************************************************************************/
260 void threads_sem_wait(sem_t *sem)
270 } while (errno == EINTR);
272 vm_abort("sem_wait failed: %s", strerror(errno));
276 /* threads_sem_post ************************************************************
278 Increase the count of a semaphore. Checks for errors.
281 sem..............the semaphore to increase the count of
283 *******************************************************************************/
285 void threads_sem_post(sem_t *sem)
291 /* unlike sem_wait, sem_post is not interruptible */
297 vm_abort("sem_post failed: %s", strerror(errno));
301 /* threads_stopworld ***********************************************************
303 Stops the world from turning. All threads except the calling one
304 are suspended. The function returns as soon as all threads have
305 acknowledged their suspension.
307 *******************************************************************************/
309 #if defined(ENABLE_GC_CACAO)
310 void threads_stopworld(void)
312 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
319 stopworldlock->lock();
321 /* lock the threads lists */
325 #if defined(__DARWIN__)
326 /*threads_cast_darwinstop();*/
328 #elif defined(__CYGWIN__)
334 DEBUGTHREADS("stops World", self);
338 /* suspend all running threads */
339 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
340 /* don't send the signal to ourself */
345 /* don't send the signal to NEW threads (because they are not
346 completely initialized) */
348 if (t->state == THREAD_STATE_NEW)
351 /* send the signal */
353 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
356 /* increase threads count */
361 /* wait for all threads signaled to suspend */
362 for (i = 0; i < count; i++)
363 threads_sem_wait(&suspend_ack);
366 /* ATTENTION: Don't unlock the threads-lists here so that
367 non-signaled NEW threads can't change their state and execute
373 /* threads_startworld **********************************************************
375 Starts the world again after it has previously been stopped.
377 *******************************************************************************/
379 #if defined(ENABLE_GC_CACAO)
380 void threads_startworld(void)
382 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
389 #if defined(__DARWIN__)
390 /*threads_cast_darwinresume();*/
392 #elif defined(__IRIX__)
393 threads_cast_irixresume();
394 #elif defined(__CYGWIN__)
400 DEBUGTHREADS("starts World", self);
404 /* resume all thread we haltet */
405 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
406 /* don't send the signal to ourself */
411 /* don't send the signal to NEW threads (because they are not
412 completely initialized) */
414 if (t->state == THREAD_STATE_NEW)
417 /* send the signal */
419 result = threads_resume_thread(t);
422 /* increase threads count */
427 /* wait for all threads signaled to suspend */
428 for (i = 0; i < count; i++)
429 threads_sem_wait(&suspend_ack);
433 /* unlock the threads lists */
437 stopworldlock->unlock();
442 /* threads_impl_thread_clear ***************************************************
444 Clears all fields in threadobject the way an MZERO would have
445 done. MZERO cannot be used anymore because it would mess up the
449 t....the threadobject
451 *******************************************************************************/
453 void threads_impl_thread_clear(threadobject *t)
465 #if defined(__DARWIN__)
469 t->interrupted = false;
472 t->suspended = false;
473 t->suspend_reason = 0;
477 t->_exceptionptr = NULL;
478 t->_stackframeinfo = NULL;
479 t->_localref_table = NULL;
481 #if defined(ENABLE_INTRP)
482 t->_global_sp = NULL;
485 #if defined(ENABLE_GC_CACAO)
486 t->gc_critical = false;
492 // Simply reuse the existing dump memory.
495 /* threads_impl_thread_reuse ***************************************************
497 Resets some implementation fields in threadobject. This was
498 previously done in threads_impl_thread_new.
501 t....the threadobject
503 *******************************************************************************/
505 void threads_impl_thread_reuse(threadobject *t)
507 /* get the pthread id */
509 t->tid = pthread_self();
511 #if defined(ENABLE_DEBUG_FILTER)
512 /* Initialize filter counters */
513 t->filterverbosecallctr[0] = 0;
514 t->filterverbosecallctr[1] = 0;
518 t->tracejavacallindent = 0;
519 t->tracejavacallcount = 0;
526 /* not really needed */
527 t->flc_object = NULL;
529 #if defined(ENABLE_TLH)
530 tlh_destroy(&(t->tlh));
536 /* threads_impl_preinit ********************************************************
538 Do some early initialization of stuff required.
540 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
541 is called AFTER this function!
543 *******************************************************************************/
545 void threads_impl_preinit(void)
547 stopworldlock = new Mutex();
549 /* initialize exit mutex and condition (on exit we join all
552 mutex_join = new Mutex();
553 cond_join = new Condition();
555 #if defined(ENABLE_GC_CACAO)
556 /* initialize the GC mutex & suspend semaphore */
558 mutex_gc = new Mutex();
559 threads_sem_init(&suspend_ack, 0, 0);
562 #if !defined(HAVE___THREAD)
563 int result = pthread_key_create(&thread_current_key, NULL);
565 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
570 /* threads_mutex_gc_lock *******************************************************
572 Enter the global GC mutex.
574 *******************************************************************************/
576 #if defined(ENABLE_GC_CACAO)
577 void threads_mutex_gc_lock(void)
584 /* threads_mutex_gc_unlock *****************************************************
586 Leave the global GC mutex.
588 *******************************************************************************/
590 #if defined(ENABLE_GC_CACAO)
591 void threads_mutex_gc_unlock(void)
597 /* threads_mutex_join_lock *****************************************************
599 Enter the join mutex.
601 *******************************************************************************/
603 void threads_mutex_join_lock(void)
609 /* threads_mutex_join_unlock ***************************************************
611 Leave the join mutex.
613 *******************************************************************************/
615 void threads_mutex_join_unlock(void)
617 mutex_join->unlock();
621 /* threads_impl_init ***********************************************************
623 Initializes the implementation specific bits.
625 *******************************************************************************/
627 void threads_impl_init(void)
632 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
634 /* Initialize the thread attribute object. */
636 result = pthread_attr_init(&attr);
639 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
641 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
644 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
648 /* threads_startup_thread ******************************************************
650 Thread startup function called by pthread_create.
652 Thread which have a startup.function != NULL are marked as internal
653 threads. All other threads are threated as normal Java threads.
655 NOTE: This function is not called directly by pthread_create. The Boehm GC
656 inserts its own GC_start_routine in between, which then calls
660 arg..........the argument passed to pthread_create, ie. a pointer to
661 a startupinfo struct. CAUTION: When the `psem` semaphore
662 is posted, the startupinfo struct becomes invalid! (It
663 is allocated on the stack of threads_start_thread.)
665 ******************************************************************************/
667 static void *threads_startup_thread(void *arg)
669 startupinfo *startup;
674 functionptr function;
676 #if defined(ENABLE_GC_BOEHM)
677 # if !defined(__DARWIN__)
678 struct GC_stack_base sb;
683 #if defined(ENABLE_INTRP)
684 u1 *intrp_thread_stack;
687 #if defined(ENABLE_INTRP)
688 /* create interpreter stack */
691 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
692 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
695 intrp_thread_stack = NULL;
698 /* get passed startupinfo structure and the values in there */
700 startup = (startupinfo*) arg;
703 function = startup->function;
704 psem = startup->psem;
706 /* Seems like we've encountered a situation where thread->tid was
707 not set by pthread_create. We alleviate this problem by waiting
708 for pthread_create to return. */
710 threads_sem_wait(startup->psem_first);
712 #if defined(__DARWIN__)
713 t->mach_thread = mach_thread_self();
716 /* Now that we are in the new thread, we can store the internal
717 thread data-structure in the TSD. */
719 thread_set_current(t);
721 #if defined(ENABLE_GC_BOEHM)
722 # if defined(__DARWIN__)
723 // This is currently not implemented in Boehm-GC. Just fail silently.
725 /* Register the thread with Boehm-GC. This must happen before the
726 thread allocates any memory from the GC heap.*/
728 result = GC_get_stack_base(&sb);
731 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
733 GC_register_my_thread(&sb);
737 // Get the java.lang.Thread object for this thread.
738 java_handle_t* object = thread_get_object(t);
739 java_lang_Thread jlt(object);
741 /* set our priority */
743 threads_set_thread_priority(t->tid, jlt.get_priority());
745 /* Thread is completely initialized. */
747 thread_set_state_runnable(t);
749 /* tell threads_startup_thread that we registered ourselves */
750 /* CAUTION: *startup becomes invalid with this! */
753 threads_sem_post(psem);
755 #if defined(ENABLE_INTRP)
756 /* set interpreter stack */
759 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
762 // Hook point just before the threads initial method is executed.
763 Hook::thread_start(t);
765 DEBUGTHREADS("starting", t);
767 /* find and run the Thread.run()V method if no other function was passed */
769 if (function == NULL) {
770 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
771 /* We need to start the run method of
772 java.lang.VMThread. Since this is a final class, we can use
773 the class object directly. */
775 c = class_java_lang_VMThread;
776 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
777 LLNI_class_get(object, c);
779 # error unknown classpath configuration
782 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
785 vm_abort("threads_startup_thread: run() method not found in class");
787 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
789 // We need to start the run method of java.lang.VMThread.
790 java_lang_VMThread jlvmt(jlt.get_vmThread());
791 java_handle_t* h = jlvmt.get_handle();
793 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
795 java_handle_t* h = jlt.get_handle();
798 # error unknown classpath configuration
801 /* Run the thread. */
803 (void) vm_call_method(m, h);
806 /* call passed function, e.g. finalizer_thread */
811 DEBUGTHREADS("stopping", t);
813 // Hook point just after the threads initial method returned.
816 /* We ignore the return value. */
818 (void) thread_detach_current_thread();
824 /* threads_impl_thread_start ***************************************************
826 Start a thread in the JVM. Both (vm internal and java) thread
830 thread....the thread object
831 f.........function to run in the new thread. NULL means that the
832 "run" method of the object `t` should be called
834 ******************************************************************************/
836 void threads_impl_thread_start(threadobject *thread, functionptr f)
844 /* fill startupinfo structure passed by pthread_create to
845 * threads_startup_thread */
847 startup.thread = thread;
848 startup.function = f; /* maybe we don't call Thread.run()V */
850 startup.psem_first = &sem_first;
852 threads_sem_init(&sem, 0, 0);
853 threads_sem_init(&sem_first, 0, 0);
855 /* Initialize thread attributes. */
857 result = pthread_attr_init(&attr);
860 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
862 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
865 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
867 /* initialize thread stacksize */
869 result = pthread_attr_setstacksize(&attr, opt_stacksize);
872 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
874 /* create the thread */
876 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
879 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
881 /* destroy the thread attributes */
883 result = pthread_attr_destroy(&attr);
886 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
888 /* signal that pthread_create has returned, so thread->tid is valid */
890 threads_sem_post(&sem_first);
892 /* wait here until the thread has entered itself into the thread list */
894 threads_sem_wait(&sem);
899 sem_destroy(&sem_first);
903 /* threads_set_thread_priority *************************************************
905 Set the priority of the given thread.
908 tid..........thread id
909 priority.....priority to set
911 ******************************************************************************/
913 void threads_set_thread_priority(pthread_t tid, int priority)
915 struct sched_param schedp;
918 pthread_getschedparam(tid, &policy, &schedp);
919 schedp.sched_priority = priority;
920 pthread_setschedparam(tid, policy, &schedp);
925 * Detaches the current thread from the VM.
927 * @return true on success, false otherwise
929 bool thread_detach_current_thread(void)
931 threadobject* t = thread_get_current();
937 /* If the given thread has already been detached, this operation
940 if (thread_is_attached(t) == false)
943 DEBUGTHREADS("detaching", t);
945 java_handle_t* object = thread_get_object(t);
946 java_lang_Thread jlt(object);
948 #if defined(ENABLE_JAVASE)
949 java_handle_t* group = jlt.get_group();
951 /* If there's an uncaught exception, call uncaughtException on the
952 thread's exception handler, or the thread's group if this is
955 java_handle_t* e = exceptions_get_and_clear_exception();
958 /* We use the type void* for handler here, as it's not trivial
959 to build the java_lang_Thread_UncaughtExceptionHandler
960 header file with cacaoh. */
962 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
964 java_handle_t* handler = jlt.get_exceptionHandler();
966 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
968 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
975 if (handler != NULL) {
976 LLNI_class_get(handler, c);
977 h = (java_handle_t *) handler;
980 LLNI_class_get(group, c);
981 h = (java_handle_t *) group;
984 methodinfo* m = class_resolveclassmethod(c,
985 utf_uncaughtException,
986 utf_java_lang_Thread_java_lang_Throwable__V,
993 (void) vm_call_method(m, h, object, e);
995 if (exceptions_get_exception())
999 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1001 /* Remove thread from the thread group. */
1003 if (group != NULL) {
1005 LLNI_class_get(group, c);
1007 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1008 methodinfo* m = class_resolveclassmethod(c,
1010 utf_java_lang_Thread__V,
1011 class_java_lang_ThreadGroup,
1013 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1014 methodinfo* m = class_resolveclassmethod(c,
1016 utf_java_lang_Thread__V,
1017 class_java_lang_ThreadGroup,
1020 # error unknown classpath configuration
1026 (void) vm_call_method(m, group, object);
1028 if (exceptions_get_exception())
1031 // Clear the ThreadGroup in the Java thread object (Mauve
1032 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1033 jlt.set_group(NULL);
1037 /* Thread has terminated. */
1039 thread_set_state_terminated(t);
1041 /* Notify all threads waiting on this thread. These are joining
1044 /* XXX Care about exceptions? */
1045 (void) lock_monitor_enter(jlt.get_handle());
1047 lock_notify_all_object(jlt.get_handle());
1049 /* XXX Care about exceptions? */
1050 (void) lock_monitor_exit(jlt.get_handle());
1052 /* Enter the join-mutex before calling thread_free, so
1053 threads_join_all_threads gets the correct number of non-daemon
1056 threads_mutex_join_lock();
1058 /* Free the internal thread data-structure. */
1062 /* Signal that this thread has finished and leave the mutex. */
1064 cond_join->signal();
1065 threads_mutex_join_unlock();
1072 * Internal helper function which suspends the current thread. This is
1073 * the core method of the suspension mechanism actually blocking the
1074 * execution until the suspension reason is cleared again. Note that
1075 * the current thread needs to hold the suspension mutex while calling
1078 static void threads_suspend_self()
1080 threadobject* thread = THREADOBJECT;
1082 DEBUGTHREADS("suspending", thread);
1084 // Mark thread as suspended.
1085 assert(!thread->suspended);
1086 assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1087 thread->suspended = true;
1089 // Acknowledge the suspension.
1090 thread->suspendcond->broadcast();
1092 #if defined(ENABLE_GC_CACAO)
1093 // If we are stopping the world, we should send a global ack.
1094 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1095 threads_sem_post(&suspend_ack);
1098 // Release the suspension mutex and wait till we are resumed.
1099 thread->suspendcond->wait(thread->suspendmutex);
1101 #if defined(ENABLE_GC_CACAO)
1102 // XXX This is propably not ok!
1103 // If we are starting the world, we should send a global ack.
1104 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1105 threads_sem_post(&suspend_ack);
1108 // Mark thread as not suspended.
1109 assert(thread->suspended);
1110 assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1111 thread->suspended = false;
1113 DEBUGTHREADS("resuming", thread);
1118 * Suspend the passed thread. Execution of that thread stops until the thread
1119 * is explicitly resumend again.
1121 * @param thread The thread to be suspended.
1122 * @param reason Reason for suspending the given thread.
1123 * @return True of operation was successful, false otherwise.
1125 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1128 assert(reason != SUSPEND_REASON_NONE);
1130 // Guard this with the suspension mutex.
1131 MutexLocker ml(*thread->suspendmutex);
1133 // Check if thread is already suspended.
1134 if (thread->suspended)
1137 // Check if thread is in the process of suspending.
1138 if (thread->suspend_reason != SUSPEND_REASON_NONE)
1141 // Set the reason for suspending the thread.
1142 thread->suspend_reason = reason;
1144 if (thread == THREADOBJECT) {
1145 // We already hold the suspension mutex and can suspend ourselves
1146 // immediately without using signals at all.
1147 threads_suspend_self();
1150 // Send the suspend signal to the other thread.
1151 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1152 os::abort_errno("threads_suspend_thread: pthread_kill failed");
1154 // Wait for the thread to acknowledge the suspension.
1155 // XXX A possible optimization would be to not wait here, but you
1156 // better think this through twice before trying it!
1157 thread->suspendcond->wait(thread->suspendmutex);
1165 * Resumes execution of the passed thread.
1167 * @param thread The thread to be resumed.
1168 * @param reason Reason for suspending the given thread.
1169 * @return True of operation was successful, false otherwise.
1171 bool threads_resume_thread(threadobject *thread, int32_t reason)
1174 assert(thread != THREADOBJECT);
1175 assert(reason != SUSPEND_REASON_NONE);
1177 // Guard this with the suspension mutex.
1178 MutexLocker ml(*thread->suspendmutex);
1180 // Check if thread really is suspended.
1181 if (!thread->suspended)
1184 // Threads can only be resumed for the same reason they were suspended.
1185 if (thread->suspend_reason != reason)
1188 // Clear the reason for suspending the thread.
1189 thread->suspend_reason = SUSPEND_REASON_NONE;
1191 // Tell everyone that the thread should resume.
1192 thread->suspendcond->broadcast();
1199 * Acknowledges the suspension of the current thread.
1201 void threads_suspend_ack()
1203 threadobject* thread = THREADOBJECT;
1205 // Guard this with the suspension mutex.
1206 MutexLocker ml(*thread->suspendmutex);
1208 // Suspend ourselves while holding the suspension mutex.
1209 threads_suspend_self();
1213 /* threads_join_all_threads ****************************************************
1215 Join all non-daemon threads.
1217 *******************************************************************************/
1219 void threads_join_all_threads(void)
1223 /* get current thread */
1227 /* This thread is waiting for all non-daemon threads to exit. */
1229 thread_set_state_waiting(t);
1231 /* enter join mutex */
1233 threads_mutex_join_lock();
1235 /* Wait for condition as long as we have non-daemon threads. We
1236 compare against 1 because the current (main thread) is also a
1237 non-daemon thread. */
1239 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1240 cond_join->wait(mutex_join);
1242 /* leave join mutex */
1244 threads_mutex_join_unlock();
1248 /* threads_timespec_earlier ****************************************************
1250 Return true if timespec tv1 is earlier than timespec tv2.
1253 tv1..........first timespec
1254 tv2..........second timespec
1257 true, if the first timespec is earlier
1259 *******************************************************************************/
1261 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1262 const struct timespec *tv2)
1264 return (tv1->tv_sec < tv2->tv_sec)
1266 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1270 /* threads_current_time_is_earlier_than ****************************************
1272 Check if the current time is earlier than the given timespec.
1275 tv...........the timespec to compare against
1278 true, if the current time is earlier
1280 *******************************************************************************/
1282 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1284 struct timeval tvnow;
1285 struct timespec tsnow;
1287 /* get current time */
1289 if (gettimeofday(&tvnow, NULL) != 0)
1290 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1292 /* convert it to a timespec */
1294 tsnow.tv_sec = tvnow.tv_sec;
1295 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1297 /* compare current time with the given timespec */
1299 return threads_timespec_earlier(&tsnow, tv);
1303 /* threads_wait_with_timeout ***************************************************
1305 Wait until the given point in time on a monitor until either
1306 we are notified, we are interrupted, or the time is up.
1309 t............the current thread
1310 wakeupTime...absolute (latest) wakeup time
1311 If both tv_sec and tv_nsec are zero, this function
1312 waits for an unlimited amount of time.
1314 *******************************************************************************/
1316 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1318 // Acquire the waitmutex.
1319 t->waitmutex->lock();
1321 /* wait on waitcond */
1323 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1325 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1326 && threads_current_time_is_earlier_than(wakeupTime))
1329 thread_set_state_timed_parked(t);
1331 thread_set_state_timed_waiting(t);
1333 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1335 thread_set_state_runnable(t);
1340 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1342 thread_set_state_parked(t);
1344 thread_set_state_waiting(t);
1346 t->waitcond->wait(t->waitmutex);
1348 thread_set_state_runnable(t);
1353 t->park_permit = false;
1355 // Release the waitmutex.
1356 t->waitmutex->unlock();
1360 /* threads_wait_with_timeout_relative ******************************************
1362 Wait for the given maximum amount of time on a monitor until either
1363 we are notified, we are interrupted, or the time is up.
1366 t............the current thread
1367 millis.......milliseconds to wait
1368 nanos........nanoseconds to wait
1370 *******************************************************************************/
1372 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1375 struct timespec wakeupTime;
1377 /* calculate the the (latest) wakeup time */
1379 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1383 threads_wait_with_timeout(thread, &wakeupTime, false);
1387 /* threads_calc_absolute_time **************************************************
1389 Calculate the absolute point in time a given number of ms and ns from now.
1392 millis............milliseconds from now
1393 nanos.............nanoseconds from now
1396 *tm...............receives the timespec of the absolute point in time
1398 *******************************************************************************/
1400 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1402 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1404 if (!millis && !nanos)
1407 gettimeofday(&tv, NULL);
1408 s8 secs = tv.tv_sec + millis / 1000;
1409 if (secs > INT32_MAX) // integer overflow
1413 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1414 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1415 if (tm->tv_sec < tv.tv_sec) // integer overflow
1417 tm->tv_nsec = nsec % 1000000000;
1425 /* threads_thread_interrupt ****************************************************
1427 Interrupt the given thread.
1429 The thread gets the "waitcond" signal and
1430 its interrupted flag is set to true.
1433 thread............the thread to interrupt
1435 *******************************************************************************/
1437 void threads_thread_interrupt(threadobject *t)
1439 /* Signal the thread a "waitcond" and tell it that it has been
1442 t->waitmutex->lock();
1444 DEBUGTHREADS("interrupted", t);
1446 /* Interrupt blocking system call using a signal. */
1448 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1450 t->waitcond->signal();
1452 t->interrupted = true;
1454 t->waitmutex->unlock();
1459 * Sleep the current thread for the specified amount of time.
1461 * @param millis Milliseconds to sleep.
1462 * @param nanos Nanoseconds to sleep.
1464 void threads_sleep(int64_t millis, int32_t nanos)
1467 struct timespec wakeupTime;
1471 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1472 exceptions_throw_illegalargumentexception();
1476 t = thread_get_current();
1478 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1479 /* Clear interrupted flag (Mauve test:
1480 gnu/testlet/java/lang/Thread/interrupt). */
1482 thread_set_interrupted(t, false);
1484 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1485 exceptions_throw_interruptedexception();
1489 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1490 // Note: JDK treats a zero length sleep is like Thread.yield(),
1491 // without checking the interrupted status of the thread. It's
1492 // unclear if this is a bug in the implementation or the spec.
1493 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1494 if (millis == 0 && nanos == 0) {
1498 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1500 threads_wait_with_timeout(t, &wakeupTime, false);
1502 interrupted = thread_is_interrupted(t);
1505 thread_set_interrupted(t, false);
1507 // An other exception could have been thrown
1508 // (e.g. ThreadDeathException).
1509 if (!exceptions_get_exception())
1510 exceptions_throw_interruptedexception();
1516 * Park the current thread for the specified amount of time or until a
1517 * specified deadline.
1519 * @param absolute Is the time in nanos a deadline or a duration?
1520 * @param nanos Nanoseconds to park (absolute=false)
1521 * or deadline in milliseconds (absolute=true)
1523 void threads_park(bool absolute, int64_t nanos)
1526 struct timespec wakeupTime;
1528 t = thread_get_current();
1531 wakeupTime.tv_nsec = 0;
1532 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1535 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1537 threads_wait_with_timeout(t, &wakeupTime, true);
1541 * Unpark the specified thread.
1543 * @param t The thread to unpark.
1545 void threads_unpark(threadobject *t)
1547 t->waitmutex->lock();
1549 t->waitcond->signal();
1551 t->park_permit = true;
1553 t->waitmutex->unlock();
1557 /* threads_yield ***************************************************************
1559 Yield to the scheduler.
1561 *******************************************************************************/
1563 void threads_yield(void)
1568 #if defined(ENABLE_TLH)
1570 void threads_tlh_add_frame() {
1571 tlh_add_frame(&(THREADOBJECT->tlh));
1574 void threads_tlh_remove_frame() {
1575 tlh_remove_frame(&(THREADOBJECT->tlh));
1582 * These are local overrides for various environment variables in Emacs.
1583 * Please do not remove this and leave it at the end of the file, where
1584 * Emacs will automagically detect them.
1585 * ---------------------------------------------------------------------
1588 * indent-tabs-mode: t
1592 * vim:noexpandtab:sw=4:ts=4: