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_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
73 # include "native/include/java_lang_VMThread.h"
76 #include "threads/lock-common.h"
77 #include "threads/mutex.h"
78 #include "threads/threadlist.h"
79 #include "threads/thread.h"
81 #include "toolbox/logging.h"
83 #include "vm/builtin.h"
84 #include "vm/exceptions.h"
85 #include "vm/global.h"
86 #include "vm/stringlocal.h"
89 #include "vm/jit/asmpart.h"
91 #include "vmcore/options.h"
93 #if defined(ENABLE_STATISTICS)
94 # include "vmcore/statistics.h"
97 #if !defined(__DARWIN__)
98 # include <semaphore.h>
100 # if defined(__LINUX__)
101 # define GC_LINUX_THREADS
102 # elif defined(__IRIX__)
103 # define GC_IRIX_THREADS
104 # elif defined(__DARWIN__)
105 # define GC_DARWIN_THREADS
107 # if defined(ENABLE_GC_BOEHM)
108 /* We need to include Boehm's gc.h here because it overrides
109 pthread_create and friends. */
110 # include "mm/boehm-gc/include/gc.h"
113 #if defined(ENABLE_JVMTI)
114 #include "native/jvmti/cacaodbg.h"
117 #if defined(__DARWIN__)
118 /* Darwin has no working semaphore implementation. This one is taken
122 This is a very simple semaphore implementation for darwin. It
123 is implemented in terms of pthreads calls so it isn't async signal
124 safe. This isn't a problem because signals aren't used to
125 suspend threads on darwin.
128 static int sem_init(sem_t *sem, int pshared, int value)
135 mutex_init(&sem->mutex);
137 if (pthread_cond_init(&sem->cond, NULL) < 0)
143 static int sem_post(sem_t *sem)
145 mutex_lock(&sem->mutex);
149 if (pthread_cond_signal(&sem->cond) < 0) {
150 mutex_unlock(&sem->mutex);
154 mutex_unlock(&sem->mutex);
159 static int sem_wait(sem_t *sem)
161 mutex_lock(&sem->mutex);
163 while (sem->value == 0) {
164 pthread_cond_wait(&sem->cond, &sem->mutex);
169 mutex_unlock(&sem->mutex);
174 static int sem_destroy(sem_t *sem)
176 if (pthread_cond_destroy(&sem->cond) < 0)
179 mutex_destroy(&sem->mutex);
183 #endif /* defined(__DARWIN__) */
186 /* internally used constants **************************************************/
188 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
189 #define STOPWORLD_FROM_GC 1
190 #define STOPWORLD_FROM_CLASS_NUMBERING 2
193 /* startupinfo *****************************************************************
195 Struct used to pass info from threads_start_thread to
196 threads_startup_thread.
198 ******************************************************************************/
201 threadobject *thread; /* threadobject for this thread */
202 functionptr function; /* function to run in the new thread */
203 sem_t *psem; /* signals when thread has been entered */
204 /* in the thread list */
205 sem_t *psem_first; /* signals when pthread_create has returned */
209 /* prototypes *****************************************************************/
211 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
214 /******************************************************************************/
215 /* GLOBAL VARIABLES */
216 /******************************************************************************/
218 /* the thread object of the current thread */
219 /* This is either a thread-local variable defined with __thread, or */
220 /* a thread-specific value stored with key threads_current_threadobject_key. */
221 #if defined(HAVE___THREAD)
222 __thread threadobject *thread_current;
224 pthread_key_t thread_current_key;
227 /* global mutex for stop-the-world */
228 static mutex_t stopworldlock;
230 #if defined(ENABLE_GC_CACAO)
231 /* global mutex for the GC */
232 static mutex_t mutex_gc;
235 /* global mutex and condition for joining threads on exit */
236 static mutex_t mutex_join;
237 static pthread_cond_t cond_join;
239 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
241 static volatile int stopworldwhere;
243 #if defined(ENABLE_GC_CACAO)
245 /* semaphore used for acknowleding thread suspension */
246 static sem_t suspend_ack;
247 #if defined(__IRIX__)
248 static mutex_t suspend_ack_lock = MUTEX_INITIALIZER;
249 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
252 #endif /* ENABLE_GC_CACAO */
254 /* mutexes used by the fake atomic instructions */
255 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
256 mutex_t _cas_lock = MUTEX_INITIALIZER;
257 mutex_t _mb_lock = MUTEX_INITIALIZER;
261 /* threads_sem_init ************************************************************
263 Initialize a semaphore. Checks against errors and interruptions.
266 sem..............the semaphore to initialize
267 shared...........true if this semaphore will be shared between processes
268 value............the initial value for the semaphore
270 *******************************************************************************/
272 void threads_sem_init(sem_t *sem, bool shared, int value)
279 r = sem_init(sem, shared, value);
282 } while (errno == EINTR);
284 vm_abort("sem_init failed: %s", strerror(errno));
288 /* threads_sem_wait ************************************************************
290 Wait for a semaphore, non-interruptible.
292 IMPORTANT: Always use this function instead of `sem_wait` directly, as
293 `sem_wait` may be interrupted by signals!
296 sem..............the semaphore to wait on
298 *******************************************************************************/
300 void threads_sem_wait(sem_t *sem)
310 } while (errno == EINTR);
312 vm_abort("sem_wait failed: %s", strerror(errno));
316 /* threads_sem_post ************************************************************
318 Increase the count of a semaphore. Checks for errors.
321 sem..............the semaphore to increase the count of
323 *******************************************************************************/
325 void threads_sem_post(sem_t *sem)
331 /* unlike sem_wait, sem_post is not interruptible */
337 vm_abort("sem_post failed: %s", strerror(errno));
341 /* lock_stopworld **************************************************************
343 Enter the stopworld lock, specifying why the world shall be stopped.
346 where........ STOPWORLD_FROM_GC (1) from within GC
347 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
349 ******************************************************************************/
351 void lock_stopworld(int where)
353 mutex_lock(&stopworldlock);
354 /* stopworldwhere = where; */
358 /* unlock_stopworld ************************************************************
360 Release the stopworld lock.
362 ******************************************************************************/
364 void unlock_stopworld(void)
366 /* stopworldwhere = 0; */
367 mutex_unlock(&stopworldlock);
370 /* XXX We disable that whole bunch of code until we have the exact-GC
371 running. Some of it may only be needed by the old Boehm-based
372 suspension handling. */
376 #if !defined(__DARWIN__)
377 /* Caller must hold threadlistlock */
378 static s4 threads_cast_sendsignals(s4 sig)
386 /* iterate over all started threads */
390 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
391 /* don't send the signal to ourself */
396 /* don't send the signal to NEW threads (because they are not
397 completely initialized) */
399 if (t->state == THREAD_STATE_NEW)
402 /* send the signal */
404 pthread_kill(t->tid, sig);
406 /* increase threads count */
416 static void threads_cast_darwinstop(void)
418 threadobject *tobj = mainthreadobj;
419 threadobject *self = THREADOBJECT;
424 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
425 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
426 #if defined(__I386__)
427 i386_thread_state_t thread_state;
429 ppc_thread_state_t thread_state;
431 mach_port_t thread = tobj->mach_thread;
434 r = thread_suspend(thread);
436 if (r != KERN_SUCCESS)
437 vm_abort("thread_suspend failed");
439 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
440 &thread_state_count);
442 if (r != KERN_SUCCESS)
443 vm_abort("thread_get_state failed");
445 md_critical_section_restart((ucontext_t *) &thread_state);
447 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
450 if (r != KERN_SUCCESS)
451 vm_abort("thread_set_state failed");
455 } while (tobj != mainthreadobj);
458 static void threads_cast_darwinresume(void)
460 threadobject *tobj = mainthreadobj;
461 threadobject *self = THREADOBJECT;
466 mach_port_t thread = tobj->mach_thread;
469 r = thread_resume(thread);
471 if (r != KERN_SUCCESS)
472 vm_abort("thread_resume failed");
476 } while (tobj != mainthreadobj);
481 #if defined(__IRIX__)
482 static void threads_cast_irixresume(void)
484 mutex_lock(&suspend_ack_lock);
485 pthread_cond_broadcast(&suspend_cond);
486 mutex_unlock(&suspend_ack_lock);
490 #if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
491 static void threads_sigsuspend_handler(ucontext_t *_uc)
496 /* XXX TWISTI: this is just a quick hack */
497 #if defined(ENABLE_JIT)
498 md_critical_section_restart(_uc);
501 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
502 (not POSIX async-safe). */
503 #if defined(__IRIX__)
504 mutex_lock(&suspend_ack_lock);
505 threads_sem_post(&suspend_ack);
506 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
507 mutex_unlock(&suspend_ack_lock);
508 #elif defined(__CYGWIN__)
515 sigdelset(&sigs, sig);
522 /* threads_stopworld ***********************************************************
524 Stops the world from turning. All threads except the calling one
525 are suspended. The function returns as soon as all threads have
526 acknowledged their suspension.
528 *******************************************************************************/
530 void threads_stopworld(void)
532 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
539 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
541 /* lock the threads lists */
545 #if defined(__DARWIN__)
546 /*threads_cast_darwinstop();*/
548 #elif defined(__CYGWIN__)
554 DEBUGTHREADS("stops World", self);
558 /* suspend all running threads */
559 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
560 /* don't send the signal to ourself */
565 /* don't send the signal to NEW threads (because they are not
566 completely initialized) */
568 if (t->state == THREAD_STATE_NEW)
571 /* send the signal */
573 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
576 /* increase threads count */
581 /* wait for all threads signaled to suspend */
582 for (i = 0; i < count; i++)
583 threads_sem_wait(&suspend_ack);
586 /* ATTENTION: Don't unlock the threads-lists here so that
587 non-signaled NEW threads can't change their state and execute
592 /* threads_startworld **********************************************************
594 Starts the world again after it has previously been stopped.
596 *******************************************************************************/
598 void threads_startworld(void)
600 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
607 #if defined(__DARWIN__)
608 /*threads_cast_darwinresume();*/
610 #elif defined(__IRIX__)
611 threads_cast_irixresume();
612 #elif defined(__CYGWIN__)
618 DEBUGTHREADS("starts World", self);
622 /* resume all thread we haltet */
623 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
624 /* don't send the signal to ourself */
629 /* don't send the signal to NEW threads (because they are not
630 completely initialized) */
632 if (t->state == THREAD_STATE_NEW)
635 /* send the signal */
637 result = threads_resume_thread(t);
640 /* increase threads count */
645 /* wait for all threads signaled to suspend */
646 for (i = 0; i < count; i++)
647 threads_sem_wait(&suspend_ack);
651 /* unlock the threads lists */
661 /* threads_impl_thread_init ****************************************************
663 Initialize OS-level locking constructs in threadobject.
666 t....the threadobject
668 *******************************************************************************/
670 void threads_impl_thread_init(threadobject *t)
674 /* initialize the mutex and the condition */
676 mutex_init(&t->flc_lock);
678 result = pthread_cond_init(&t->flc_cond, NULL);
680 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
682 mutex_init(&(t->waitmutex));
684 result = pthread_cond_init(&(t->waitcond), NULL);
686 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
688 mutex_init(&(t->suspendmutex));
690 result = pthread_cond_init(&(t->suspendcond), NULL);
692 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
695 /* threads_impl_thread_clear ***************************************************
697 Clears all fields in threadobject the way an MZERO would have
698 done. MZERO cannot be used anymore because it would mess up the
702 t....the threadobject
704 *******************************************************************************/
706 void threads_impl_thread_clear(threadobject *t)
718 #if defined(__DARWIN__)
722 t->interrupted = false;
726 t->suspended = false;
727 t->suspend_reason = 0;
731 t->_exceptionptr = NULL;
732 t->_stackframeinfo = NULL;
733 t->_localref_table = NULL;
735 #if defined(ENABLE_INTRP)
736 t->_global_sp = NULL;
739 #if defined(ENABLE_GC_CACAO)
740 t->gc_critical = false;
746 MZERO(&t->dumpinfo, dumpinfo_t, 1);
749 /* threads_impl_thread_reuse ***************************************************
751 Resets some implementation fields in threadobject. This was
752 previously done in threads_impl_thread_new.
755 t....the threadobject
757 *******************************************************************************/
759 void threads_impl_thread_reuse(threadobject *t)
761 /* get the pthread id */
763 t->tid = pthread_self();
765 #if defined(ENABLE_DEBUG_FILTER)
766 /* Initialize filter counters */
767 t->filterverbosecallctr[0] = 0;
768 t->filterverbosecallctr[1] = 0;
772 t->tracejavacallindent = 0;
773 t->tracejavacallcount = 0;
780 /* not really needed */
781 t->flc_object = NULL;
785 /* threads_impl_thread_free ****************************************************
787 Cleanup thread stuff.
790 t....the threadobject
792 *******************************************************************************/
796 void threads_impl_thread_free(threadobject *t)
800 /* Destroy the mutex and the condition. */
802 mutex_destroy(&(t->flc_lock));
804 result = pthread_cond_destroy(&(t->flc_cond));
807 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
809 mutex_destroy(&(t->waitmutex));
811 result = pthread_cond_destroy(&(t->waitcond));
814 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
816 mutex_destroy(&(t->suspendmutex));
818 result = pthread_cond_destroy(&(t->suspendcond));
821 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
826 /* threads_impl_preinit ********************************************************
828 Do some early initialization of stuff required.
830 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
831 is called AFTER this function!
833 *******************************************************************************/
835 void threads_impl_preinit(void)
839 mutex_init(&stopworldlock);
841 /* initialize exit mutex and condition (on exit we join all
844 mutex_init(&mutex_join);
846 result = pthread_cond_init(&cond_join, NULL);
848 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
850 #if defined(ENABLE_GC_CACAO)
851 /* initialize the GC mutex & suspend semaphore */
853 mutex_init(&mutex_gc);
854 threads_sem_init(&suspend_ack, 0, 0);
857 #if !defined(HAVE___THREAD)
858 result = pthread_key_create(&thread_current_key, NULL);
860 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
865 /* threads_mutex_gc_lock *******************************************************
867 Enter the global GC mutex.
869 *******************************************************************************/
871 #if defined(ENABLE_GC_CACAO)
872 void threads_mutex_gc_lock(void)
874 mutex_lock(&mutex_gc);
879 /* threads_mutex_gc_unlock *****************************************************
881 Leave the global GC mutex.
883 *******************************************************************************/
885 #if defined(ENABLE_GC_CACAO)
886 void threads_mutex_gc_unlock(void)
888 mutex_unlock(&mutex_gc);
892 /* threads_mutex_join_lock *****************************************************
894 Enter the join mutex.
896 *******************************************************************************/
898 void threads_mutex_join_lock(void)
900 mutex_lock(&mutex_join);
904 /* threads_mutex_join_unlock ***************************************************
906 Leave the join mutex.
908 *******************************************************************************/
910 void threads_mutex_join_unlock(void)
912 mutex_unlock(&mutex_join);
916 /* threads_impl_init ***********************************************************
918 Initializes the implementation specific bits.
920 *******************************************************************************/
922 void threads_impl_init(void)
927 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
929 /* Initialize the thread attribute object. */
931 result = pthread_attr_init(&attr);
934 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
936 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
939 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
943 /* threads_startup_thread ******************************************************
945 Thread startup function called by pthread_create.
947 Thread which have a startup.function != NULL are marked as internal
948 threads. All other threads are threated as normal Java threads.
950 NOTE: This function is not called directly by pthread_create. The Boehm GC
951 inserts its own GC_start_routine in between, which then calls
955 arg..........the argument passed to pthread_create, ie. a pointer to
956 a startupinfo struct. CAUTION: When the `psem` semaphore
957 is posted, the startupinfo struct becomes invalid! (It
958 is allocated on the stack of threads_start_thread.)
960 ******************************************************************************/
962 static void *threads_startup_thread(void *arg)
964 startupinfo *startup;
966 java_lang_Thread *object;
967 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
968 java_lang_VMThread *vmt;
974 functionptr function;
976 #if defined(ENABLE_INTRP)
977 u1 *intrp_thread_stack;
979 /* create interpreter stack */
982 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
983 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
986 intrp_thread_stack = NULL;
989 /* get passed startupinfo structure and the values in there */
994 function = startup->function;
995 psem = startup->psem;
997 /* Seems like we've encountered a situation where thread->tid was
998 not set by pthread_create. We alleviate this problem by waiting
999 for pthread_create to return. */
1001 threads_sem_wait(startup->psem_first);
1003 #if defined(__DARWIN__)
1004 t->mach_thread = mach_thread_self();
1007 /* Now that we are in the new thread, we can store the internal
1008 thread data-structure in the TSD. */
1010 thread_set_current(t);
1012 /* get the java.lang.Thread object for this thread */
1014 object = (java_lang_Thread *) thread_get_object(t);
1016 /* set our priority */
1018 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
1020 /* Thread is completely initialized. */
1022 thread_set_state_runnable(t);
1024 /* tell threads_startup_thread that we registered ourselves */
1025 /* CAUTION: *startup becomes invalid with this! */
1028 threads_sem_post(psem);
1030 #if defined(ENABLE_INTRP)
1031 /* set interpreter stack */
1034 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1037 #if defined(ENABLE_JVMTI)
1038 /* fire thread start event */
1041 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1044 DEBUGTHREADS("starting", t);
1046 /* find and run the Thread.run()V method if no other function was passed */
1048 if (function == NULL) {
1049 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1050 /* We need to start the run method of
1051 java.lang.VMThread. Since this is a final class, we can use
1052 the class object directly. */
1054 c = class_java_lang_VMThread;
1055 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1056 LLNI_class_get(object, c);
1058 # error unknown classpath configuration
1061 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1064 vm_abort("threads_startup_thread: run() method not found in class");
1066 /* set ThreadMXBean variables */
1068 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1069 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1071 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1072 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1073 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1074 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1076 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1077 /* we need to start the run method of java.lang.VMThread */
1079 LLNI_field_get_ref(object, vmThread, vmt);
1080 o = (java_handle_t *) vmt;
1082 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1083 o = (java_handle_t *) object;
1085 # error unknown classpath configuration
1088 /* Run the thread. */
1090 (void) vm_call_method(m, o);
1093 /* set ThreadMXBean variables */
1095 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1096 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1098 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1099 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1100 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1101 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1103 /* call passed function, e.g. finalizer_thread */
1108 DEBUGTHREADS("stopping", t);
1110 #if defined(ENABLE_JVMTI)
1111 /* fire thread end event */
1114 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1117 /* We ignore the return value. */
1119 (void) threads_detach_thread(t);
1121 /* set ThreadMXBean variables */
1123 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1129 /* threads_impl_thread_start ***************************************************
1131 Start a thread in the JVM. Both (vm internal and java) thread
1135 thread....the thread object
1136 f.........function to run in the new thread. NULL means that the
1137 "run" method of the object `t` should be called
1139 ******************************************************************************/
1141 void threads_impl_thread_start(threadobject *thread, functionptr f)
1145 pthread_attr_t attr;
1146 startupinfo startup;
1149 /* fill startupinfo structure passed by pthread_create to
1150 * threads_startup_thread */
1152 startup.thread = thread;
1153 startup.function = f; /* maybe we don't call Thread.run()V */
1154 startup.psem = &sem;
1155 startup.psem_first = &sem_first;
1157 threads_sem_init(&sem, 0, 0);
1158 threads_sem_init(&sem_first, 0, 0);
1160 /* Initialize thread attributes. */
1162 result = pthread_attr_init(&attr);
1165 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1167 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1170 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1172 /* initialize thread stacksize */
1174 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1177 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1179 /* create the thread */
1181 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1184 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1186 /* destroy the thread attributes */
1188 result = pthread_attr_destroy(&attr);
1191 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1193 /* signal that pthread_create has returned, so thread->tid is valid */
1195 threads_sem_post(&sem_first);
1197 /* wait here until the thread has entered itself into the thread list */
1199 threads_sem_wait(&sem);
1204 sem_destroy(&sem_first);
1208 /* threads_set_thread_priority *************************************************
1210 Set the priority of the given thread.
1213 tid..........thread id
1214 priority.....priority to set
1216 ******************************************************************************/
1218 void threads_set_thread_priority(pthread_t tid, int priority)
1220 struct sched_param schedp;
1223 pthread_getschedparam(tid, &policy, &schedp);
1224 schedp.sched_priority = priority;
1225 pthread_setschedparam(tid, policy, &schedp);
1229 /* threads_detach_thread *******************************************************
1231 Detaches the passed thread from the VM. Used in JNI.
1233 *******************************************************************************/
1235 bool threads_detach_thread(threadobject *t)
1238 java_lang_Thread *object;
1240 #if defined(ENABLE_JAVASE)
1241 java_lang_ThreadGroup *group;
1248 /* If the given thread has already been detached, this operation
1251 result = thread_is_attached(t);
1253 if (result == false)
1256 DEBUGTHREADS("detaching", t);
1258 object = (java_lang_Thread *) thread_get_object(t);
1260 #if defined(ENABLE_JAVASE)
1261 LLNI_field_get_ref(object, group, group);
1263 /* If there's an uncaught exception, call uncaughtException on the
1264 thread's exception handler, or the thread's group if this is
1267 e = exceptions_get_and_clear_exception();
1270 /* We use the type void* for handler here, as it's not trivial
1271 to build the java_lang_Thread_UncaughtExceptionHandler
1272 header file with cacaoh. */
1274 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1275 LLNI_field_get_ref(object, exceptionHandler, handler);
1276 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1277 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1280 if (handler != NULL) {
1281 LLNI_class_get(handler, c);
1282 o = (java_handle_t *) handler;
1285 LLNI_class_get(group, c);
1286 o = (java_handle_t *) group;
1289 m = class_resolveclassmethod(c,
1290 utf_uncaughtException,
1291 utf_java_lang_Thread_java_lang_Throwable__V,
1298 (void) vm_call_method(m, o, object, e);
1300 if (exceptions_get_exception())
1304 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1306 /* Remove thread from the thread group. */
1308 if (group != NULL) {
1309 LLNI_class_get(group, c);
1311 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1312 m = class_resolveclassmethod(c,
1314 utf_java_lang_Thread__V,
1315 class_java_lang_ThreadGroup,
1317 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1318 m = class_resolveclassmethod(c,
1320 utf_java_lang_Thread__V,
1321 class_java_lang_ThreadGroup,
1324 # error unknown classpath configuration
1330 o = (java_handle_t *) group;
1332 (void) vm_call_method(m, o, object);
1334 if (exceptions_get_exception())
1337 /* Reset the threadgroup in the Java thread object (Mauve
1338 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1340 LLNI_field_set_ref(object, group, NULL);
1344 /* Thread has terminated. */
1346 thread_set_state_terminated(t);
1348 /* Notify all threads waiting on this thread. These are joining
1351 o = (java_handle_t *) object;
1353 /* XXX Care about exceptions? */
1354 (void) lock_monitor_enter(o);
1356 lock_notify_all_object(o);
1358 /* XXX Care about exceptions? */
1359 (void) lock_monitor_exit(o);
1361 /* Enter the join-mutex before calling thread_free, so
1362 threads_join_all_threads gets the correct number of non-daemon
1365 threads_mutex_join_lock();
1367 /* Free the internal thread data-structure. */
1371 /* Signal that this thread has finished and leave the mutex. */
1373 pthread_cond_signal(&cond_join);
1374 threads_mutex_join_unlock();
1380 #if defined(ENABLE_GC_CACAO)
1382 /* threads_suspend_thread ******************************************************
1384 Suspend the passed thread. Execution stops until the thread
1385 is explicitly resumend again.
1388 reason.....Reason for suspending this thread.
1390 *******************************************************************************/
1392 bool threads_suspend_thread(threadobject *thread, s4 reason)
1394 /* acquire the suspendmutex */
1395 mutex_lock(&(thread->suspendmutex));
1397 if (thread->suspended) {
1398 mutex_unlock(&(thread->suspendmutex));
1402 /* set the reason for the suspension */
1403 thread->suspend_reason = reason;
1405 /* send the suspend signal to the thread */
1406 assert(thread != THREADOBJECT);
1407 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1408 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1411 /* REMEMBER: do not release the suspendmutex, this is done
1412 by the thread itself in threads_suspend_ack(). */
1418 /* threads_suspend_ack *********************************************************
1420 Acknowledges the suspension of the current thread.
1423 pc.....The PC where the thread suspended its execution.
1424 sp.....The SP before the thread suspended its execution.
1426 *******************************************************************************/
1428 void threads_suspend_ack(u1* pc, u1* sp)
1430 threadobject *thread;
1432 thread = THREADOBJECT;
1434 assert(thread->suspend_reason != 0);
1436 /* TODO: remember dump memory size */
1438 /* inform the GC about the suspension */
1439 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1441 /* check if the GC wants to leave the thread running */
1442 if (!gc_suspend(thread, pc, sp)) {
1444 /* REMEMBER: we do not unlock the suspendmutex because the thread
1445 will suspend itself again at a later time */
1451 /* mark this thread as suspended and remember the PC */
1453 thread->suspended = true;
1455 /* if we are stopping the world, we should send a global ack */
1456 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1457 threads_sem_post(&suspend_ack);
1460 DEBUGTHREADS("suspending", thread);
1462 /* release the suspension mutex and wait till we are resumed */
1463 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1465 DEBUGTHREADS("resuming", thread);
1467 /* if we are stopping the world, we should send a global ack */
1468 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1469 threads_sem_post(&suspend_ack);
1472 /* TODO: free dump memory */
1474 /* release the suspendmutex */
1475 mutex_unlock(&(thread->suspendmutex));
1479 /* threads_resume_thread *******************************************************
1481 Resumes the execution of the passed thread.
1483 *******************************************************************************/
1485 bool threads_resume_thread(threadobject *thread)
1487 /* acquire the suspendmutex */
1488 mutex_lock(&(thread->suspendmutex));
1490 if (!thread->suspended) {
1491 mutex_unlock(&(thread->suspendmutex));
1495 thread->suspended = false;
1497 /* tell everyone that the thread should resume */
1498 assert(thread != THREADOBJECT);
1499 pthread_cond_broadcast(&(thread->suspendcond));
1501 /* release the suspendmutex */
1502 mutex_unlock(&(thread->suspendmutex));
1509 /* threads_join_all_threads ****************************************************
1511 Join all non-daemon threads.
1513 *******************************************************************************/
1515 void threads_join_all_threads(void)
1519 /* get current thread */
1523 /* This thread is waiting for all non-daemon threads to exit. */
1525 thread_set_state_waiting(t);
1527 /* enter join mutex */
1529 threads_mutex_join_lock();
1531 /* Wait for condition as long as we have non-daemon threads. We
1532 compare against 1 because the current (main thread) is also a
1533 non-daemon thread. */
1535 while (threadlist_get_non_daemons() > 1)
1536 pthread_cond_wait(&cond_join, &mutex_join);
1538 /* leave join mutex */
1540 threads_mutex_join_unlock();
1544 /* threads_timespec_earlier ****************************************************
1546 Return true if timespec tv1 is earlier than timespec tv2.
1549 tv1..........first timespec
1550 tv2..........second timespec
1553 true, if the first timespec is earlier
1555 *******************************************************************************/
1557 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1558 const struct timespec *tv2)
1560 return (tv1->tv_sec < tv2->tv_sec)
1562 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1566 /* threads_current_time_is_earlier_than ****************************************
1568 Check if the current time is earlier than the given timespec.
1571 tv...........the timespec to compare against
1574 true, if the current time is earlier
1576 *******************************************************************************/
1578 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1580 struct timeval tvnow;
1581 struct timespec tsnow;
1583 /* get current time */
1585 if (gettimeofday(&tvnow, NULL) != 0)
1586 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1588 /* convert it to a timespec */
1590 tsnow.tv_sec = tvnow.tv_sec;
1591 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1593 /* compare current time with the given timespec */
1595 return threads_timespec_earlier(&tsnow, tv);
1599 /* threads_wait_with_timeout ***************************************************
1601 Wait until the given point in time on a monitor until either
1602 we are notified, we are interrupted, or the time is up.
1605 t............the current thread
1606 wakeupTime...absolute (latest) wakeup time
1607 If both tv_sec and tv_nsec are zero, this function
1608 waits for an unlimited amount of time.
1610 *******************************************************************************/
1612 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1614 /* acquire the waitmutex */
1616 mutex_lock(&t->waitmutex);
1618 /* mark us as sleeping */
1622 /* wait on waitcond */
1624 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1626 while (!t->interrupted && !t->signaled
1627 && threads_current_time_is_earlier_than(wakeupTime))
1629 thread_set_state_timed_waiting(t);
1631 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1634 thread_set_state_runnable(t);
1639 while (!t->interrupted && !t->signaled) {
1640 thread_set_state_waiting(t);
1642 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1644 thread_set_state_runnable(t);
1648 t->sleeping = false;
1650 /* release the waitmutex */
1652 mutex_unlock(&t->waitmutex);
1656 /* threads_wait_with_timeout_relative ******************************************
1658 Wait for the given maximum amount of time on a monitor until either
1659 we are notified, we are interrupted, or the time is up.
1662 t............the current thread
1663 millis.......milliseconds to wait
1664 nanos........nanoseconds to wait
1666 *******************************************************************************/
1668 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1671 struct timespec wakeupTime;
1673 /* calculate the the (latest) wakeup time */
1675 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1679 threads_wait_with_timeout(thread, &wakeupTime);
1683 /* threads_calc_absolute_time **************************************************
1685 Calculate the absolute point in time a given number of ms and ns from now.
1688 millis............milliseconds from now
1689 nanos.............nanoseconds from now
1692 *tm...............receives the timespec of the absolute point in time
1694 *******************************************************************************/
1696 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1698 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1701 gettimeofday(&tv, NULL);
1702 tv.tv_sec += millis / 1000;
1704 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1705 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1706 tm->tv_nsec = nsec % 1000000000;
1715 /* threads_thread_interrupt ****************************************************
1717 Interrupt the given thread.
1719 The thread gets the "waitcond" signal and
1720 its interrupted flag is set to true.
1723 thread............the thread to interrupt
1725 *******************************************************************************/
1727 void threads_thread_interrupt(threadobject *thread)
1729 /* Signal the thread a "waitcond" and tell it that it has been
1732 mutex_lock(&thread->waitmutex);
1734 DEBUGTHREADS("interrupted", thread);
1736 /* Interrupt blocking system call using a signal. */
1738 pthread_kill(thread->tid, SIGHUP);
1740 if (thread->sleeping)
1741 pthread_cond_signal(&thread->waitcond);
1743 thread->interrupted = true;
1745 mutex_unlock(&thread->waitmutex);
1749 /* threads_sleep ***************************************************************
1751 Sleep the current thread for the specified amount of time.
1753 *******************************************************************************/
1755 void threads_sleep(int64_t millis, int32_t nanos)
1758 struct timespec wakeupTime;
1762 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1763 exceptions_throw_illegalargumentexception();
1767 t = thread_get_current();
1769 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1770 /* Clear interrupted flag (Mauve test:
1771 gnu/testlet/java/lang/Thread/interrupt). */
1773 thread_set_interrupted(t, false);
1775 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1776 exceptions_throw_interruptedexception();
1780 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1782 threads_wait_with_timeout(t, &wakeupTime);
1784 interrupted = thread_is_interrupted(t);
1787 thread_set_interrupted(t, false);
1789 /* An other exception could have been thrown
1790 (e.g. ThreadDeathException). */
1792 if (!exceptions_get_exception())
1793 exceptions_throw_interruptedexception();
1798 /* threads_yield ***************************************************************
1800 Yield to the scheduler.
1802 *******************************************************************************/
1804 void threads_yield(void)
1811 * These are local overrides for various environment variables in Emacs.
1812 * Please do not remove this and leave it at the end of the file, where
1813 * Emacs will automagically detect them.
1814 * ---------------------------------------------------------------------
1817 * indent-tabs-mode: t
1821 * vim:noexpandtab:sw=4:ts=4: