1 /* src/threads/posix/thread-posix.c - POSIX thread functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 /* XXX cleanup these includes */
33 #include <sys/types.h>
46 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
47 # include "machine-instr.h"
49 # include "threads/posix/generic-primitives.h"
52 #include "mm/gc-common.h"
53 #include "mm/memory.h"
55 #if defined(ENABLE_GC_CACAO)
56 # include "mm/cacao-gc/gc.h"
59 #include "native/jni.h"
60 #include "native/llni.h"
61 #include "native/native.h"
63 #include "native/include/java_lang_Object.h"
64 #include "native/include/java_lang_String.h"
65 #include "native/include/java_lang_Throwable.h"
66 #include "native/include/java_lang_Thread.h"
68 #if defined(ENABLE_JAVASE)
69 # include "native/include/java_lang_ThreadGroup.h"
72 #if defined(WITH_CLASSPATH_GNU)
73 # include "native/include/java_lang_VMThread.h"
76 #include "threads/lock-common.h"
77 #include "threads/threadlist.h"
78 #include "threads/thread.h"
80 #include "toolbox/logging.h"
82 #include "vm/builtin.h"
83 #include "vm/exceptions.h"
84 #include "vm/global.h"
85 #include "vm/stringlocal.h"
88 #include "vm/jit/asmpart.h"
90 #include "vmcore/options.h"
92 #if defined(ENABLE_STATISTICS)
93 # include "vmcore/statistics.h"
96 #if !defined(__DARWIN__)
97 # if defined(__LINUX__)
98 # define GC_LINUX_THREADS
99 # elif defined(__IRIX__)
100 # define GC_IRIX_THREADS
102 # include <semaphore.h>
103 # if defined(ENABLE_GC_BOEHM)
104 # include "mm/boehm-gc/include/gc.h"
108 #if defined(ENABLE_JVMTI)
109 #include "native/jvmti/cacaodbg.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)
130 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
133 if (pthread_cond_init(&sem->cond, NULL) < 0)
139 static int sem_post(sem_t *sem)
141 if (pthread_mutex_lock(&sem->mutex) < 0)
146 if (pthread_cond_signal(&sem->cond) < 0) {
147 pthread_mutex_unlock(&sem->mutex);
151 if (pthread_mutex_unlock(&sem->mutex) < 0)
157 static int sem_wait(sem_t *sem)
159 if (pthread_mutex_lock(&sem->mutex) < 0)
162 while (sem->value == 0) {
163 pthread_cond_wait(&sem->cond, &sem->mutex);
168 if (pthread_mutex_unlock(&sem->mutex) < 0)
174 static int sem_destroy(sem_t *sem)
176 if (pthread_cond_destroy(&sem->cond) < 0)
179 if (pthread_mutex_destroy(&sem->mutex) < 0)
184 #endif /* defined(__DARWIN__) */
187 /* internally used constants **************************************************/
189 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
190 #define STOPWORLD_FROM_GC 1
191 #define STOPWORLD_FROM_CLASS_NUMBERING 2
194 /* startupinfo *****************************************************************
196 Struct used to pass info from threads_start_thread to
197 threads_startup_thread.
199 ******************************************************************************/
202 threadobject *thread; /* threadobject for this thread */
203 functionptr function; /* function to run in the new thread */
204 sem_t *psem; /* signals when thread has been entered */
205 /* in the thread list */
206 sem_t *psem_first; /* signals when pthread_create has returned */
210 /* prototypes *****************************************************************/
212 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
215 /******************************************************************************/
216 /* GLOBAL VARIABLES */
217 /******************************************************************************/
219 /* the thread object of the current thread */
220 /* This is either a thread-local variable defined with __thread, or */
221 /* a thread-specific value stored with key threads_current_threadobject_key. */
222 #if defined(HAVE___THREAD)
223 __thread threadobject *thread_current;
225 pthread_key_t thread_current_key;
228 /* global mutex for stop-the-world */
229 static pthread_mutex_t stopworldlock;
231 #if defined(ENABLE_GC_CACAO)
232 /* global mutex for the GC */
233 static pthread_mutex_t mutex_gc;
236 /* global mutex and condition for joining threads on exit */
237 static pthread_mutex_t mutex_join;
238 static pthread_cond_t cond_join;
240 /* XXX We disable that whole bunch of code until we have the exact-GC
245 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
247 static volatile int stopworldwhere;
249 /* semaphore used for acknowleding thread suspension */
250 static sem_t suspend_ack;
251 #if defined(__IRIX__)
252 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
253 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
258 /* mutexes used by the fake atomic instructions */
259 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
260 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
261 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
265 /* threads_sem_init ************************************************************
267 Initialize a semaphore. Checks against errors and interruptions.
270 sem..............the semaphore to initialize
271 shared...........true if this semaphore will be shared between processes
272 value............the initial value for the semaphore
274 *******************************************************************************/
276 void threads_sem_init(sem_t *sem, bool shared, int value)
283 r = sem_init(sem, shared, value);
286 } while (errno == EINTR);
288 vm_abort("sem_init failed: %s", strerror(errno));
292 /* threads_sem_wait ************************************************************
294 Wait for a semaphore, non-interruptible.
296 IMPORTANT: Always use this function instead of `sem_wait` directly, as
297 `sem_wait` may be interrupted by signals!
300 sem..............the semaphore to wait on
302 *******************************************************************************/
304 void threads_sem_wait(sem_t *sem)
314 } while (errno == EINTR);
316 vm_abort("sem_wait failed: %s", strerror(errno));
320 /* threads_sem_post ************************************************************
322 Increase the count of a semaphore. Checks for errors.
325 sem..............the semaphore to increase the count of
327 *******************************************************************************/
329 void threads_sem_post(sem_t *sem)
335 /* unlike sem_wait, sem_post is not interruptible */
341 vm_abort("sem_post failed: %s", strerror(errno));
345 /* lock_stopworld **************************************************************
347 Enter the stopworld lock, specifying why the world shall be stopped.
350 where........ STOPWORLD_FROM_GC (1) from within GC
351 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
353 ******************************************************************************/
355 void lock_stopworld(int where)
357 pthread_mutex_lock(&stopworldlock);
358 /* stopworldwhere = where; */
362 /* unlock_stopworld ************************************************************
364 Release the stopworld lock.
366 ******************************************************************************/
368 void unlock_stopworld(void)
370 /* stopworldwhere = 0; */
371 pthread_mutex_unlock(&stopworldlock);
374 /* XXX We disable that whole bunch of code until we have the exact-GC
379 #if !defined(__DARWIN__)
380 /* Caller must hold threadlistlock */
381 static s4 threads_cast_sendsignals(s4 sig)
389 /* iterate over all started threads */
393 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
394 /* don't send the signal to ourself */
399 /* don't send the signal to NEW threads (because they are not
400 completely initialized) */
402 if (t->state == THREAD_STATE_NEW)
405 /* send the signal */
407 pthread_kill(t->tid, sig);
409 /* increase threads count */
419 static void threads_cast_darwinstop(void)
421 threadobject *tobj = mainthreadobj;
422 threadobject *self = THREADOBJECT;
427 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
428 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
429 #if defined(__I386__)
430 i386_thread_state_t thread_state;
432 ppc_thread_state_t thread_state;
434 mach_port_t thread = tobj->mach_thread;
437 r = thread_suspend(thread);
439 if (r != KERN_SUCCESS)
440 vm_abort("thread_suspend failed");
442 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
443 &thread_state_count);
445 if (r != KERN_SUCCESS)
446 vm_abort("thread_get_state failed");
448 md_critical_section_restart((ucontext_t *) &thread_state);
450 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
453 if (r != KERN_SUCCESS)
454 vm_abort("thread_set_state failed");
458 } while (tobj != mainthreadobj);
461 static void threads_cast_darwinresume(void)
463 threadobject *tobj = mainthreadobj;
464 threadobject *self = THREADOBJECT;
469 mach_port_t thread = tobj->mach_thread;
472 r = thread_resume(thread);
474 if (r != KERN_SUCCESS)
475 vm_abort("thread_resume failed");
479 } while (tobj != mainthreadobj);
484 #if defined(__IRIX__)
485 static void threads_cast_irixresume(void)
487 pthread_mutex_lock(&suspend_ack_lock);
488 pthread_cond_broadcast(&suspend_cond);
489 pthread_mutex_unlock(&suspend_ack_lock);
493 #if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
494 static void threads_sigsuspend_handler(ucontext_t *_uc)
499 /* XXX TWISTI: this is just a quick hack */
500 #if defined(ENABLE_JIT)
501 md_critical_section_restart(_uc);
504 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
505 (not POSIX async-safe). */
506 #if defined(__IRIX__)
507 pthread_mutex_lock(&suspend_ack_lock);
508 threads_sem_post(&suspend_ack);
509 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
510 pthread_mutex_unlock(&suspend_ack_lock);
511 #elif defined(__CYGWIN__)
518 sigdelset(&sigs, sig);
527 /* threads_stopworld ***********************************************************
529 Stops the world from turning. All threads except the calling one
530 are suspended. The function returns as soon as all threads have
531 acknowledged their suspension.
533 *******************************************************************************/
535 #if !defined(DISABLE_GC)
536 void threads_stopworld(void)
538 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
545 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
547 /* lock the threads lists */
551 #if defined(__DARWIN__)
552 /*threads_cast_darwinstop();*/
554 #elif defined(__CYGWIN__)
560 DEBUGTHREADS("stops World", self);
564 /* suspend all running threads */
565 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
566 /* don't send the signal to ourself */
571 /* don't send the signal to NEW threads (because they are not
572 completely initialized) */
574 if (t->state == THREAD_STATE_NEW)
577 /* send the signal */
579 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
582 /* increase threads count */
587 /* wait for all threads signaled to suspend */
588 for (i = 0; i < count; i++)
589 threads_sem_wait(&suspend_ack);
592 /* ATTENTION: Don't unlock the threads-lists here so that
593 non-signaled NEW threads can't change their state and execute
596 #endif /* !defined(DISABLE_GC) */
599 /* threads_startworld **********************************************************
601 Starts the world again after it has previously been stopped.
603 *******************************************************************************/
605 #if !defined(DISABLE_GC)
606 void threads_startworld(void)
608 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
615 #if defined(__DARWIN__)
616 /*threads_cast_darwinresume();*/
618 #elif defined(__IRIX__)
619 threads_cast_irixresume();
620 #elif defined(__CYGWIN__)
626 DEBUGTHREADS("starts World", self);
630 /* resume all thread we haltet */
631 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
632 /* don't send the signal to ourself */
637 /* don't send the signal to NEW threads (because they are not
638 completely initialized) */
640 if (t->state == THREAD_STATE_NEW)
643 /* send the signal */
645 result = threads_resume_thread(t);
648 /* increase threads count */
653 /* wait for all threads signaled to suspend */
654 for (i = 0; i < count; i++)
655 threads_sem_wait(&suspend_ack);
659 /* unlock the threads lists */
668 /* threads_impl_thread_init ****************************************************
670 Initialize OS-level locking constructs in threadobject.
673 t....the threadobject
675 *******************************************************************************/
677 void threads_impl_thread_init(threadobject *t)
681 /* initialize the mutex and the condition */
683 result = pthread_mutex_init(&t->flc_lock, NULL);
685 vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
687 result = pthread_cond_init(&t->flc_cond, NULL);
689 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
691 result = pthread_mutex_init(&(t->waitmutex), NULL);
693 vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
695 result = pthread_cond_init(&(t->waitcond), NULL);
697 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
699 result = pthread_mutex_init(&(t->suspendmutex), NULL);
701 vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
703 result = pthread_cond_init(&(t->suspendcond), NULL);
705 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
708 /* threads_impl_thread_clear ***************************************************
710 Clears all fields in threadobject the way an MZERO would have
711 done. MZERO cannot be used anymore because it would mess up the
715 t....the threadobject
717 *******************************************************************************/
719 void threads_impl_thread_clear(threadobject *t)
731 #if defined(__DARWIN__)
735 t->interrupted = false;
739 t->suspended = false;
740 t->suspend_reason = 0;
744 t->_exceptionptr = NULL;
745 t->_stackframeinfo = NULL;
746 t->_localref_table = NULL;
748 #if defined(ENABLE_INTRP)
749 t->_global_sp = NULL;
752 #if defined(ENABLE_GC_CACAO)
753 t->gc_critical = false;
759 MZERO(&t->dumpinfo, dumpinfo_t, 1);
762 /* threads_impl_thread_reuse ***************************************************
764 Resets some implementation fields in threadobject. This was
765 previously done in threads_impl_thread_new.
768 t....the threadobject
770 *******************************************************************************/
772 void threads_impl_thread_reuse(threadobject *t)
774 /* get the pthread id */
776 t->tid = pthread_self();
778 #if defined(ENABLE_DEBUG_FILTER)
779 /* Initialize filter counters */
780 t->filterverbosecallctr[0] = 0;
781 t->filterverbosecallctr[1] = 0;
785 t->tracejavacallindent = 0;
786 t->tracejavacallcount = 0;
793 /* not really needed */
794 t->flc_object = NULL;
798 /* threads_impl_thread_free ****************************************************
800 Cleanup thread stuff.
803 t....the threadobject
805 *******************************************************************************/
809 void threads_impl_thread_free(threadobject *t)
813 /* Destroy the mutex and the condition. */
815 result = pthread_mutex_destroy(&(t->flc_lock));
818 vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
820 result = pthread_cond_destroy(&(t->flc_cond));
823 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
825 result = pthread_mutex_destroy(&(t->waitmutex));
828 vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
830 result = pthread_cond_destroy(&(t->waitcond));
833 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
835 result = pthread_mutex_destroy(&(t->suspendmutex));
838 vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
840 result = pthread_cond_destroy(&(t->suspendcond));
843 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
848 /* threads_impl_preinit ********************************************************
850 Do some early initialization of stuff required.
852 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
853 is called AFTER this function!
855 *******************************************************************************/
857 void threads_impl_preinit(void)
861 result = pthread_mutex_init(&stopworldlock, NULL);
863 vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
865 /* initialize exit mutex and condition (on exit we join all
868 result = pthread_mutex_init(&mutex_join, NULL);
870 vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
872 result = pthread_cond_init(&cond_join, NULL);
874 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
876 #if defined(ENABLE_GC_CACAO)
877 /* initialize the GC mutext */
879 result = pthread_mutex_init(&mutex_gc, NULL);
881 vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
884 #if !defined(HAVE___THREAD)
885 result = pthread_key_create(&thread_current_key, NULL);
887 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
890 threads_sem_init(&suspend_ack, 0, 0);
894 /* threads_mutex_gc_lock *******************************************************
896 Enter the global GC mutex.
898 *******************************************************************************/
900 #if defined(ENABLE_GC_CACAO)
901 void threads_mutex_gc_lock(void)
905 result = pthread_mutex_lock(&mutex_gc);
908 vm_abort_errnum(result, "threads_mutex_gc_lock: pthread_mutex_lock failed");
913 /* threads_mutex_gc_unlock *****************************************************
915 Leave the global GC mutex.
917 *******************************************************************************/
919 #if defined(ENABLE_GC_CACAO)
920 void threads_mutex_gc_unlock(void)
924 result = pthread_mutex_unlock(&mutex_gc);
927 vm_abort_errnum(result, "threads_mutex_gc_unlock: pthread_mutex_unlock failed");
931 /* threads_mutex_join_lock *****************************************************
933 Enter the join mutex.
935 *******************************************************************************/
937 void threads_mutex_join_lock(void)
941 result = pthread_mutex_lock(&mutex_join);
944 vm_abort_errnum(result, "threads_mutex_join_lock: pthread_mutex_lock failed");
948 /* threads_mutex_join_unlock ***************************************************
950 Leave the join mutex.
952 *******************************************************************************/
954 void threads_mutex_join_unlock(void)
958 result = pthread_mutex_unlock(&mutex_join);
961 vm_abort_errnum(result, "threads_mutex_join_unlock: pthread_mutex_unlock failed");
965 /* threads_impl_init ***********************************************************
967 Initializes the implementation specific bits.
969 *******************************************************************************/
971 void threads_impl_init(void)
976 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
978 /* Initialize the thread attribute object. */
980 result = pthread_attr_init(&attr);
983 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
985 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
988 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
992 /* threads_startup_thread ******************************************************
994 Thread startup function called by pthread_create.
996 Thread which have a startup.function != NULL are marked as internal
997 threads. All other threads are threated as normal Java threads.
999 NOTE: This function is not called directly by pthread_create. The Boehm GC
1000 inserts its own GC_start_routine in between, which then calls
1004 arg..........the argument passed to pthread_create, ie. a pointer to
1005 a startupinfo struct. CAUTION: When the `psem` semaphore
1006 is posted, the startupinfo struct becomes invalid! (It
1007 is allocated on the stack of threads_start_thread.)
1009 ******************************************************************************/
1011 static void *threads_startup_thread(void *arg)
1013 startupinfo *startup;
1014 threadobject *thread;
1015 java_lang_Thread *object;
1016 #if defined(WITH_CLASSPATH_GNU)
1017 java_lang_VMThread *vmt;
1023 functionptr function;
1025 #if defined(ENABLE_INTRP)
1026 u1 *intrp_thread_stack;
1028 /* create interpreter stack */
1031 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1032 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1035 intrp_thread_stack = NULL;
1038 /* get passed startupinfo structure and the values in there */
1042 thread = startup->thread;
1043 function = startup->function;
1044 psem = startup->psem;
1046 /* Seems like we've encountered a situation where thread->tid was
1047 not set by pthread_create. We alleviate this problem by waiting
1048 for pthread_create to return. */
1050 threads_sem_wait(startup->psem_first);
1052 #if defined(__DARWIN__)
1053 thread->mach_thread = mach_thread_self();
1056 /* Store the internal thread data-structure in the TSD. */
1058 thread_set_current(thread);
1060 /* get the java.lang.Thread object for this thread */
1062 object = (java_lang_Thread *) thread_get_object(thread);
1064 /* set our priority */
1066 threads_set_thread_priority(thread->tid, LLNI_field_direct(object, priority));
1068 /* thread is completely initialized */
1070 threads_thread_state_runnable(thread);
1072 /* tell threads_startup_thread that we registered ourselves */
1073 /* CAUTION: *startup becomes invalid with this! */
1076 threads_sem_post(psem);
1078 #if defined(ENABLE_INTRP)
1079 /* set interpreter stack */
1082 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1085 #if defined(ENABLE_JVMTI)
1086 /* fire thread start event */
1089 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1092 DEBUGTHREADS("starting", thread);
1094 /* find and run the Thread.run()V method if no other function was passed */
1096 if (function == NULL) {
1097 #if defined(WITH_CLASSPATH_GNU)
1098 /* We need to start the run method of
1099 java.lang.VMThread. Since this is a final class, we can use
1100 the class object directly. */
1102 c = class_java_lang_VMThread;
1103 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1104 LLNI_class_get(object, c);
1106 # error unknown classpath configuration
1109 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1112 vm_abort("threads_startup_thread: run() method not found in class");
1114 /* set ThreadMXBean variables */
1116 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1117 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1119 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1120 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1121 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1122 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1124 #if defined(WITH_CLASSPATH_GNU)
1125 /* we need to start the run method of java.lang.VMThread */
1127 LLNI_field_get_ref(object, vmThread, vmt);
1128 o = (java_handle_t *) vmt;
1130 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1131 o = (java_handle_t *) object;
1133 # error unknown classpath configuration
1136 /* run the thread */
1138 (void) vm_call_method(m, o);
1141 /* set ThreadMXBean variables */
1143 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1144 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1146 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1147 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1148 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1149 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1151 /* call passed function, e.g. finalizer_thread */
1156 DEBUGTHREADS("stopping", thread);
1158 #if defined(ENABLE_JVMTI)
1159 /* fire thread end event */
1162 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1165 /* We ignore the return value. */
1167 (void) threads_detach_thread(thread);
1169 /* set ThreadMXBean variables */
1171 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1177 /* threads_impl_thread_start ***************************************************
1179 Start a thread in the JVM. Both (vm internal and java) thread
1183 thread....the thread object
1184 f.........function to run in the new thread. NULL means that the
1185 "run" method of the object `t` should be called
1187 ******************************************************************************/
1189 void threads_impl_thread_start(threadobject *thread, functionptr f)
1193 pthread_attr_t attr;
1194 startupinfo startup;
1197 /* fill startupinfo structure passed by pthread_create to
1198 * threads_startup_thread */
1200 startup.thread = thread;
1201 startup.function = f; /* maybe we don't call Thread.run()V */
1202 startup.psem = &sem;
1203 startup.psem_first = &sem_first;
1205 threads_sem_init(&sem, 0, 0);
1206 threads_sem_init(&sem_first, 0, 0);
1208 /* Initialize thread attributes. */
1210 result = pthread_attr_init(&attr);
1213 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1215 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1218 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1220 /* initialize thread stacksize */
1222 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1225 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1227 /* create the thread */
1229 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1232 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1234 /* destroy the thread attributes */
1236 result = pthread_attr_destroy(&attr);
1239 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1241 /* signal that pthread_create has returned, so thread->tid is valid */
1243 threads_sem_post(&sem_first);
1245 /* wait here until the thread has entered itself into the thread list */
1247 threads_sem_wait(&sem);
1252 sem_destroy(&sem_first);
1256 /* threads_set_thread_priority *************************************************
1258 Set the priority of the given thread.
1261 tid..........thread id
1262 priority.....priority to set
1264 ******************************************************************************/
1266 void threads_set_thread_priority(pthread_t tid, int priority)
1268 struct sched_param schedp;
1271 pthread_getschedparam(tid, &policy, &schedp);
1272 schedp.sched_priority = priority;
1273 pthread_setschedparam(tid, policy, &schedp);
1277 /* threads_detach_thread *******************************************************
1279 Detaches the passed thread from the VM. Used in JNI.
1281 *******************************************************************************/
1283 bool threads_detach_thread(threadobject *t)
1286 java_lang_Thread *object;
1288 #if defined(ENABLE_JAVASE)
1289 java_lang_ThreadGroup *group;
1296 /* If the given thread has already been detached, this operation
1299 result = thread_is_attached(t);
1301 if (result == false)
1304 DEBUGTHREADS("detaching", t);
1306 object = (java_lang_Thread *) thread_get_object(t);
1308 #if defined(ENABLE_JAVASE)
1309 LLNI_field_get_ref(object, group, group);
1311 /* If there's an uncaught exception, call uncaughtException on the
1312 thread's exception handler, or the thread's group if this is
1315 e = exceptions_get_and_clear_exception();
1318 /* We use the type void* for handler here, as it's not trivial
1319 to build the java_lang_Thread_UncaughtExceptionHandler
1320 header file with cacaoh. */
1322 # if defined(WITH_CLASSPATH_GNU)
1323 LLNI_field_get_ref(object, exceptionHandler, handler);
1324 # elif defined(WITH_CLASSPATH_SUN)
1325 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1328 if (handler != NULL) {
1329 LLNI_class_get(handler, c);
1330 o = (java_handle_t *) handler;
1333 LLNI_class_get(group, c);
1334 o = (java_handle_t *) group;
1337 m = class_resolveclassmethod(c,
1338 utf_uncaughtException,
1339 utf_java_lang_Thread_java_lang_Throwable__V,
1346 (void) vm_call_method(m, o, object, e);
1348 if (exceptions_get_exception())
1352 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1354 /* Remove thread from the thread group. */
1356 if (group != NULL) {
1357 LLNI_class_get(group, c);
1359 # if defined(WITH_CLASSPATH_GNU)
1360 m = class_resolveclassmethod(c,
1362 utf_java_lang_Thread__V,
1363 class_java_lang_ThreadGroup,
1365 # elif defined(WITH_CLASSPATH_SUN)
1366 m = class_resolveclassmethod(c,
1368 utf_java_lang_Thread__V,
1369 class_java_lang_ThreadGroup,
1372 # error unknown classpath configuration
1378 o = (java_handle_t *) group;
1380 (void) vm_call_method(m, o, object);
1382 if (exceptions_get_exception())
1387 /* Thread has terminated. */
1389 threads_thread_state_terminated(t);
1391 /* Notify all threads waiting on this thread. These are joining
1394 o = (java_handle_t *) object;
1396 /* XXX Care about exceptions? */
1397 (void) lock_monitor_enter(o);
1399 lock_notify_all_object(o);
1401 /* XXX Care about exceptions? */
1402 (void) lock_monitor_exit(o);
1404 /* Enter the join-mutex before calling thread_free, so
1405 threads_join_all_threads gets the correct number of non-daemon
1408 threads_mutex_join_lock();
1410 /* Free the internal thread data-structure. */
1414 /* Signal that this thread has finished and leave the mutex. */
1416 pthread_cond_signal(&cond_join);
1417 threads_mutex_join_unlock();
1423 /* threads_suspend_thread ******************************************************
1425 Suspend the passed thread. Execution stops until the thread
1426 is explicitly resumend again.
1429 reason.....Reason for suspending this thread.
1431 *******************************************************************************/
1433 bool threads_suspend_thread(threadobject *thread, s4 reason)
1435 /* acquire the suspendmutex */
1436 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1437 vm_abort("threads_suspend_thread: pthread_mutex_lock failed: %s",
1440 if (thread->suspended) {
1441 pthread_mutex_unlock(&(thread->suspendmutex));
1445 /* set the reason for the suspension */
1446 thread->suspend_reason = reason;
1448 /* send the suspend signal to the thread */
1449 assert(thread != THREADOBJECT);
1450 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1451 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1454 /* REMEMBER: do not release the suspendmutex, this is done
1455 by the thread itself in threads_suspend_ack(). */
1461 /* threads_suspend_ack *********************************************************
1463 Acknowledges the suspension of the current thread.
1466 pc.....The PC where the thread suspended its execution.
1467 sp.....The SP before the thread suspended its execution.
1469 *******************************************************************************/
1471 void threads_suspend_ack(u1* pc, u1* sp)
1473 threadobject *thread;
1475 thread = THREADOBJECT;
1477 assert(thread->suspend_reason != 0);
1479 /* TODO: remember dump memory size */
1481 #if defined(ENABLE_GC_CACAO)
1482 /* inform the GC about the suspension */
1483 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1485 /* check if the GC wants to leave the thread running */
1486 if (!gc_suspend(thread, pc, sp)) {
1488 /* REMEMBER: we do not unlock the suspendmutex because the thread
1489 will suspend itself again at a later time */
1496 /* mark this thread as suspended and remember the PC */
1498 thread->suspended = true;
1500 /* if we are stopping the world, we should send a global ack */
1501 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1502 threads_sem_post(&suspend_ack);
1505 DEBUGTHREADS("suspending", thread);
1507 /* release the suspension mutex and wait till we are resumed */
1508 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1510 DEBUGTHREADS("resuming", thread);
1512 /* if we are stopping the world, we should send a global ack */
1513 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1514 threads_sem_post(&suspend_ack);
1517 /* TODO: free dump memory */
1519 /* release the suspendmutex */
1520 if (pthread_mutex_unlock(&(thread->suspendmutex)) != 0)
1521 vm_abort("threads_suspend_ack: pthread_mutex_unlock failed: %s",
1526 /* threads_resume_thread *******************************************************
1528 Resumes the execution of the passed thread.
1530 *******************************************************************************/
1532 bool threads_resume_thread(threadobject *thread)
1534 /* acquire the suspendmutex */
1535 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1536 vm_abort("threads_resume_ack: pthread_mutex_unlock failed: %s",
1539 if (!thread->suspended) {
1540 pthread_mutex_unlock(&(thread->suspendmutex));
1544 thread->suspended = false;
1546 /* tell everyone that the thread should resume */
1547 assert(thread != THREADOBJECT);
1548 pthread_cond_broadcast(&(thread->suspendcond));
1550 /* release the suspendmutex */
1551 pthread_mutex_unlock(&(thread->suspendmutex));
1557 /* threads_join_all_threads ****************************************************
1559 Join all non-daemon threads.
1561 *******************************************************************************/
1563 void threads_join_all_threads(void)
1567 /* get current thread */
1571 /* this thread is waiting for all non-daemon threads to exit */
1573 threads_thread_state_waiting(t);
1575 /* enter join mutex */
1577 threads_mutex_join_lock();
1579 /* Wait for condition as long as we have non-daemon threads. We
1580 compare against 1 because the current (main thread) is also a
1581 non-daemon thread. */
1583 while (threadlist_get_non_daemons() > 1)
1584 pthread_cond_wait(&cond_join, &mutex_join);
1586 /* leave join mutex */
1588 threads_mutex_join_unlock();
1592 /* threads_timespec_earlier ****************************************************
1594 Return true if timespec tv1 is earlier than timespec tv2.
1597 tv1..........first timespec
1598 tv2..........second timespec
1601 true, if the first timespec is earlier
1603 *******************************************************************************/
1605 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1606 const struct timespec *tv2)
1608 return (tv1->tv_sec < tv2->tv_sec)
1610 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1614 /* threads_current_time_is_earlier_than ****************************************
1616 Check if the current time is earlier than the given timespec.
1619 tv...........the timespec to compare against
1622 true, if the current time is earlier
1624 *******************************************************************************/
1626 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1628 struct timeval tvnow;
1629 struct timespec tsnow;
1631 /* get current time */
1633 if (gettimeofday(&tvnow, NULL) != 0)
1634 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1636 /* convert it to a timespec */
1638 tsnow.tv_sec = tvnow.tv_sec;
1639 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1641 /* compare current time with the given timespec */
1643 return threads_timespec_earlier(&tsnow, tv);
1647 /* threads_wait_with_timeout ***************************************************
1649 Wait until the given point in time on a monitor until either
1650 we are notified, we are interrupted, or the time is up.
1653 t............the current thread
1654 wakeupTime...absolute (latest) wakeup time
1655 If both tv_sec and tv_nsec are zero, this function
1656 waits for an unlimited amount of time.
1658 *******************************************************************************/
1660 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1662 /* acquire the waitmutex */
1664 pthread_mutex_lock(&t->waitmutex);
1666 /* mark us as sleeping */
1670 /* wait on waitcond */
1672 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1674 while (!t->interrupted && !t->signaled
1675 && threads_current_time_is_earlier_than(wakeupTime))
1677 threads_thread_state_timed_waiting(t);
1679 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1682 threads_thread_state_runnable(t);
1687 while (!t->interrupted && !t->signaled) {
1688 threads_thread_state_waiting(t);
1690 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1692 threads_thread_state_runnable(t);
1696 t->sleeping = false;
1698 /* release the waitmutex */
1700 pthread_mutex_unlock(&t->waitmutex);
1704 /* threads_wait_with_timeout_relative ******************************************
1706 Wait for the given maximum amount of time on a monitor until either
1707 we are notified, we are interrupted, or the time is up.
1710 t............the current thread
1711 millis.......milliseconds to wait
1712 nanos........nanoseconds to wait
1714 *******************************************************************************/
1716 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1719 struct timespec wakeupTime;
1721 /* calculate the the (latest) wakeup time */
1723 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1727 threads_wait_with_timeout(thread, &wakeupTime);
1731 /* threads_calc_absolute_time **************************************************
1733 Calculate the absolute point in time a given number of ms and ns from now.
1736 millis............milliseconds from now
1737 nanos.............nanoseconds from now
1740 *tm...............receives the timespec of the absolute point in time
1742 *******************************************************************************/
1744 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1746 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1749 gettimeofday(&tv, NULL);
1750 tv.tv_sec += millis / 1000;
1752 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1753 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1754 tm->tv_nsec = nsec % 1000000000;
1763 /* threads_thread_interrupt ****************************************************
1765 Interrupt the given thread.
1767 The thread gets the "waitcond" signal and
1768 its interrupted flag is set to true.
1771 thread............the thread to interrupt
1773 *******************************************************************************/
1775 void threads_thread_interrupt(threadobject *thread)
1777 /* Signal the thread a "waitcond" and tell it that it has been
1780 pthread_mutex_lock(&thread->waitmutex);
1782 DEBUGTHREADS("interrupted", thread);
1784 /* Interrupt blocking system call using a signal. */
1786 pthread_kill(thread->tid, SIGHUP);
1788 if (thread->sleeping)
1789 pthread_cond_signal(&thread->waitcond);
1791 thread->interrupted = true;
1793 pthread_mutex_unlock(&thread->waitmutex);
1797 /* threads_check_if_interrupted_and_reset **************************************
1799 Check if the current thread has been interrupted and reset the
1803 true, if the current thread had been interrupted
1805 *******************************************************************************/
1807 bool threads_check_if_interrupted_and_reset(void)
1809 threadobject *thread;
1812 thread = THREADOBJECT;
1814 pthread_mutex_lock(&thread->waitmutex);
1816 /* get interrupted flag */
1818 intr = thread->interrupted;
1820 /* reset interrupted flag */
1822 thread->interrupted = false;
1824 pthread_mutex_unlock(&thread->waitmutex);
1830 /* threads_thread_has_been_interrupted *****************************************
1832 Check if the given thread has been interrupted
1835 t............the thread to check
1838 true, if the given thread had been interrupted
1840 *******************************************************************************/
1842 bool threads_thread_has_been_interrupted(threadobject *thread)
1844 return thread->interrupted;
1848 /* threads_sleep ***************************************************************
1850 Sleep the current thread for the specified amount of time.
1852 *******************************************************************************/
1854 void threads_sleep(s8 millis, s4 nanos)
1856 threadobject *thread;
1857 struct timespec wakeupTime;
1858 bool wasinterrupted;
1860 thread = THREADOBJECT;
1862 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1864 threads_wait_with_timeout(thread, &wakeupTime);
1866 wasinterrupted = threads_check_if_interrupted_and_reset();
1869 exceptions_throw_interruptedexception();
1873 /* threads_yield ***************************************************************
1875 Yield to the scheduler.
1877 *******************************************************************************/
1879 void threads_yield(void)
1886 * These are local overrides for various environment variables in Emacs.
1887 * Please do not remove this and leave it at the end of the file, where
1888 * Emacs will automagically detect them.
1889 * ---------------------------------------------------------------------
1892 * indent-tabs-mode: t
1896 * vim:noexpandtab:sw=4:ts=4: