1 /* src/threads/posix/threads.c - native threads support
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/threads-common.h"
80 #include "threads/posix/threads.h"
82 #include "toolbox/logging.h"
84 #include "vm/builtin.h"
85 #include "vm/exceptions.h"
86 #include "vm/global.h"
87 #include "vm/stringlocal.h"
90 #include "vm/jit/asmpart.h"
92 #include "vmcore/options.h"
94 #if defined(ENABLE_STATISTICS)
95 # include "vmcore/statistics.h"
98 #if !defined(__DARWIN__)
99 # if defined(__LINUX__)
100 # define GC_LINUX_THREADS
101 # elif defined(__IRIX__)
102 # define GC_IRIX_THREADS
104 # include <semaphore.h>
105 # if defined(ENABLE_GC_BOEHM)
106 # include "mm/boehm-gc/include/gc.h"
110 #if defined(ENABLE_JVMTI)
111 #include "native/jvmti/cacaodbg.h"
114 #if defined(__DARWIN__)
115 /* Darwin has no working semaphore implementation. This one is taken
119 This is a very simple semaphore implementation for darwin. It
120 is implemented in terms of pthreads calls so it isn't async signal
121 safe. This isn't a problem because signals aren't used to
122 suspend threads on darwin.
125 static int sem_init(sem_t *sem, int pshared, int value)
132 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
135 if (pthread_cond_init(&sem->cond, NULL) < 0)
141 static int sem_post(sem_t *sem)
143 if (pthread_mutex_lock(&sem->mutex) < 0)
148 if (pthread_cond_signal(&sem->cond) < 0) {
149 pthread_mutex_unlock(&sem->mutex);
153 if (pthread_mutex_unlock(&sem->mutex) < 0)
159 static int sem_wait(sem_t *sem)
161 if (pthread_mutex_lock(&sem->mutex) < 0)
164 while (sem->value == 0) {
165 pthread_cond_wait(&sem->cond, &sem->mutex);
170 if (pthread_mutex_unlock(&sem->mutex) < 0)
176 static int sem_destroy(sem_t *sem)
178 if (pthread_cond_destroy(&sem->cond) < 0)
181 if (pthread_mutex_destroy(&sem->mutex) < 0)
186 #endif /* defined(__DARWIN__) */
189 /* internally used constants **************************************************/
191 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
192 #define STOPWORLD_FROM_GC 1
193 #define STOPWORLD_FROM_CLASS_NUMBERING 2
196 /* startupinfo *****************************************************************
198 Struct used to pass info from threads_start_thread to
199 threads_startup_thread.
201 ******************************************************************************/
204 threadobject *thread; /* threadobject for this thread */
205 functionptr function; /* function to run in the new thread */
206 sem_t *psem; /* signals when thread has been entered */
207 /* in the thread list */
208 sem_t *psem_first; /* signals when pthread_create has returned */
212 /* prototypes *****************************************************************/
214 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
217 /******************************************************************************/
218 /* GLOBAL VARIABLES */
219 /******************************************************************************/
221 /* the thread object of the current thread */
222 /* This is either a thread-local variable defined with __thread, or */
223 /* a thread-specific value stored with key threads_current_threadobject_key. */
224 #if defined(HAVE___THREAD)
225 __thread threadobject *thread_current;
227 pthread_key_t thread_current_key;
230 /* global mutex for stop-the-world */
231 static pthread_mutex_t stopworldlock;
233 #if defined(ENABLE_GC_CACAO)
234 /* global mutex for the GC */
235 static pthread_mutex_t mutex_gc;
238 /* global mutex and condition for joining threads on exit */
239 static pthread_mutex_t mutex_join;
240 static pthread_cond_t cond_join;
242 /* XXX We disable that whole bunch of code until we have the exact-GC
247 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
249 static volatile int stopworldwhere;
251 /* semaphore used for acknowleding thread suspension */
252 static sem_t suspend_ack;
253 #if defined(__IRIX__)
254 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
255 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
260 /* mutexes used by the fake atomic instructions */
261 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
262 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
263 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
267 /* threads_sem_init ************************************************************
269 Initialize a semaphore. Checks against errors and interruptions.
272 sem..............the semaphore to initialize
273 shared...........true if this semaphore will be shared between processes
274 value............the initial value for the semaphore
276 *******************************************************************************/
278 void threads_sem_init(sem_t *sem, bool shared, int value)
285 r = sem_init(sem, shared, value);
288 } while (errno == EINTR);
290 vm_abort("sem_init failed: %s", strerror(errno));
294 /* threads_sem_wait ************************************************************
296 Wait for a semaphore, non-interruptible.
298 IMPORTANT: Always use this function instead of `sem_wait` directly, as
299 `sem_wait` may be interrupted by signals!
302 sem..............the semaphore to wait on
304 *******************************************************************************/
306 void threads_sem_wait(sem_t *sem)
316 } while (errno == EINTR);
318 vm_abort("sem_wait failed: %s", strerror(errno));
322 /* threads_sem_post ************************************************************
324 Increase the count of a semaphore. Checks for errors.
327 sem..............the semaphore to increase the count of
329 *******************************************************************************/
331 void threads_sem_post(sem_t *sem)
337 /* unlike sem_wait, sem_post is not interruptible */
343 vm_abort("sem_post failed: %s", strerror(errno));
347 /* lock_stopworld **************************************************************
349 Enter the stopworld lock, specifying why the world shall be stopped.
352 where........ STOPWORLD_FROM_GC (1) from within GC
353 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
355 ******************************************************************************/
357 void lock_stopworld(int where)
359 pthread_mutex_lock(&stopworldlock);
360 /* stopworldwhere = where; */
364 /* unlock_stopworld ************************************************************
366 Release the stopworld lock.
368 ******************************************************************************/
370 void unlock_stopworld(void)
372 /* stopworldwhere = 0; */
373 pthread_mutex_unlock(&stopworldlock);
376 /* XXX We disable that whole bunch of code until we have the exact-GC
381 #if !defined(__DARWIN__)
382 /* Caller must hold threadlistlock */
383 static s4 threads_cast_sendsignals(s4 sig)
391 /* iterate over all started threads */
395 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
396 /* don't send the signal to ourself */
401 /* don't send the signal to NEW threads (because they are not
402 completely initialized) */
404 if (t->state == THREAD_STATE_NEW)
407 /* send the signal */
409 pthread_kill(t->tid, sig);
411 /* increase threads count */
421 static void threads_cast_darwinstop(void)
423 threadobject *tobj = mainthreadobj;
424 threadobject *self = THREADOBJECT;
429 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
430 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
431 #if defined(__I386__)
432 i386_thread_state_t thread_state;
434 ppc_thread_state_t thread_state;
436 mach_port_t thread = tobj->mach_thread;
439 r = thread_suspend(thread);
441 if (r != KERN_SUCCESS)
442 vm_abort("thread_suspend failed");
444 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
445 &thread_state_count);
447 if (r != KERN_SUCCESS)
448 vm_abort("thread_get_state failed");
450 md_critical_section_restart((ucontext_t *) &thread_state);
452 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
455 if (r != KERN_SUCCESS)
456 vm_abort("thread_set_state failed");
460 } while (tobj != mainthreadobj);
463 static void threads_cast_darwinresume(void)
465 threadobject *tobj = mainthreadobj;
466 threadobject *self = THREADOBJECT;
471 mach_port_t thread = tobj->mach_thread;
474 r = thread_resume(thread);
476 if (r != KERN_SUCCESS)
477 vm_abort("thread_resume failed");
481 } while (tobj != mainthreadobj);
486 #if defined(__IRIX__)
487 static void threads_cast_irixresume(void)
489 pthread_mutex_lock(&suspend_ack_lock);
490 pthread_cond_broadcast(&suspend_cond);
491 pthread_mutex_unlock(&suspend_ack_lock);
495 #if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
496 static void threads_sigsuspend_handler(ucontext_t *_uc)
501 /* XXX TWISTI: this is just a quick hack */
502 #if defined(ENABLE_JIT)
503 md_critical_section_restart(_uc);
506 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
507 (not POSIX async-safe). */
508 #if defined(__IRIX__)
509 pthread_mutex_lock(&suspend_ack_lock);
510 threads_sem_post(&suspend_ack);
511 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
512 pthread_mutex_unlock(&suspend_ack_lock);
513 #elif defined(__CYGWIN__)
520 sigdelset(&sigs, sig);
529 /* threads_stopworld ***********************************************************
531 Stops the world from turning. All threads except the calling one
532 are suspended. The function returns as soon as all threads have
533 acknowledged their suspension.
535 *******************************************************************************/
537 #if !defined(DISABLE_GC)
538 void threads_stopworld(void)
540 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
547 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
549 /* lock the threads lists */
553 #if defined(__DARWIN__)
554 /*threads_cast_darwinstop();*/
556 #elif defined(__CYGWIN__)
562 DEBUGTHREADS("stops World", self);
566 /* suspend all running threads */
567 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
568 /* don't send the signal to ourself */
573 /* don't send the signal to NEW threads (because they are not
574 completely initialized) */
576 if (t->state == THREAD_STATE_NEW)
579 /* send the signal */
581 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
584 /* increase threads count */
589 /* wait for all threads signaled to suspend */
590 for (i = 0; i < count; i++)
591 threads_sem_wait(&suspend_ack);
594 /* ATTENTION: Don't unlock the threads-lists here so that
595 non-signaled NEW threads can't change their state and execute
598 #endif /* !defined(DISABLE_GC) */
601 /* threads_startworld **********************************************************
603 Starts the world again after it has previously been stopped.
605 *******************************************************************************/
607 #if !defined(DISABLE_GC)
608 void threads_startworld(void)
610 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
617 #if defined(__DARWIN__)
618 /*threads_cast_darwinresume();*/
620 #elif defined(__IRIX__)
621 threads_cast_irixresume();
622 #elif defined(__CYGWIN__)
628 DEBUGTHREADS("starts World", self);
632 /* resume all thread we haltet */
633 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
634 /* don't send the signal to ourself */
639 /* don't send the signal to NEW threads (because they are not
640 completely initialized) */
642 if (t->state == THREAD_STATE_NEW)
645 /* send the signal */
647 result = threads_resume_thread(t);
650 /* increase threads count */
655 /* wait for all threads signaled to suspend */
656 for (i = 0; i < count; i++)
657 threads_sem_wait(&suspend_ack);
661 /* unlock the threads lists */
670 /* threads_impl_thread_init ****************************************************
672 Initialize OS-level locking constructs in threadobject.
675 t....the threadobject
677 *******************************************************************************/
679 void threads_impl_thread_init(threadobject *t)
683 /* initialize the mutex and the condition */
685 result = pthread_mutex_init(&t->flc_lock, NULL);
687 vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
689 result = pthread_cond_init(&t->flc_cond, NULL);
691 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
693 result = pthread_mutex_init(&(t->waitmutex), NULL);
695 vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
697 result = pthread_cond_init(&(t->waitcond), NULL);
699 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
701 result = pthread_mutex_init(&(t->suspendmutex), NULL);
703 vm_abort_errnum(result, "threads_impl_thread_new: pthread_mutex_init failed");
705 result = pthread_cond_init(&(t->suspendcond), NULL);
707 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
710 /* threads_impl_thread_clear ***************************************************
712 Clears all fields in threadobject the way an MZERO would have
713 done. MZERO cannot be used anymore because it would mess up the
717 t....the threadobject
719 *******************************************************************************/
721 void threads_impl_thread_clear(threadobject *t)
733 #if defined(__DARWIN__)
737 t->interrupted = false;
741 t->suspended = false;
742 t->suspend_reason = 0;
746 t->_exceptionptr = NULL;
747 t->_stackframeinfo = NULL;
748 t->_localref_table = NULL;
750 #if defined(ENABLE_INTRP)
751 t->_global_sp = NULL;
754 #if defined(ENABLE_GC_CACAO)
755 t->gc_critical = false;
761 MZERO(&t->dumpinfo, dumpinfo_t, 1);
764 /* threads_impl_thread_reuse ***************************************************
766 Resets some implementation fields in threadobject. This was
767 previously done in threads_impl_thread_new.
770 t....the threadobject
772 *******************************************************************************/
774 void threads_impl_thread_reuse(threadobject *t)
776 /* get the pthread id */
778 t->tid = pthread_self();
780 #if defined(ENABLE_DEBUG_FILTER)
781 /* Initialize filter counters */
782 t->filterverbosecallctr[0] = 0;
783 t->filterverbosecallctr[1] = 0;
787 t->tracejavacallindent = 0;
788 t->tracejavacallcount = 0;
795 /* not really needed */
796 t->flc_object = NULL;
800 /* threads_impl_thread_free ****************************************************
802 Cleanup thread stuff.
805 t....the threadobject
807 *******************************************************************************/
811 void threads_impl_thread_free(threadobject *t)
815 /* Destroy the mutex and the condition. */
817 result = pthread_mutex_destroy(&(t->flc_lock));
820 vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
822 result = pthread_cond_destroy(&(t->flc_cond));
825 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
827 result = pthread_mutex_destroy(&(t->waitmutex));
830 vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
832 result = pthread_cond_destroy(&(t->waitcond));
835 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
837 result = pthread_mutex_destroy(&(t->suspendmutex));
840 vm_abort_errnum(result, "threads_impl_thread_free: pthread_mutex_destroy failed");
842 result = pthread_cond_destroy(&(t->suspendcond));
845 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
850 /* threads_impl_preinit ********************************************************
852 Do some early initialization of stuff required.
854 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
855 is called AFTER this function!
857 *******************************************************************************/
859 void threads_impl_preinit(void)
863 result = pthread_mutex_init(&stopworldlock, NULL);
865 vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
867 /* initialize exit mutex and condition (on exit we join all
870 result = pthread_mutex_init(&mutex_join, NULL);
872 vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
874 result = pthread_cond_init(&cond_join, NULL);
876 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
878 #if defined(ENABLE_GC_CACAO)
879 /* initialize the GC mutext */
881 result = pthread_mutex_init(&mutex_gc, NULL);
883 vm_abort_errnum(result, "threads_impl_preinit: pthread_mutex_init failed");
886 #if !defined(HAVE___THREAD)
887 result = pthread_key_create(&thread_current_key, NULL);
889 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
892 threads_sem_init(&suspend_ack, 0, 0);
896 /* threads_mutex_gc_lock *******************************************************
898 Enter the global GC mutex.
900 *******************************************************************************/
902 #if defined(ENABLE_GC_CACAO)
903 void threads_mutex_gc_lock(void)
907 result = pthread_mutex_lock(&mutex_gc);
910 vm_abort_errnum(result, "threads_mutex_gc_lock: pthread_mutex_lock failed");
915 /* threads_mutex_gc_unlock *****************************************************
917 Leave the global GC mutex.
919 *******************************************************************************/
921 #if defined(ENABLE_GC_CACAO)
922 void threads_mutex_gc_unlock(void)
926 result = pthread_mutex_unlock(&mutex_gc);
929 vm_abort_errnum(result, "threads_mutex_gc_unlock: pthread_mutex_unlock failed");
933 /* threads_mutex_join_lock *****************************************************
935 Enter the join mutex.
937 *******************************************************************************/
939 void threads_mutex_join_lock(void)
943 result = pthread_mutex_lock(&mutex_join);
946 vm_abort_errnum(result, "threads_mutex_join_lock: pthread_mutex_lock failed");
950 /* threads_mutex_join_unlock ***************************************************
952 Leave the join mutex.
954 *******************************************************************************/
956 void threads_mutex_join_unlock(void)
960 result = pthread_mutex_unlock(&mutex_join);
963 vm_abort_errnum(result, "threads_mutex_join_unlock: pthread_mutex_unlock failed");
967 /* threads_impl_init ***********************************************************
969 Initializes the implementation specific bits.
971 *******************************************************************************/
973 void threads_impl_init(void)
978 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
980 /* Initialize the thread attribute object. */
982 result = pthread_attr_init(&attr);
985 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
987 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
990 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
994 /* threads_startup_thread ******************************************************
996 Thread startup function called by pthread_create.
998 Thread which have a startup.function != NULL are marked as internal
999 threads. All other threads are threated as normal Java threads.
1001 NOTE: This function is not called directly by pthread_create. The Boehm GC
1002 inserts its own GC_start_routine in between, which then calls
1006 arg..........the argument passed to pthread_create, ie. a pointer to
1007 a startupinfo struct. CAUTION: When the `psem` semaphore
1008 is posted, the startupinfo struct becomes invalid! (It
1009 is allocated on the stack of threads_start_thread.)
1011 ******************************************************************************/
1013 static void *threads_startup_thread(void *arg)
1015 startupinfo *startup;
1016 threadobject *thread;
1017 java_lang_Thread *object;
1018 #if defined(WITH_CLASSPATH_GNU)
1019 java_lang_VMThread *vmt;
1025 functionptr function;
1027 #if defined(ENABLE_INTRP)
1028 u1 *intrp_thread_stack;
1030 /* create interpreter stack */
1033 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1034 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1037 intrp_thread_stack = NULL;
1040 /* get passed startupinfo structure and the values in there */
1044 thread = startup->thread;
1045 function = startup->function;
1046 psem = startup->psem;
1048 /* Seems like we've encountered a situation where thread->tid was
1049 not set by pthread_create. We alleviate this problem by waiting
1050 for pthread_create to return. */
1052 threads_sem_wait(startup->psem_first);
1054 #if defined(__DARWIN__)
1055 thread->mach_thread = mach_thread_self();
1058 /* Store the internal thread data-structure in the TSD. */
1060 thread_set_current(thread);
1062 /* get the java.lang.Thread object for this thread */
1064 object = (java_lang_Thread *) threads_thread_get_object(thread);
1066 /* set our priority */
1068 threads_set_thread_priority(thread->tid, LLNI_field_direct(object, priority));
1070 /* thread is completely initialized */
1072 threads_thread_state_runnable(thread);
1074 /* tell threads_startup_thread that we registered ourselves */
1075 /* CAUTION: *startup becomes invalid with this! */
1078 threads_sem_post(psem);
1080 #if defined(ENABLE_INTRP)
1081 /* set interpreter stack */
1084 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1087 #if defined(ENABLE_JVMTI)
1088 /* fire thread start event */
1091 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1094 DEBUGTHREADS("starting", thread);
1096 /* find and run the Thread.run()V method if no other function was passed */
1098 if (function == NULL) {
1099 #if defined(WITH_CLASSPATH_GNU)
1100 /* We need to start the run method of
1101 java.lang.VMThread. Since this is a final class, we can use
1102 the class object directly. */
1104 c = class_java_lang_VMThread;
1105 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1106 LLNI_class_get(object, c);
1108 # error unknown classpath configuration
1111 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1114 vm_abort("threads_startup_thread: run() method not found in class");
1116 /* set ThreadMXBean variables */
1118 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1119 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1121 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1122 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1123 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1124 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1126 #if defined(WITH_CLASSPATH_GNU)
1127 /* we need to start the run method of java.lang.VMThread */
1129 LLNI_field_get_ref(object, vmThread, vmt);
1130 o = (java_handle_t *) vmt;
1132 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1133 o = (java_handle_t *) object;
1135 # error unknown classpath configuration
1138 /* run the thread */
1140 (void) vm_call_method(m, o);
1143 /* set ThreadMXBean variables */
1145 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1146 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1148 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1149 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1150 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1151 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1153 /* call passed function, e.g. finalizer_thread */
1158 DEBUGTHREADS("stopping", thread);
1160 #if defined(ENABLE_JVMTI)
1161 /* fire thread end event */
1164 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1167 /* We ignore the return value. */
1169 (void) threads_detach_thread(thread);
1171 /* set ThreadMXBean variables */
1173 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1179 /* threads_impl_thread_start ***************************************************
1181 Start a thread in the JVM. Both (vm internal and java) thread
1185 thread....the thread object
1186 f.........function to run in the new thread. NULL means that the
1187 "run" method of the object `t` should be called
1189 ******************************************************************************/
1191 void threads_impl_thread_start(threadobject *thread, functionptr f)
1195 pthread_attr_t attr;
1196 startupinfo startup;
1199 /* fill startupinfo structure passed by pthread_create to
1200 * threads_startup_thread */
1202 startup.thread = thread;
1203 startup.function = f; /* maybe we don't call Thread.run()V */
1204 startup.psem = &sem;
1205 startup.psem_first = &sem_first;
1207 threads_sem_init(&sem, 0, 0);
1208 threads_sem_init(&sem_first, 0, 0);
1210 /* Initialize thread attributes. */
1212 result = pthread_attr_init(&attr);
1215 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1217 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1220 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1222 /* initialize thread stacksize */
1224 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1227 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1229 /* create the thread */
1231 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1234 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1236 /* destroy the thread attributes */
1238 result = pthread_attr_destroy(&attr);
1241 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1243 /* signal that pthread_create has returned, so thread->tid is valid */
1245 threads_sem_post(&sem_first);
1247 /* wait here until the thread has entered itself into the thread list */
1249 threads_sem_wait(&sem);
1254 sem_destroy(&sem_first);
1258 /* threads_set_thread_priority *************************************************
1260 Set the priority of the given thread.
1263 tid..........thread id
1264 priority.....priority to set
1266 ******************************************************************************/
1268 void threads_set_thread_priority(pthread_t tid, int priority)
1270 struct sched_param schedp;
1273 pthread_getschedparam(tid, &policy, &schedp);
1274 schedp.sched_priority = priority;
1275 pthread_setschedparam(tid, policy, &schedp);
1279 /* threads_detach_thread *******************************************************
1281 Detaches the passed thread from the VM. Used in JNI.
1283 *******************************************************************************/
1285 bool threads_detach_thread(threadobject *t)
1288 java_lang_Thread *object;
1290 #if defined(ENABLE_JAVASE)
1291 java_lang_ThreadGroup *group;
1298 /* If the given thread has already been detached, this operation
1301 result = thread_is_attached(t);
1303 if (result == false)
1306 DEBUGTHREADS("detaching", t);
1308 object = (java_lang_Thread *) threads_thread_get_object(t);
1310 #if defined(ENABLE_JAVASE)
1311 LLNI_field_get_ref(object, group, group);
1313 /* If there's an uncaught exception, call uncaughtException on the
1314 thread's exception handler, or the thread's group if this is
1317 e = exceptions_get_and_clear_exception();
1320 /* We use the type void* for handler here, as it's not trivial
1321 to build the java_lang_Thread_UncaughtExceptionHandler
1322 header file with cacaoh. */
1324 # if defined(WITH_CLASSPATH_GNU)
1325 LLNI_field_get_ref(object, exceptionHandler, handler);
1326 # elif defined(WITH_CLASSPATH_SUN)
1327 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1330 if (handler != NULL) {
1331 LLNI_class_get(handler, c);
1332 o = (java_handle_t *) handler;
1335 LLNI_class_get(group, c);
1336 o = (java_handle_t *) group;
1339 m = class_resolveclassmethod(c,
1340 utf_uncaughtException,
1341 utf_java_lang_Thread_java_lang_Throwable__V,
1348 (void) vm_call_method(m, o, object, e);
1350 if (exceptions_get_exception())
1354 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1356 /* Remove thread from the thread group. */
1358 if (group != NULL) {
1359 LLNI_class_get(group, c);
1361 # if defined(WITH_CLASSPATH_GNU)
1362 m = class_resolveclassmethod(c,
1364 utf_java_lang_Thread__V,
1365 class_java_lang_ThreadGroup,
1367 # elif defined(WITH_CLASSPATH_SUN)
1368 m = class_resolveclassmethod(c,
1370 utf_java_lang_Thread__V,
1371 class_java_lang_ThreadGroup,
1374 # error unknown classpath configuration
1380 o = (java_handle_t *) group;
1382 (void) vm_call_method(m, o, object);
1384 if (exceptions_get_exception())
1389 /* Thread has terminated. */
1391 threads_thread_state_terminated(t);
1393 /* Notify all threads waiting on this thread. These are joining
1396 o = (java_handle_t *) object;
1398 /* XXX Care about exceptions? */
1399 (void) lock_monitor_enter(o);
1401 lock_notify_all_object(o);
1403 /* XXX Care about exceptions? */
1404 (void) lock_monitor_exit(o);
1406 /* Enter the join-mutex before calling threads_thread_free, so
1407 threads_join_all_threads gets the correct number of non-daemon
1410 threads_mutex_join_lock();
1412 /* free the vm internal thread object */
1414 threads_thread_free(t);
1416 /* Signal that this thread has finished and leave the mutex. */
1418 pthread_cond_signal(&cond_join);
1419 threads_mutex_join_unlock();
1425 /* threads_suspend_thread ******************************************************
1427 Suspend the passed thread. Execution stops until the thread
1428 is explicitly resumend again.
1431 reason.....Reason for suspending this thread.
1433 *******************************************************************************/
1435 bool threads_suspend_thread(threadobject *thread, s4 reason)
1437 /* acquire the suspendmutex */
1438 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1439 vm_abort("threads_suspend_thread: pthread_mutex_lock failed: %s",
1442 if (thread->suspended) {
1443 pthread_mutex_unlock(&(thread->suspendmutex));
1447 /* set the reason for the suspension */
1448 thread->suspend_reason = reason;
1450 /* send the suspend signal to the thread */
1451 assert(thread != THREADOBJECT);
1452 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1453 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1456 /* REMEMBER: do not release the suspendmutex, this is done
1457 by the thread itself in threads_suspend_ack(). */
1463 /* threads_suspend_ack *********************************************************
1465 Acknowledges the suspension of the current thread.
1468 pc.....The PC where the thread suspended its execution.
1469 sp.....The SP before the thread suspended its execution.
1471 *******************************************************************************/
1473 void threads_suspend_ack(u1* pc, u1* sp)
1475 threadobject *thread;
1477 thread = THREADOBJECT;
1479 assert(thread->suspend_reason != 0);
1481 /* TODO: remember dump memory size */
1483 #if defined(ENABLE_GC_CACAO)
1484 /* inform the GC about the suspension */
1485 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1487 /* check if the GC wants to leave the thread running */
1488 if (!gc_suspend(thread, pc, sp)) {
1490 /* REMEMBER: we do not unlock the suspendmutex because the thread
1491 will suspend itself again at a later time */
1498 /* mark this thread as suspended and remember the PC */
1500 thread->suspended = true;
1502 /* if we are stopping the world, we should send a global ack */
1503 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1504 threads_sem_post(&suspend_ack);
1507 DEBUGTHREADS("suspending", thread);
1509 /* release the suspension mutex and wait till we are resumed */
1510 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1512 DEBUGTHREADS("resuming", thread);
1514 /* if we are stopping the world, we should send a global ack */
1515 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1516 threads_sem_post(&suspend_ack);
1519 /* TODO: free dump memory */
1521 /* release the suspendmutex */
1522 if (pthread_mutex_unlock(&(thread->suspendmutex)) != 0)
1523 vm_abort("threads_suspend_ack: pthread_mutex_unlock failed: %s",
1528 /* threads_resume_thread *******************************************************
1530 Resumes the execution of the passed thread.
1532 *******************************************************************************/
1534 bool threads_resume_thread(threadobject *thread)
1536 /* acquire the suspendmutex */
1537 if (pthread_mutex_lock(&(thread->suspendmutex)) != 0)
1538 vm_abort("threads_resume_ack: pthread_mutex_unlock failed: %s",
1541 if (!thread->suspended) {
1542 pthread_mutex_unlock(&(thread->suspendmutex));
1546 thread->suspended = false;
1548 /* tell everyone that the thread should resume */
1549 assert(thread != THREADOBJECT);
1550 pthread_cond_broadcast(&(thread->suspendcond));
1552 /* release the suspendmutex */
1553 pthread_mutex_unlock(&(thread->suspendmutex));
1559 /* threads_join_all_threads ****************************************************
1561 Join all non-daemon threads.
1563 *******************************************************************************/
1565 void threads_join_all_threads(void)
1569 /* get current thread */
1573 /* this thread is waiting for all non-daemon threads to exit */
1575 threads_thread_state_waiting(t);
1577 /* enter join mutex */
1579 threads_mutex_join_lock();
1581 /* Wait for condition as long as we have non-daemon threads. We
1582 compare against 1 because the current (main thread) is also a
1583 non-daemon thread. */
1585 while (threadlist_get_non_daemons() > 1)
1586 pthread_cond_wait(&cond_join, &mutex_join);
1588 /* leave join mutex */
1590 threads_mutex_join_unlock();
1594 /* threads_timespec_earlier ****************************************************
1596 Return true if timespec tv1 is earlier than timespec tv2.
1599 tv1..........first timespec
1600 tv2..........second timespec
1603 true, if the first timespec is earlier
1605 *******************************************************************************/
1607 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1608 const struct timespec *tv2)
1610 return (tv1->tv_sec < tv2->tv_sec)
1612 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1616 /* threads_current_time_is_earlier_than ****************************************
1618 Check if the current time is earlier than the given timespec.
1621 tv...........the timespec to compare against
1624 true, if the current time is earlier
1626 *******************************************************************************/
1628 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1630 struct timeval tvnow;
1631 struct timespec tsnow;
1633 /* get current time */
1635 if (gettimeofday(&tvnow, NULL) != 0)
1636 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1638 /* convert it to a timespec */
1640 tsnow.tv_sec = tvnow.tv_sec;
1641 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1643 /* compare current time with the given timespec */
1645 return threads_timespec_earlier(&tsnow, tv);
1649 /* threads_wait_with_timeout ***************************************************
1651 Wait until the given point in time on a monitor until either
1652 we are notified, we are interrupted, or the time is up.
1655 t............the current thread
1656 wakeupTime...absolute (latest) wakeup time
1657 If both tv_sec and tv_nsec are zero, this function
1658 waits for an unlimited amount of time.
1660 *******************************************************************************/
1662 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1664 /* acquire the waitmutex */
1666 pthread_mutex_lock(&t->waitmutex);
1668 /* mark us as sleeping */
1672 /* wait on waitcond */
1674 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1676 while (!t->interrupted && !t->signaled
1677 && threads_current_time_is_earlier_than(wakeupTime))
1679 threads_thread_state_timed_waiting(t);
1681 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1684 threads_thread_state_runnable(t);
1689 while (!t->interrupted && !t->signaled) {
1690 threads_thread_state_waiting(t);
1692 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1694 threads_thread_state_runnable(t);
1698 t->sleeping = false;
1700 /* release the waitmutex */
1702 pthread_mutex_unlock(&t->waitmutex);
1706 /* threads_wait_with_timeout_relative ******************************************
1708 Wait for the given maximum amount of time on a monitor until either
1709 we are notified, we are interrupted, or the time is up.
1712 t............the current thread
1713 millis.......milliseconds to wait
1714 nanos........nanoseconds to wait
1716 *******************************************************************************/
1718 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1721 struct timespec wakeupTime;
1723 /* calculate the the (latest) wakeup time */
1725 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1729 threads_wait_with_timeout(thread, &wakeupTime);
1733 /* threads_calc_absolute_time **************************************************
1735 Calculate the absolute point in time a given number of ms and ns from now.
1738 millis............milliseconds from now
1739 nanos.............nanoseconds from now
1742 *tm...............receives the timespec of the absolute point in time
1744 *******************************************************************************/
1746 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1748 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1751 gettimeofday(&tv, NULL);
1752 tv.tv_sec += millis / 1000;
1754 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1755 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1756 tm->tv_nsec = nsec % 1000000000;
1765 /* threads_thread_interrupt ****************************************************
1767 Interrupt the given thread.
1769 The thread gets the "waitcond" signal and
1770 its interrupted flag is set to true.
1773 thread............the thread to interrupt
1775 *******************************************************************************/
1777 void threads_thread_interrupt(threadobject *thread)
1779 /* Signal the thread a "waitcond" and tell it that it has been
1782 pthread_mutex_lock(&thread->waitmutex);
1784 DEBUGTHREADS("interrupted", thread);
1786 /* Interrupt blocking system call using a signal. */
1788 pthread_kill(thread->tid, SIGHUP);
1790 if (thread->sleeping)
1791 pthread_cond_signal(&thread->waitcond);
1793 thread->interrupted = true;
1795 pthread_mutex_unlock(&thread->waitmutex);
1799 /* threads_check_if_interrupted_and_reset **************************************
1801 Check if the current thread has been interrupted and reset the
1805 true, if the current thread had been interrupted
1807 *******************************************************************************/
1809 bool threads_check_if_interrupted_and_reset(void)
1811 threadobject *thread;
1814 thread = THREADOBJECT;
1816 pthread_mutex_lock(&thread->waitmutex);
1818 /* get interrupted flag */
1820 intr = thread->interrupted;
1822 /* reset interrupted flag */
1824 thread->interrupted = false;
1826 pthread_mutex_unlock(&thread->waitmutex);
1832 /* threads_thread_has_been_interrupted *****************************************
1834 Check if the given thread has been interrupted
1837 t............the thread to check
1840 true, if the given thread had been interrupted
1842 *******************************************************************************/
1844 bool threads_thread_has_been_interrupted(threadobject *thread)
1846 return thread->interrupted;
1850 /* threads_sleep ***************************************************************
1852 Sleep the current thread for the specified amount of time.
1854 *******************************************************************************/
1856 void threads_sleep(s8 millis, s4 nanos)
1858 threadobject *thread;
1859 struct timespec wakeupTime;
1860 bool wasinterrupted;
1862 thread = THREADOBJECT;
1864 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1866 threads_wait_with_timeout(thread, &wakeupTime);
1868 wasinterrupted = threads_check_if_interrupted_and_reset();
1871 exceptions_throw_interruptedexception();
1875 /* threads_yield ***************************************************************
1877 Yield to the scheduler.
1879 *******************************************************************************/
1881 void threads_yield(void)
1888 * These are local overrides for various environment variables in Emacs.
1889 * Please do not remove this and leave it at the end of the file, where
1890 * Emacs will automagically detect them.
1891 * ---------------------------------------------------------------------
1894 * indent-tabs-mode: t
1898 * vim:noexpandtab:sw=4:ts=4: