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
103 #if defined(ENABLE_GC_BOEHM)
104 /* We need to include Boehm's gc.h here because it overrides
105 pthread_create and friends. */
106 # include "mm/boehm-gc/include/gc.h"
110 #if defined(__DARWIN__)
111 /* Darwin has no working semaphore implementation. This one is taken
115 This is a very simple semaphore implementation for Darwin. It
116 is implemented in terms of pthreads calls so it isn't async signal
117 safe. This isn't a problem because signals aren't used to
118 suspend threads on Darwin.
121 static int sem_init(sem_t *sem, int pshared, int value)
126 sem->mutex = new Mutex();
127 sem->cond = new Condition();
133 static int sem_post(sem_t *sem)
138 sem->mutex->unlock();
143 static int sem_wait(sem_t *sem)
147 while (sem->value == 0) {
148 sem->cond->wait(sem->mutex);
152 sem->mutex->unlock();
157 static int sem_destroy(sem_t *sem)
164 #endif /* defined(__DARWIN__) */
167 /* startupinfo *****************************************************************
169 Struct used to pass info from threads_start_thread to
170 threads_startup_thread.
172 ******************************************************************************/
175 threadobject *thread; /* threadobject for this thread */
176 functionptr function; /* function to run in the new thread */
177 sem_t *psem; /* signals when thread has been entered */
178 /* in the thread list */
179 sem_t *psem_first; /* signals when pthread_create has returned */
183 /* prototypes *****************************************************************/
185 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
188 /******************************************************************************/
189 /* GLOBAL VARIABLES */
190 /******************************************************************************/
192 /* the thread object of the current thread */
193 /* This is either a thread-local variable defined with __thread, or */
194 /* a thread-specific value stored with key threads_current_threadobject_key. */
195 #if defined(HAVE___THREAD)
196 __thread threadobject *thread_current;
198 pthread_key_t thread_current_key;
201 /* global mutex for stop-the-world */
202 static Mutex* stopworldlock;
204 #if defined(ENABLE_GC_CACAO)
205 /* global mutex for the GC */
206 static Mutex* mutex_gc;
209 /* global mutex and condition for joining threads on exit */
210 static Mutex* mutex_join;
211 static Condition* cond_join;
213 #if defined(ENABLE_GC_CACAO)
214 /* semaphore used for acknowleding thread suspension */
215 static sem_t suspend_ack;
219 /* threads_sem_init ************************************************************
221 Initialize a semaphore. Checks against errors and interruptions.
224 sem..............the semaphore to initialize
225 shared...........true if this semaphore will be shared between processes
226 value............the initial value for the semaphore
228 *******************************************************************************/
230 void threads_sem_init(sem_t *sem, bool shared, int value)
237 r = sem_init(sem, shared, value);
240 } while (errno == EINTR);
242 vm_abort("sem_init failed: %s", strerror(errno));
246 /* threads_sem_wait ************************************************************
248 Wait for a semaphore, non-interruptible.
250 IMPORTANT: Always use this function instead of `sem_wait` directly, as
251 `sem_wait` may be interrupted by signals!
254 sem..............the semaphore to wait on
256 *******************************************************************************/
258 void threads_sem_wait(sem_t *sem)
268 } while (errno == EINTR);
270 vm_abort("sem_wait failed: %s", strerror(errno));
274 /* threads_sem_post ************************************************************
276 Increase the count of a semaphore. Checks for errors.
279 sem..............the semaphore to increase the count of
281 *******************************************************************************/
283 void threads_sem_post(sem_t *sem)
289 /* unlike sem_wait, sem_post is not interruptible */
295 vm_abort("sem_post failed: %s", strerror(errno));
299 /* threads_stopworld ***********************************************************
301 Stops the world from turning. All threads except the calling one
302 are suspended. The function returns as soon as all threads have
303 acknowledged their suspension.
305 *******************************************************************************/
307 #if defined(ENABLE_GC_CACAO)
308 void threads_stopworld(void)
310 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
317 stopworldlock->lock();
319 /* lock the threads lists */
323 #if defined(__DARWIN__)
324 /*threads_cast_darwinstop();*/
326 #elif defined(__CYGWIN__)
332 DEBUGTHREADS("stops World", self);
336 /* suspend all running threads */
337 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
338 /* don't send the signal to ourself */
343 /* don't send the signal to NEW threads (because they are not
344 completely initialized) */
346 if (t->state == THREAD_STATE_NEW)
349 /* send the signal */
351 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
354 /* increase threads count */
359 /* wait for all threads signaled to suspend */
360 for (i = 0; i < count; i++)
361 threads_sem_wait(&suspend_ack);
364 /* ATTENTION: Don't unlock the threads-lists here so that
365 non-signaled NEW threads can't change their state and execute
371 /* threads_startworld **********************************************************
373 Starts the world again after it has previously been stopped.
375 *******************************************************************************/
377 #if defined(ENABLE_GC_CACAO)
378 void threads_startworld(void)
380 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
387 #if defined(__DARWIN__)
388 /*threads_cast_darwinresume();*/
390 #elif defined(__IRIX__)
391 threads_cast_irixresume();
392 #elif defined(__CYGWIN__)
398 DEBUGTHREADS("starts World", self);
402 /* resume all thread we haltet */
403 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
404 /* don't send the signal to ourself */
409 /* don't send the signal to NEW threads (because they are not
410 completely initialized) */
412 if (t->state == THREAD_STATE_NEW)
415 /* send the signal */
417 result = threads_resume_thread(t);
420 /* increase threads count */
425 /* wait for all threads signaled to suspend */
426 for (i = 0; i < count; i++)
427 threads_sem_wait(&suspend_ack);
431 /* unlock the threads lists */
435 stopworldlock->unlock();
440 /* threads_impl_thread_clear ***************************************************
442 Clears all fields in threadobject the way an MZERO would have
443 done. MZERO cannot be used anymore because it would mess up the
447 t....the threadobject
449 *******************************************************************************/
451 void threads_impl_thread_clear(threadobject *t)
463 #if defined(__DARWIN__)
467 t->interrupted = false;
470 t->suspended = false;
471 t->suspend_reason = 0;
475 t->_exceptionptr = NULL;
476 t->_stackframeinfo = NULL;
477 t->_localref_table = NULL;
479 #if defined(ENABLE_INTRP)
480 t->_global_sp = NULL;
483 #if defined(ENABLE_GC_CACAO)
484 t->gc_critical = false;
490 // Simply reuse the existing dump memory.
493 /* threads_impl_thread_reuse ***************************************************
495 Resets some implementation fields in threadobject. This was
496 previously done in threads_impl_thread_new.
499 t....the threadobject
501 *******************************************************************************/
503 void threads_impl_thread_reuse(threadobject *t)
505 /* get the pthread id */
507 t->tid = pthread_self();
509 #if defined(ENABLE_DEBUG_FILTER)
510 /* Initialize filter counters */
511 t->filterverbosecallctr[0] = 0;
512 t->filterverbosecallctr[1] = 0;
516 t->tracejavacallindent = 0;
517 t->tracejavacallcount = 0;
524 /* not really needed */
525 t->flc_object = NULL;
527 #if defined(ENABLE_TLH)
528 tlh_destroy(&(t->tlh));
534 /* threads_impl_thread_free ****************************************************
536 Cleanup thread stuff.
539 t....the threadobject
541 *******************************************************************************/
545 void threads_impl_thread_free(threadobject *t)
549 /* Destroy the mutex and the condition. */
553 result = pthread_cond_destroy(&(t->flc_cond));
556 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
560 result = pthread_cond_destroy(&(t->waitcond));
563 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
565 delete t->suspendmutex;
567 result = pthread_cond_destroy(&(t->suspendcond));
570 os::abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
575 /* threads_impl_preinit ********************************************************
577 Do some early initialization of stuff required.
579 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
580 is called AFTER this function!
582 *******************************************************************************/
584 void threads_impl_preinit(void)
586 stopworldlock = new Mutex();
588 /* initialize exit mutex and condition (on exit we join all
591 mutex_join = new Mutex();
592 cond_join = new Condition();
594 #if defined(ENABLE_GC_CACAO)
595 /* initialize the GC mutex & suspend semaphore */
597 mutex_gc = new Mutex();
598 threads_sem_init(&suspend_ack, 0, 0);
601 #if !defined(HAVE___THREAD)
602 int result = pthread_key_create(&thread_current_key, NULL);
604 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
609 /* threads_mutex_gc_lock *******************************************************
611 Enter the global GC mutex.
613 *******************************************************************************/
615 #if defined(ENABLE_GC_CACAO)
616 void threads_mutex_gc_lock(void)
623 /* threads_mutex_gc_unlock *****************************************************
625 Leave the global GC mutex.
627 *******************************************************************************/
629 #if defined(ENABLE_GC_CACAO)
630 void threads_mutex_gc_unlock(void)
636 /* threads_mutex_join_lock *****************************************************
638 Enter the join mutex.
640 *******************************************************************************/
642 void threads_mutex_join_lock(void)
648 /* threads_mutex_join_unlock ***************************************************
650 Leave the join mutex.
652 *******************************************************************************/
654 void threads_mutex_join_unlock(void)
656 mutex_join->unlock();
660 /* threads_impl_init ***********************************************************
662 Initializes the implementation specific bits.
664 *******************************************************************************/
666 void threads_impl_init(void)
671 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
673 /* Initialize the thread attribute object. */
675 result = pthread_attr_init(&attr);
678 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
680 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
683 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
687 /* threads_startup_thread ******************************************************
689 Thread startup function called by pthread_create.
691 Thread which have a startup.function != NULL are marked as internal
692 threads. All other threads are threated as normal Java threads.
694 NOTE: This function is not called directly by pthread_create. The Boehm GC
695 inserts its own GC_start_routine in between, which then calls
699 arg..........the argument passed to pthread_create, ie. a pointer to
700 a startupinfo struct. CAUTION: When the `psem` semaphore
701 is posted, the startupinfo struct becomes invalid! (It
702 is allocated on the stack of threads_start_thread.)
704 ******************************************************************************/
706 static void *threads_startup_thread(void *arg)
708 startupinfo *startup;
713 functionptr function;
715 #if defined(ENABLE_GC_BOEHM)
716 # if !defined(__DARWIN__)
717 struct GC_stack_base sb;
722 #if defined(ENABLE_INTRP)
723 u1 *intrp_thread_stack;
726 #if defined(ENABLE_INTRP)
727 /* create interpreter stack */
730 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
731 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
734 intrp_thread_stack = NULL;
737 /* get passed startupinfo structure and the values in there */
739 startup = (startupinfo*) arg;
742 function = startup->function;
743 psem = startup->psem;
745 /* Seems like we've encountered a situation where thread->tid was
746 not set by pthread_create. We alleviate this problem by waiting
747 for pthread_create to return. */
749 threads_sem_wait(startup->psem_first);
751 #if defined(__DARWIN__)
752 t->mach_thread = mach_thread_self();
755 /* Now that we are in the new thread, we can store the internal
756 thread data-structure in the TSD. */
758 thread_set_current(t);
760 #if defined(ENABLE_GC_BOEHM)
761 # if defined(__DARWIN__)
762 // This is currently not implemented in Boehm-GC. Just fail silently.
764 /* Register the thread with Boehm-GC. This must happen before the
765 thread allocates any memory from the GC heap.*/
767 result = GC_get_stack_base(&sb);
770 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
772 GC_register_my_thread(&sb);
776 // Get the java.lang.Thread object for this thread.
777 java_handle_t* object = thread_get_object(t);
778 java_lang_Thread jlt(object);
780 /* set our priority */
782 threads_set_thread_priority(t->tid, jlt.get_priority());
784 /* Thread is completely initialized. */
786 thread_set_state_runnable(t);
788 /* tell threads_startup_thread that we registered ourselves */
789 /* CAUTION: *startup becomes invalid with this! */
792 threads_sem_post(psem);
794 #if defined(ENABLE_INTRP)
795 /* set interpreter stack */
798 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
801 // Hook point just before the threads initial method is executed.
802 Hook::thread_start(t);
804 DEBUGTHREADS("starting", t);
806 /* find and run the Thread.run()V method if no other function was passed */
808 if (function == NULL) {
809 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
810 /* We need to start the run method of
811 java.lang.VMThread. Since this is a final class, we can use
812 the class object directly. */
814 c = class_java_lang_VMThread;
815 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
816 LLNI_class_get(object, c);
818 # error unknown classpath configuration
821 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
824 vm_abort("threads_startup_thread: run() method not found in class");
826 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
828 // We need to start the run method of java.lang.VMThread.
829 java_lang_VMThread jlvmt(jlt.get_vmThread());
830 java_handle_t* h = jlvmt.get_handle();
832 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
834 java_handle_t* h = jlt.get_handle();
837 # error unknown classpath configuration
840 /* Run the thread. */
842 (void) vm_call_method(m, h);
845 /* call passed function, e.g. finalizer_thread */
850 DEBUGTHREADS("stopping", t);
852 // Hook point just after the threads initial method returned.
855 /* We ignore the return value. */
857 (void) thread_detach_current_thread();
863 /* threads_impl_thread_start ***************************************************
865 Start a thread in the JVM. Both (vm internal and java) thread
869 thread....the thread object
870 f.........function to run in the new thread. NULL means that the
871 "run" method of the object `t` should be called
873 ******************************************************************************/
875 void threads_impl_thread_start(threadobject *thread, functionptr f)
883 /* fill startupinfo structure passed by pthread_create to
884 * threads_startup_thread */
886 startup.thread = thread;
887 startup.function = f; /* maybe we don't call Thread.run()V */
889 startup.psem_first = &sem_first;
891 threads_sem_init(&sem, 0, 0);
892 threads_sem_init(&sem_first, 0, 0);
894 /* Initialize thread attributes. */
896 result = pthread_attr_init(&attr);
899 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
901 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
904 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
906 /* initialize thread stacksize */
908 result = pthread_attr_setstacksize(&attr, opt_stacksize);
911 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
913 /* create the thread */
915 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
918 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
920 /* destroy the thread attributes */
922 result = pthread_attr_destroy(&attr);
925 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
927 /* signal that pthread_create has returned, so thread->tid is valid */
929 threads_sem_post(&sem_first);
931 /* wait here until the thread has entered itself into the thread list */
933 threads_sem_wait(&sem);
938 sem_destroy(&sem_first);
942 /* threads_set_thread_priority *************************************************
944 Set the priority of the given thread.
947 tid..........thread id
948 priority.....priority to set
950 ******************************************************************************/
952 void threads_set_thread_priority(pthread_t tid, int priority)
954 struct sched_param schedp;
957 pthread_getschedparam(tid, &policy, &schedp);
958 schedp.sched_priority = priority;
959 pthread_setschedparam(tid, policy, &schedp);
964 * Detaches the current thread from the VM.
966 * @return true on success, false otherwise
968 bool thread_detach_current_thread(void)
970 threadobject* t = thread_get_current();
976 /* If the given thread has already been detached, this operation
979 if (thread_is_attached(t) == false)
982 DEBUGTHREADS("detaching", t);
984 java_handle_t* object = thread_get_object(t);
985 java_lang_Thread jlt(object);
987 #if defined(ENABLE_JAVASE)
988 java_handle_t* group = jlt.get_group();
990 /* If there's an uncaught exception, call uncaughtException on the
991 thread's exception handler, or the thread's group if this is
994 java_handle_t* e = exceptions_get_and_clear_exception();
997 /* We use the type void* for handler here, as it's not trivial
998 to build the java_lang_Thread_UncaughtExceptionHandler
999 header file with cacaoh. */
1001 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1003 java_handle_t* handler = jlt.get_exceptionHandler();
1005 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1007 java_handle_t* handler = jlt.get_uncaughtExceptionHandler();
1014 if (handler != NULL) {
1015 LLNI_class_get(handler, c);
1016 h = (java_handle_t *) handler;
1019 LLNI_class_get(group, c);
1020 h = (java_handle_t *) group;
1023 methodinfo* m = class_resolveclassmethod(c,
1024 utf_uncaughtException,
1025 utf_java_lang_Thread_java_lang_Throwable__V,
1032 (void) vm_call_method(m, h, object, e);
1034 if (exceptions_get_exception())
1038 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1040 /* Remove thread from the thread group. */
1042 if (group != NULL) {
1044 LLNI_class_get(group, c);
1046 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1047 methodinfo* m = class_resolveclassmethod(c,
1049 utf_java_lang_Thread__V,
1050 class_java_lang_ThreadGroup,
1052 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1053 methodinfo* m = class_resolveclassmethod(c,
1055 utf_java_lang_Thread__V,
1056 class_java_lang_ThreadGroup,
1059 # error unknown classpath configuration
1065 (void) vm_call_method(m, group, object);
1067 if (exceptions_get_exception())
1070 // Clear the ThreadGroup in the Java thread object (Mauve
1071 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
1072 jlt.set_group(NULL);
1076 /* Thread has terminated. */
1078 thread_set_state_terminated(t);
1080 /* Notify all threads waiting on this thread. These are joining
1083 /* XXX Care about exceptions? */
1084 (void) lock_monitor_enter(jlt.get_handle());
1086 lock_notify_all_object(jlt.get_handle());
1088 /* XXX Care about exceptions? */
1089 (void) lock_monitor_exit(jlt.get_handle());
1091 /* Enter the join-mutex before calling thread_free, so
1092 threads_join_all_threads gets the correct number of non-daemon
1095 threads_mutex_join_lock();
1097 /* Free the internal thread data-structure. */
1101 /* Signal that this thread has finished and leave the mutex. */
1103 cond_join->signal();
1104 threads_mutex_join_unlock();
1111 * Internal helper function which suspends the current thread. This is
1112 * the core method of the suspension mechanism actually blocking the
1113 * execution until the suspension reason is cleared again. Note that
1114 * the current thread needs to hold the suspension mutex while calling
1117 static void threads_suspend_self()
1119 threadobject* thread = THREADOBJECT;
1121 DEBUGTHREADS("suspending", thread);
1123 // Mark thread as suspended.
1124 assert(!thread->suspended);
1125 assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1126 thread->suspended = true;
1128 // Acknowledge the suspension.
1129 thread->suspendcond->broadcast();
1131 #if defined(ENABLE_GC_CACAO)
1132 // If we are stopping the world, we should send a global ack.
1133 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1134 threads_sem_post(&suspend_ack);
1137 // Release the suspension mutex and wait till we are resumed.
1138 thread->suspendcond->wait(thread->suspendmutex);
1140 #if defined(ENABLE_GC_CACAO)
1141 // XXX This is propably not ok!
1142 // If we are starting the world, we should send a global ack.
1143 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1144 threads_sem_post(&suspend_ack);
1147 // Mark thread as not suspended.
1148 assert(thread->suspended);
1149 assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1150 thread->suspended = false;
1152 DEBUGTHREADS("resuming", thread);
1157 * Suspend the passed thread. Execution of that thread stops until the thread
1158 * is explicitly resumend again.
1160 * @param thread The thread to be suspended.
1161 * @param reason Reason for suspending the given thread.
1162 * @return True of operation was successful, false otherwise.
1164 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1167 assert(reason != SUSPEND_REASON_NONE);
1169 // Guard this with the suspension mutex.
1170 MutexLocker ml(*thread->suspendmutex);
1172 // Check if thread is already suspended.
1173 if (thread->suspended)
1176 // Check if thread is in the process of suspending.
1177 if (thread->suspend_reason != SUSPEND_REASON_NONE)
1180 // Set the reason for suspending the thread.
1181 thread->suspend_reason = reason;
1183 if (thread == THREADOBJECT) {
1184 // We already hold the suspension mutex and can suspend ourselves
1185 // immediately without using signals at all.
1186 threads_suspend_self();
1189 // Send the suspend signal to the other thread.
1190 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1191 os::abort_errno("threads_suspend_thread: pthread_kill failed");
1193 // Wait for the thread to acknowledge the suspension.
1194 // XXX A possible optimization would be to not wait here, but you
1195 // better think this through twice before trying it!
1196 thread->suspendcond->wait(thread->suspendmutex);
1204 * Resumes execution of the passed thread.
1206 * @param thread The thread to be resumed.
1207 * @param reason Reason for suspending the given thread.
1208 * @return True of operation was successful, false otherwise.
1210 bool threads_resume_thread(threadobject *thread, int32_t reason)
1213 assert(thread != THREADOBJECT);
1214 assert(reason != SUSPEND_REASON_NONE);
1216 // Guard this with the suspension mutex.
1217 MutexLocker ml(*thread->suspendmutex);
1219 // Check if thread really is suspended.
1220 if (!thread->suspended)
1223 // Threads can only be resumed for the same reason they were suspended.
1224 if (thread->suspend_reason != reason)
1227 // Clear the reason for suspending the thread.
1228 thread->suspend_reason = SUSPEND_REASON_NONE;
1230 // Tell everyone that the thread should resume.
1231 thread->suspendcond->broadcast();
1238 * Acknowledges the suspension of the current thread.
1240 void threads_suspend_ack()
1242 threadobject* thread = THREADOBJECT;
1244 // Guard this with the suspension mutex.
1245 MutexLocker ml(*thread->suspendmutex);
1247 // Suspend ourselves while holding the suspension mutex.
1248 threads_suspend_self();
1252 /* threads_join_all_threads ****************************************************
1254 Join all non-daemon threads.
1256 *******************************************************************************/
1258 void threads_join_all_threads(void)
1262 /* get current thread */
1266 /* This thread is waiting for all non-daemon threads to exit. */
1268 thread_set_state_waiting(t);
1270 /* enter join mutex */
1272 threads_mutex_join_lock();
1274 /* Wait for condition as long as we have non-daemon threads. We
1275 compare against 1 because the current (main thread) is also a
1276 non-daemon thread. */
1278 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1279 cond_join->wait(mutex_join);
1281 /* leave join mutex */
1283 threads_mutex_join_unlock();
1287 /* threads_timespec_earlier ****************************************************
1289 Return true if timespec tv1 is earlier than timespec tv2.
1292 tv1..........first timespec
1293 tv2..........second timespec
1296 true, if the first timespec is earlier
1298 *******************************************************************************/
1300 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1301 const struct timespec *tv2)
1303 return (tv1->tv_sec < tv2->tv_sec)
1305 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1309 /* threads_current_time_is_earlier_than ****************************************
1311 Check if the current time is earlier than the given timespec.
1314 tv...........the timespec to compare against
1317 true, if the current time is earlier
1319 *******************************************************************************/
1321 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1323 struct timeval tvnow;
1324 struct timespec tsnow;
1326 /* get current time */
1328 if (gettimeofday(&tvnow, NULL) != 0)
1329 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1331 /* convert it to a timespec */
1333 tsnow.tv_sec = tvnow.tv_sec;
1334 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1336 /* compare current time with the given timespec */
1338 return threads_timespec_earlier(&tsnow, tv);
1342 /* threads_wait_with_timeout ***************************************************
1344 Wait until the given point in time on a monitor until either
1345 we are notified, we are interrupted, or the time is up.
1348 t............the current thread
1349 wakeupTime...absolute (latest) wakeup time
1350 If both tv_sec and tv_nsec are zero, this function
1351 waits for an unlimited amount of time.
1353 *******************************************************************************/
1355 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1357 // Acquire the waitmutex.
1358 t->waitmutex->lock();
1360 /* wait on waitcond */
1362 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1364 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1365 && threads_current_time_is_earlier_than(wakeupTime))
1368 thread_set_state_timed_parked(t);
1370 thread_set_state_timed_waiting(t);
1372 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1374 thread_set_state_runnable(t);
1379 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1381 thread_set_state_parked(t);
1383 thread_set_state_waiting(t);
1385 t->waitcond->wait(t->waitmutex);
1387 thread_set_state_runnable(t);
1392 t->park_permit = false;
1394 // Release the waitmutex.
1395 t->waitmutex->unlock();
1399 /* threads_wait_with_timeout_relative ******************************************
1401 Wait for the given maximum amount of time on a monitor until either
1402 we are notified, we are interrupted, or the time is up.
1405 t............the current thread
1406 millis.......milliseconds to wait
1407 nanos........nanoseconds to wait
1409 *******************************************************************************/
1411 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1414 struct timespec wakeupTime;
1416 /* calculate the the (latest) wakeup time */
1418 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1422 threads_wait_with_timeout(thread, &wakeupTime, false);
1426 /* threads_calc_absolute_time **************************************************
1428 Calculate the absolute point in time a given number of ms and ns from now.
1431 millis............milliseconds from now
1432 nanos.............nanoseconds from now
1435 *tm...............receives the timespec of the absolute point in time
1437 *******************************************************************************/
1439 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1441 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1443 if (!millis && !nanos)
1446 gettimeofday(&tv, NULL);
1447 s8 secs = tv.tv_sec + millis / 1000;
1448 if (secs > INT32_MAX) // integer overflow
1452 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1453 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1454 if (tm->tv_sec < tv.tv_sec) // integer overflow
1456 tm->tv_nsec = nsec % 1000000000;
1464 /* threads_thread_interrupt ****************************************************
1466 Interrupt the given thread.
1468 The thread gets the "waitcond" signal and
1469 its interrupted flag is set to true.
1472 thread............the thread to interrupt
1474 *******************************************************************************/
1476 void threads_thread_interrupt(threadobject *t)
1478 /* Signal the thread a "waitcond" and tell it that it has been
1481 t->waitmutex->lock();
1483 DEBUGTHREADS("interrupted", t);
1485 /* Interrupt blocking system call using a signal. */
1487 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1489 t->waitcond->signal();
1491 t->interrupted = true;
1493 t->waitmutex->unlock();
1498 * Sleep the current thread for the specified amount of time.
1500 * @param millis Milliseconds to sleep.
1501 * @param nanos Nanoseconds to sleep.
1503 void threads_sleep(int64_t millis, int32_t nanos)
1506 struct timespec wakeupTime;
1510 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1511 exceptions_throw_illegalargumentexception();
1515 t = thread_get_current();
1517 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1518 /* Clear interrupted flag (Mauve test:
1519 gnu/testlet/java/lang/Thread/interrupt). */
1521 thread_set_interrupted(t, false);
1523 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1524 exceptions_throw_interruptedexception();
1528 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1529 // Note: JDK treats a zero length sleep is like Thread.yield(),
1530 // without checking the interrupted status of the thread. It's
1531 // unclear if this is a bug in the implementation or the spec.
1532 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1533 if (millis == 0 && nanos == 0) {
1537 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1539 threads_wait_with_timeout(t, &wakeupTime, false);
1541 interrupted = thread_is_interrupted(t);
1544 thread_set_interrupted(t, false);
1546 // An other exception could have been thrown
1547 // (e.g. ThreadDeathException).
1548 if (!exceptions_get_exception())
1549 exceptions_throw_interruptedexception();
1555 * Park the current thread for the specified amount of time or until a
1556 * specified deadline.
1558 * @param absolute Is the time in nanos a deadline or a duration?
1559 * @param nanos Nanoseconds to park (absolute=false)
1560 * or deadline in milliseconds (absolute=true)
1562 void threads_park(bool absolute, int64_t nanos)
1565 struct timespec wakeupTime;
1567 t = thread_get_current();
1570 wakeupTime.tv_nsec = 0;
1571 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1574 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1576 threads_wait_with_timeout(t, &wakeupTime, true);
1580 * Unpark the specified thread.
1582 * @param t The thread to unpark.
1584 void threads_unpark(threadobject *t)
1586 t->waitmutex->lock();
1588 t->waitcond->signal();
1590 t->park_permit = true;
1592 t->waitmutex->unlock();
1596 /* threads_yield ***************************************************************
1598 Yield to the scheduler.
1600 *******************************************************************************/
1602 void threads_yield(void)
1607 #if defined(ENABLE_TLH)
1609 void threads_tlh_add_frame() {
1610 tlh_add_frame(&(THREADOBJECT->tlh));
1613 void threads_tlh_remove_frame() {
1614 tlh_remove_frame(&(THREADOBJECT->tlh));
1621 * These are local overrides for various environment variables in Emacs.
1622 * Please do not remove this and leave it at the end of the file, where
1623 * Emacs will automagically detect them.
1624 * ---------------------------------------------------------------------
1627 * indent-tabs-mode: t
1631 * vim:noexpandtab:sw=4:ts=4: