1 /* src/threads/posix/thread-posix.cpp - POSIX thread functions
3 Copyright (C) 1996-2011
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 Condition* cond_join;
214 #if defined(ENABLE_GC_CACAO)
215 /* semaphore used for acknowleding thread suspension */
216 static sem_t suspend_ack;
220 /* threads_sem_init ************************************************************
222 Initialize a semaphore. Checks against errors and interruptions.
225 sem..............the semaphore to initialize
226 shared...........true if this semaphore will be shared between processes
227 value............the initial value for the semaphore
229 *******************************************************************************/
231 void threads_sem_init(sem_t *sem, bool shared, int value)
238 r = sem_init(sem, shared, value);
241 } while (errno == EINTR);
243 vm_abort("sem_init failed: %s", strerror(errno));
247 /* threads_sem_wait ************************************************************
249 Wait for a semaphore, non-interruptible.
251 IMPORTANT: Always use this function instead of `sem_wait` directly, as
252 `sem_wait` may be interrupted by signals!
255 sem..............the semaphore to wait on
257 *******************************************************************************/
259 void threads_sem_wait(sem_t *sem)
269 } while (errno == EINTR);
271 vm_abort("sem_wait failed: %s", strerror(errno));
275 /* threads_sem_post ************************************************************
277 Increase the count of a semaphore. Checks for errors.
280 sem..............the semaphore to increase the count of
282 *******************************************************************************/
284 void threads_sem_post(sem_t *sem)
290 /* unlike sem_wait, sem_post is not interruptible */
296 vm_abort("sem_post failed: %s", strerror(errno));
300 /* threads_stopworld ***********************************************************
302 Stops the world from turning. All threads except the calling one
303 are suspended. The function returns as soon as all threads have
304 acknowledged their suspension.
306 *******************************************************************************/
308 #if defined(ENABLE_GC_CACAO)
309 void threads_stopworld(void)
311 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
318 stopworldlock->lock();
320 /* lock the threads lists */
324 #if defined(__DARWIN__)
325 /*threads_cast_darwinstop();*/
327 #elif defined(__CYGWIN__)
333 DEBUGTHREADS("stops World", self);
337 /* suspend all running threads */
338 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
339 /* don't send the signal to ourself */
344 /* don't send the signal to NEW threads (because they are not
345 completely initialized) */
347 if (t->state == THREAD_STATE_NEW)
350 /* send the signal */
352 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
355 /* increase threads count */
360 /* wait for all threads signaled to suspend */
361 for (i = 0; i < count; i++)
362 threads_sem_wait(&suspend_ack);
365 /* ATTENTION: Don't unlock the threads-lists here so that
366 non-signaled NEW threads can't change their state and execute
372 /* threads_startworld **********************************************************
374 Starts the world again after it has previously been stopped.
376 *******************************************************************************/
378 #if defined(ENABLE_GC_CACAO)
379 void threads_startworld(void)
381 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
388 #if defined(__DARWIN__)
389 /*threads_cast_darwinresume();*/
391 #elif defined(__IRIX__)
392 threads_cast_irixresume();
393 #elif defined(__CYGWIN__)
399 DEBUGTHREADS("starts World", self);
403 /* resume all thread we haltet */
404 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
405 /* don't send the signal to ourself */
410 /* don't send the signal to NEW threads (because they are not
411 completely initialized) */
413 if (t->state == THREAD_STATE_NEW)
416 /* send the signal */
418 result = threads_resume_thread(t);
421 /* increase threads count */
426 /* wait for all threads signaled to suspend */
427 for (i = 0; i < count; i++)
428 threads_sem_wait(&suspend_ack);
432 /* unlock the threads lists */
436 stopworldlock->unlock();
441 /* threads_impl_thread_clear ***************************************************
443 Clears all fields in threadobject the way an MZERO would have
444 done. MZERO cannot be used anymore because it would mess up the
448 t....the threadobject
450 *******************************************************************************/
452 void threads_impl_thread_clear(threadobject *t)
461 t->is_in_active_list = false;
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));
535 void threads_impl_clear_heap_pointers(threadobject *t)
541 /* threads_impl_preinit ********************************************************
543 Do some early initialization of stuff required.
545 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
546 is called AFTER this function!
548 *******************************************************************************/
550 void threads_impl_preinit(void)
552 stopworldlock = new Mutex();
554 /* initialize exit mutex and condition (on exit we join all
557 cond_join = new Condition();
559 #if defined(ENABLE_GC_CACAO)
560 /* initialize the GC mutex & suspend semaphore */
562 mutex_gc = new Mutex();
563 threads_sem_init(&suspend_ack, 0, 0);
566 #if !defined(HAVE___THREAD)
567 int result = pthread_key_create(&thread_current_key, NULL);
569 os::abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
574 /* threads_mutex_gc_lock *******************************************************
576 Enter the global GC mutex.
578 *******************************************************************************/
580 #if defined(ENABLE_GC_CACAO)
581 void threads_mutex_gc_lock(void)
588 /* threads_mutex_gc_unlock *****************************************************
590 Leave the global GC mutex.
592 *******************************************************************************/
594 #if defined(ENABLE_GC_CACAO)
595 void threads_mutex_gc_unlock(void)
601 /* threads_impl_init ***********************************************************
603 Initializes the implementation specific bits.
605 *******************************************************************************/
607 void threads_impl_init(void)
612 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
614 /* Initialize the thread attribute object. */
616 result = pthread_attr_init(&attr);
619 os::abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
621 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
624 os::abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
628 /* threads_startup_thread ******************************************************
630 Thread startup function called by pthread_create.
632 Thread which have a startup.function != NULL are marked as internal
633 threads. All other threads are threated as normal Java threads.
635 NOTE: This function is not called directly by pthread_create. The Boehm GC
636 inserts its own GC_start_routine in between, which then calls
640 arg..........the argument passed to pthread_create, ie. a pointer to
641 a startupinfo struct. CAUTION: When the `psem` semaphore
642 is posted, the startupinfo struct becomes invalid! (It
643 is allocated on the stack of threads_start_thread.)
645 ******************************************************************************/
647 static void *threads_startup_thread(void *arg)
649 startupinfo *startup;
654 functionptr function;
656 #if defined(ENABLE_GC_BOEHM)
657 # if !defined(__DARWIN__)
658 struct GC_stack_base sb;
663 #if defined(ENABLE_INTRP)
664 u1 *intrp_thread_stack;
667 #if defined(ENABLE_INTRP)
668 /* create interpreter stack */
671 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
672 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
675 intrp_thread_stack = NULL;
678 /* get passed startupinfo structure and the values in there */
680 startup = (startupinfo*) arg;
683 function = startup->function;
684 psem = startup->psem;
686 /* Seems like we've encountered a situation where thread->tid was
687 not set by pthread_create. We alleviate this problem by waiting
688 for pthread_create to return. */
690 threads_sem_wait(startup->psem_first);
692 #if defined(__DARWIN__)
693 t->mach_thread = mach_thread_self();
696 /* Now that we are in the new thread, we can store the internal
697 thread data-structure in the TSD. */
699 thread_set_current(t);
701 #if defined(ENABLE_GC_BOEHM)
702 # if defined(__DARWIN__)
703 // This is currently not implemented in Boehm-GC. Just fail silently.
705 /* Register the thread with Boehm-GC. This must happen before the
706 thread allocates any memory from the GC heap.*/
708 result = GC_get_stack_base(&sb);
711 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
713 GC_register_my_thread(&sb);
717 // Get the java.lang.Thread object for this thread.
718 java_handle_t* object = LLNI_WRAP(t->object);
719 java_lang_Thread jlt(object);
721 /* set our priority */
723 threads_set_thread_priority(t->tid, jlt.get_priority());
725 /* Thread is completely initialized. */
727 thread_set_state_runnable(t);
729 /* tell threads_startup_thread that we registered ourselves */
730 /* CAUTION: *startup becomes invalid with this! */
733 threads_sem_post(psem);
735 #if defined(ENABLE_INTRP)
736 /* set interpreter stack */
739 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
742 // Hook point just before the threads initial method is executed.
743 Hook::thread_start(t);
745 DEBUGTHREADS("starting", t);
747 /* find and run the Thread.run()V method if no other function was passed */
749 if (function == NULL) {
750 c = ThreadRuntime::get_thread_class_from_object(object);
752 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
755 vm_abort("threads_startup_thread: run() method not found in class");
757 java_handle_t *h = ThreadRuntime::get_vmthread_handle(jlt);
759 /* Run the thread. */
761 (void) vm_call_method(m, h);
764 /* call passed function, e.g. finalizer_thread */
769 DEBUGTHREADS("stopping", t);
771 // Hook point just after the threads initial method returned.
774 /* We ignore the return value. */
776 (void) thread_detach_current_thread();
782 /* threads_impl_thread_start ***************************************************
784 Start a thread in the JVM. Both (vm internal and java) thread
788 thread....the thread object
789 f.........function to run in the new thread. NULL means that the
790 "run" method of the object `t` should be called
792 ******************************************************************************/
794 void threads_impl_thread_start(threadobject *thread, functionptr f)
802 /* fill startupinfo structure passed by pthread_create to
803 * threads_startup_thread */
805 startup.thread = thread;
806 startup.function = f; /* maybe we don't call Thread.run()V */
808 startup.psem_first = &sem_first;
810 threads_sem_init(&sem, 0, 0);
811 threads_sem_init(&sem_first, 0, 0);
813 /* Initialize thread attributes. */
815 result = pthread_attr_init(&attr);
818 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
820 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
823 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
825 /* initialize thread stacksize */
827 result = pthread_attr_setstacksize(&attr, opt_stacksize);
830 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
832 /* create the thread */
834 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
837 os::abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
839 /* destroy the thread attributes */
841 result = pthread_attr_destroy(&attr);
844 os::abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
846 /* signal that pthread_create has returned, so thread->tid is valid */
848 threads_sem_post(&sem_first);
850 /* wait here until the thread has entered itself into the thread list */
852 threads_sem_wait(&sem);
857 sem_destroy(&sem_first);
861 /* threads_set_thread_priority *************************************************
863 Set the priority of the given thread.
866 tid..........thread id
867 priority.....priority to set
869 ******************************************************************************/
871 void threads_set_thread_priority(pthread_t tid, int priority)
873 struct sched_param schedp;
876 pthread_getschedparam(tid, &policy, &schedp);
877 schedp.sched_priority = priority;
878 pthread_setschedparam(tid, policy, &schedp);
883 * Detaches the current thread from the VM.
885 * @return true on success, false otherwise
887 bool thread_detach_current_thread(void)
889 threadobject* t = thread_get_current();
895 /* If the given thread has already been detached, this operation
898 if (thread_is_attached(t) == false)
901 DEBUGTHREADS("detaching", t);
903 java_handle_t* object = LLNI_WRAP(t->object);
904 java_lang_Thread jlt(object);
906 #if defined(ENABLE_JAVASE)
907 java_handle_t* group = jlt.get_group();
909 /* If there's an uncaught exception, call uncaughtException on the
910 thread's exception handler, or the thread's group if this is
913 java_handle_t* e = exceptions_get_and_clear_exception();
916 /* We use the type void* for handler here, as it's not trivial
917 to build the java_lang_Thread_UncaughtExceptionHandler
918 header file with cacaoh. */
920 java_handle_t *handler = ThreadRuntime::get_thread_exception_handler(jlt);
925 if (handler != NULL) {
926 LLNI_class_get(handler, c);
927 h = (java_handle_t *) handler;
930 LLNI_class_get(group, c);
931 h = (java_handle_t *) group;
934 methodinfo* m = class_resolveclassmethod(c,
935 utf_uncaughtException,
936 utf_java_lang_Thread_java_lang_Throwable__V,
943 (void) vm_call_method(m, h, object, e);
945 if (exceptions_get_exception())
949 /* XXX TWISTI: should all threads be in a ThreadGroup? */
951 /* Remove thread from the thread group. */
955 LLNI_class_get(group, c);
957 methodinfo *m = ThreadRuntime::get_threadgroup_remove_method(c);
962 (void) vm_call_method(m, group, object);
964 if (exceptions_get_exception())
967 // Clear the ThreadGroup in the Java thread object (Mauve
968 // test: gnu/testlet/java/lang/Thread/getThreadGroup).
973 /* Thread has terminated. */
975 thread_set_state_terminated(t);
977 /* Notify all threads waiting on this thread. These are joining
980 /* XXX Care about exceptions? */
981 (void) lock_monitor_enter(jlt.get_handle());
983 lock_notify_all_object(jlt.get_handle());
985 /* XXX Care about exceptions? */
986 (void) lock_monitor_exit(jlt.get_handle());
988 t->waitmutex->lock();
990 t->waitmutex->unlock();
994 /* Free the internal thread data-structure. */
998 /* Signal that this thread has finished and leave the mutex. */
1000 cond_join->signal();
1001 ThreadList::unlock();
1003 t->suspendmutex->lock();
1004 t->suspendmutex->unlock();
1011 * Internal helper function which suspends the current thread. This is
1012 * the core method of the suspension mechanism actually blocking the
1013 * execution until the suspension reason is cleared again. Note that
1014 * the current thread needs to hold the suspension mutex while calling
1017 static void threads_suspend_self()
1019 threadobject* thread = THREADOBJECT;
1021 DEBUGTHREADS("suspending", thread);
1023 // Mark thread as suspended.
1024 assert(!thread->suspended);
1025 assert(thread->suspend_reason != SUSPEND_REASON_NONE);
1026 thread->suspended = true;
1028 // Acknowledge the suspension.
1029 thread->suspendcond->broadcast();
1031 #if defined(ENABLE_GC_CACAO)
1032 // If we are stopping the world, we should send a global ack.
1033 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1034 threads_sem_post(&suspend_ack);
1037 // Release the suspension mutex and wait till we are resumed.
1038 while (thread->suspend_reason != SUSPEND_REASON_NONE)
1039 thread->suspendcond->wait(thread->suspendmutex);
1041 #if defined(ENABLE_GC_CACAO)
1042 // XXX This is propably not ok!
1043 // If we are starting the world, we should send a global ack.
1044 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD)
1045 threads_sem_post(&suspend_ack);
1048 // Mark thread as not suspended.
1049 assert(thread->suspended);
1050 assert(thread->suspend_reason == SUSPEND_REASON_NONE);
1051 thread->suspended = false;
1053 DEBUGTHREADS("resuming", thread);
1058 * Suspend the passed thread. Execution of that thread stops until the thread
1059 * is explicitly resumed again.
1061 * @param thread The thread to be suspended.
1062 * @param reason Reason for suspending the given thread.
1063 * @return True of operation was successful, false otherwise.
1065 bool threads_suspend_thread(threadobject *thread, int32_t reason)
1068 assert(reason != SUSPEND_REASON_NONE);
1070 // Guard this with the suspension mutex.
1071 MutexLocker ml(*thread->suspendmutex);
1073 // Check if thread is already suspended.
1074 if (thread->suspended)
1077 // Check if thread is in the process of suspending.
1078 if (thread->suspend_reason != SUSPEND_REASON_NONE)
1081 // Set the reason for suspending the thread.
1082 thread->suspend_reason = reason;
1084 if (thread == THREADOBJECT) {
1085 // We already hold the suspension mutex and can suspend ourselves
1086 // immediately without using signals at all.
1087 threads_suspend_self();
1090 // Send the suspend signal to the other thread.
1093 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1094 os::abort_errno("threads_suspend_thread: pthread_kill failed");
1096 // Wait for the thread to acknowledge the suspension.
1097 while (!thread->suspended)
1098 thread->suspendcond->wait(thread->suspendmutex);
1106 * Resumes execution of the passed thread.
1108 * @param thread The thread to be resumed.
1109 * @param reason Reason for suspending the given thread.
1110 * @return True of operation was successful, false otherwise.
1112 bool threads_resume_thread(threadobject *thread, int32_t reason)
1115 assert(thread != THREADOBJECT);
1116 assert(reason != SUSPEND_REASON_NONE);
1118 // Guard this with the suspension mutex.
1119 MutexLocker ml(*thread->suspendmutex);
1121 // Check if thread really is suspended.
1122 if (!thread->suspended)
1125 // Threads can only be resumed for the same reason they were suspended.
1126 if (thread->suspend_reason != reason)
1129 // Clear the reason for suspending the thread.
1130 thread->suspend_reason = SUSPEND_REASON_NONE;
1132 // Tell everyone that the thread should resume.
1133 thread->suspendcond->broadcast();
1140 * Acknowledges the suspension of the current thread.
1142 void threads_suspend_ack()
1144 threadobject* thread = THREADOBJECT;
1146 // Guard this with the suspension mutex.
1147 MutexLocker ml(*thread->suspendmutex);
1149 // Suspend ourselves while holding the suspension mutex.
1150 threads_suspend_self();
1154 /* threads_join_all_threads ****************************************************
1156 Join all non-daemon threads.
1158 *******************************************************************************/
1160 void threads_join_all_threads(void)
1164 /* get current thread */
1168 /* This thread is waiting for all non-daemon threads to exit. */
1170 thread_set_state_waiting(t);
1172 /* enter join mutex */
1176 /* Wait for condition as long as we have non-daemon threads. We
1177 compare against 1 because the current (main thread) is also a
1178 non-daemon thread. */
1180 while (ThreadList::get_number_of_non_daemon_threads() > 1)
1181 ThreadList::wait_cond(cond_join);
1183 /* leave join mutex */
1185 ThreadList::unlock();
1189 /* threads_timespec_earlier ****************************************************
1191 Return true if timespec tv1 is earlier than timespec tv2.
1194 tv1..........first timespec
1195 tv2..........second timespec
1198 true, if the first timespec is earlier
1200 *******************************************************************************/
1202 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1203 const struct timespec *tv2)
1205 return (tv1->tv_sec < tv2->tv_sec)
1207 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1211 /* threads_current_time_is_earlier_than ****************************************
1213 Check if the current time is earlier than the given timespec.
1216 tv...........the timespec to compare against
1219 true, if the current time is earlier
1221 *******************************************************************************/
1223 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1225 struct timeval tvnow;
1226 struct timespec tsnow;
1228 /* get current time */
1230 if (gettimeofday(&tvnow, NULL) != 0)
1231 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1233 /* convert it to a timespec */
1235 tsnow.tv_sec = tvnow.tv_sec;
1236 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1238 /* compare current time with the given timespec */
1240 return threads_timespec_earlier(&tsnow, tv);
1244 /* threads_wait_with_timeout ***************************************************
1246 Wait until the given point in time on a monitor until either
1247 we are notified, we are interrupted, or the time is up.
1250 t............the current thread
1251 wakeupTime...absolute (latest) wakeup time
1252 If both tv_sec and tv_nsec are zero, this function
1253 waits for an unlimited amount of time.
1255 *******************************************************************************/
1257 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime, bool parking)
1259 // Acquire the waitmutex.
1260 t->waitmutex->lock();
1262 /* wait on waitcond */
1264 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1266 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
1267 && threads_current_time_is_earlier_than(wakeupTime))
1270 thread_set_state_timed_parked(t);
1272 thread_set_state_timed_waiting(t);
1274 t->waitcond->timedwait(t->waitmutex, wakeupTime);
1276 thread_set_state_runnable(t);
1281 while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
1283 thread_set_state_parked(t);
1285 thread_set_state_waiting(t);
1287 t->waitcond->wait(t->waitmutex);
1289 thread_set_state_runnable(t);
1294 t->park_permit = false;
1296 // Release the waitmutex.
1297 t->waitmutex->unlock();
1301 /* threads_wait_with_timeout_relative ******************************************
1303 Wait for the given maximum amount of time on a monitor until either
1304 we are notified, we are interrupted, or the time is up.
1307 t............the current thread
1308 millis.......milliseconds to wait
1309 nanos........nanoseconds to wait
1311 *******************************************************************************/
1313 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1316 struct timespec wakeupTime;
1318 /* calculate the the (latest) wakeup time */
1320 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1324 threads_wait_with_timeout(thread, &wakeupTime, false);
1328 /* threads_calc_absolute_time **************************************************
1330 Calculate the absolute point in time a given number of ms and ns from now.
1333 millis............milliseconds from now
1334 nanos.............nanoseconds from now
1337 *tm...............receives the timespec of the absolute point in time
1339 *******************************************************************************/
1341 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1343 // (at least with GNU classpath) we know that 0 <= nanos <= 999999
1345 if (!millis && !nanos)
1348 gettimeofday(&tv, NULL);
1349 s8 secs = tv.tv_sec + millis / 1000;
1350 if (secs > INT32_MAX) // integer overflow
1354 long nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1355 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1356 if (tm->tv_sec < tv.tv_sec) // integer overflow
1358 tm->tv_nsec = nsec % 1000000000;
1366 /* threads_thread_interrupt ****************************************************
1368 Interrupt the given thread.
1370 The thread gets the "waitcond" signal and
1371 its interrupted flag is set to true.
1374 thread............the thread to interrupt
1376 *******************************************************************************/
1378 void threads_thread_interrupt(threadobject *t)
1380 /* Signal the thread a "waitcond" and tell it that it has been
1383 t->waitmutex->lock();
1385 DEBUGTHREADS("interrupted", t);
1387 /* Interrupt blocking system call using a signal. */
1390 pthread_kill(t->tid, Signal_INTERRUPT_SYSTEM_CALL);
1392 t->waitcond->signal();
1394 t->interrupted = true;
1396 t->waitmutex->unlock();
1401 * Sleep the current thread for the specified amount of time.
1403 * @param millis Milliseconds to sleep.
1404 * @param nanos Nanoseconds to sleep.
1406 void threads_sleep(int64_t millis, int32_t nanos)
1409 struct timespec wakeupTime;
1413 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1414 exceptions_throw_illegalargumentexception();
1418 t = thread_get_current();
1420 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1421 /* Clear interrupted flag (Mauve test:
1422 gnu/testlet/java/lang/Thread/interrupt). */
1424 thread_set_interrupted(t, false);
1426 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1427 exceptions_throw_interruptedexception();
1431 // (Note taken from classpath/vm/reference/java/lang/VMThread.java (sleep))
1432 // Note: JDK treats a zero length sleep is like Thread.yield(),
1433 // without checking the interrupted status of the thread. It's
1434 // unclear if this is a bug in the implementation or the spec.
1435 // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203 */
1436 if (millis == 0 && nanos == 0) {
1440 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1442 threads_wait_with_timeout(t, &wakeupTime, false);
1444 interrupted = thread_is_interrupted(t);
1447 thread_set_interrupted(t, false);
1449 // An other exception could have been thrown
1450 // (e.g. ThreadDeathException).
1451 if (!exceptions_get_exception())
1452 exceptions_throw_interruptedexception();
1458 * Park the current thread for the specified amount of time or until a
1459 * specified deadline.
1461 * @param absolute Is the time in nanos a deadline or a duration?
1462 * @param nanos Nanoseconds to park (absolute=false)
1463 * or deadline in milliseconds (absolute=true)
1465 void threads_park(bool absolute, int64_t nanos)
1468 struct timespec wakeupTime;
1470 t = thread_get_current();
1473 wakeupTime.tv_nsec = 0;
1474 wakeupTime.tv_sec = nanos / 1000; /* milliseconds */
1477 threads_calc_absolute_time(&wakeupTime, nanos / 1000000, nanos % 1000000);
1479 threads_wait_with_timeout(t, &wakeupTime, true);
1483 * Unpark the specified thread.
1485 * @param t The thread to unpark.
1487 void threads_unpark(threadobject *t)
1489 t->waitmutex->lock();
1491 t->waitcond->signal();
1493 t->park_permit = true;
1495 t->waitmutex->unlock();
1499 /* threads_yield ***************************************************************
1501 Yield to the scheduler.
1503 *******************************************************************************/
1505 void threads_yield(void)
1510 #if defined(ENABLE_TLH)
1512 void threads_tlh_add_frame() {
1513 tlh_add_frame(&(THREADOBJECT->tlh));
1516 void threads_tlh_remove_frame() {
1517 tlh_remove_frame(&(THREADOBJECT->tlh));
1524 * These are local overrides for various environment variables in Emacs.
1525 * Please do not remove this and leave it at the end of the file, where
1526 * Emacs will automagically detect them.
1527 * ---------------------------------------------------------------------
1530 * indent-tabs-mode: t
1534 * vim:noexpandtab:sw=4:ts=4: