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/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 # include "mm/boehm-gc/include/gc.h"
111 #if defined(ENABLE_JVMTI)
112 #include "native/jvmti/cacaodbg.h"
115 #if defined(__DARWIN__)
116 /* Darwin has no working semaphore implementation. This one is taken
120 This is a very simple semaphore implementation for darwin. It
121 is implemented in terms of pthreads calls so it isn't async signal
122 safe. This isn't a problem because signals aren't used to
123 suspend threads on darwin.
126 static int sem_init(sem_t *sem, int pshared, int value)
133 mutex_init(&sem->mutex);
135 if (pthread_cond_init(&sem->cond, NULL) < 0)
141 static int sem_post(sem_t *sem)
143 mutex_lock(&sem->mutex);
147 if (pthread_cond_signal(&sem->cond) < 0) {
148 mutex_unlock(&sem->mutex);
152 mutex_unlock(&sem->mutex);
157 static int sem_wait(sem_t *sem)
159 mutex_lock(&sem->mutex);
161 while (sem->value == 0) {
162 pthread_cond_wait(&sem->cond, &sem->mutex);
167 mutex_unlock(&sem->mutex);
172 static int sem_destroy(sem_t *sem)
174 if (pthread_cond_destroy(&sem->cond) < 0)
177 mutex_destroy(&sem->mutex);
181 #endif /* defined(__DARWIN__) */
184 /* internally used constants **************************************************/
186 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
187 #define STOPWORLD_FROM_GC 1
188 #define STOPWORLD_FROM_CLASS_NUMBERING 2
191 /* startupinfo *****************************************************************
193 Struct used to pass info from threads_start_thread to
194 threads_startup_thread.
196 ******************************************************************************/
199 threadobject *thread; /* threadobject for this thread */
200 functionptr function; /* function to run in the new thread */
201 sem_t *psem; /* signals when thread has been entered */
202 /* in the thread list */
203 sem_t *psem_first; /* signals when pthread_create has returned */
207 /* prototypes *****************************************************************/
209 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
212 /******************************************************************************/
213 /* GLOBAL VARIABLES */
214 /******************************************************************************/
216 /* the thread object of the current thread */
217 /* This is either a thread-local variable defined with __thread, or */
218 /* a thread-specific value stored with key threads_current_threadobject_key. */
219 #if defined(HAVE___THREAD)
220 __thread threadobject *thread_current;
222 pthread_key_t thread_current_key;
225 /* global mutex for stop-the-world */
226 static mutex_t stopworldlock;
228 #if defined(ENABLE_GC_CACAO)
229 /* global mutex for the GC */
230 static mutex_t mutex_gc;
233 /* global mutex and condition for joining threads on exit */
234 static mutex_t mutex_join;
235 static pthread_cond_t cond_join;
237 /* XXX We disable that whole bunch of code until we have the exact-GC
242 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
244 static volatile int stopworldwhere;
246 /* semaphore used for acknowleding thread suspension */
247 static sem_t suspend_ack;
248 #if defined(__IRIX__)
249 static mutex_t suspend_ack_lock = MUTEX_INITIALIZER;
250 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
255 /* mutexes used by the fake atomic instructions */
256 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
257 mutex_t _cas_lock = MUTEX_INITIALIZER;
258 mutex_t _mb_lock = MUTEX_INITIALIZER;
262 /* threads_sem_init ************************************************************
264 Initialize a semaphore. Checks against errors and interruptions.
267 sem..............the semaphore to initialize
268 shared...........true if this semaphore will be shared between processes
269 value............the initial value for the semaphore
271 *******************************************************************************/
273 void threads_sem_init(sem_t *sem, bool shared, int value)
280 r = sem_init(sem, shared, value);
283 } while (errno == EINTR);
285 vm_abort("sem_init failed: %s", strerror(errno));
289 /* threads_sem_wait ************************************************************
291 Wait for a semaphore, non-interruptible.
293 IMPORTANT: Always use this function instead of `sem_wait` directly, as
294 `sem_wait` may be interrupted by signals!
297 sem..............the semaphore to wait on
299 *******************************************************************************/
301 void threads_sem_wait(sem_t *sem)
311 } while (errno == EINTR);
313 vm_abort("sem_wait failed: %s", strerror(errno));
317 /* threads_sem_post ************************************************************
319 Increase the count of a semaphore. Checks for errors.
322 sem..............the semaphore to increase the count of
324 *******************************************************************************/
326 void threads_sem_post(sem_t *sem)
332 /* unlike sem_wait, sem_post is not interruptible */
338 vm_abort("sem_post failed: %s", strerror(errno));
342 /* lock_stopworld **************************************************************
344 Enter the stopworld lock, specifying why the world shall be stopped.
347 where........ STOPWORLD_FROM_GC (1) from within GC
348 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
350 ******************************************************************************/
352 void lock_stopworld(int where)
354 mutex_lock(&stopworldlock);
355 /* stopworldwhere = where; */
359 /* unlock_stopworld ************************************************************
361 Release the stopworld lock.
363 ******************************************************************************/
365 void unlock_stopworld(void)
367 /* stopworldwhere = 0; */
368 mutex_unlock(&stopworldlock);
371 /* XXX We disable that whole bunch of code until we have the exact-GC
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);
524 /* threads_stopworld ***********************************************************
526 Stops the world from turning. All threads except the calling one
527 are suspended. The function returns as soon as all threads have
528 acknowledged their suspension.
530 *******************************************************************************/
532 #if !defined(DISABLE_GC)
533 void threads_stopworld(void)
535 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
542 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
544 /* lock the threads lists */
548 #if defined(__DARWIN__)
549 /*threads_cast_darwinstop();*/
551 #elif defined(__CYGWIN__)
557 DEBUGTHREADS("stops World", self);
561 /* suspend all running threads */
562 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
563 /* don't send the signal to ourself */
568 /* don't send the signal to NEW threads (because they are not
569 completely initialized) */
571 if (t->state == THREAD_STATE_NEW)
574 /* send the signal */
576 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
579 /* increase threads count */
584 /* wait for all threads signaled to suspend */
585 for (i = 0; i < count; i++)
586 threads_sem_wait(&suspend_ack);
589 /* ATTENTION: Don't unlock the threads-lists here so that
590 non-signaled NEW threads can't change their state and execute
593 #endif /* !defined(DISABLE_GC) */
596 /* threads_startworld **********************************************************
598 Starts the world again after it has previously been stopped.
600 *******************************************************************************/
602 #if !defined(DISABLE_GC)
603 void threads_startworld(void)
605 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
612 #if defined(__DARWIN__)
613 /*threads_cast_darwinresume();*/
615 #elif defined(__IRIX__)
616 threads_cast_irixresume();
617 #elif defined(__CYGWIN__)
623 DEBUGTHREADS("starts World", self);
627 /* resume all thread we haltet */
628 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
629 /* don't send the signal to ourself */
634 /* don't send the signal to NEW threads (because they are not
635 completely initialized) */
637 if (t->state == THREAD_STATE_NEW)
640 /* send the signal */
642 result = threads_resume_thread(t);
645 /* increase threads count */
650 /* wait for all threads signaled to suspend */
651 for (i = 0; i < count; i++)
652 threads_sem_wait(&suspend_ack);
656 /* unlock the threads lists */
665 /* threads_impl_thread_init ****************************************************
667 Initialize OS-level locking constructs in threadobject.
670 t....the threadobject
672 *******************************************************************************/
674 void threads_impl_thread_init(threadobject *t)
678 /* initialize the mutex and the condition */
680 mutex_init(&t->flc_lock);
682 result = pthread_cond_init(&t->flc_cond, NULL);
684 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
686 mutex_init(&(t->waitmutex));
688 result = pthread_cond_init(&(t->waitcond), NULL);
690 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
692 mutex_init(&(t->suspendmutex));
694 result = pthread_cond_init(&(t->suspendcond), NULL);
696 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
699 /* threads_impl_thread_clear ***************************************************
701 Clears all fields in threadobject the way an MZERO would have
702 done. MZERO cannot be used anymore because it would mess up the
706 t....the threadobject
708 *******************************************************************************/
710 void threads_impl_thread_clear(threadobject *t)
722 #if defined(__DARWIN__)
726 t->interrupted = false;
730 t->suspended = false;
731 t->suspend_reason = 0;
735 t->_exceptionptr = NULL;
736 t->_stackframeinfo = NULL;
737 t->_localref_table = NULL;
739 #if defined(ENABLE_INTRP)
740 t->_global_sp = NULL;
743 #if defined(ENABLE_GC_CACAO)
744 t->gc_critical = false;
750 MZERO(&t->dumpinfo, dumpinfo_t, 1);
753 /* threads_impl_thread_reuse ***************************************************
755 Resets some implementation fields in threadobject. This was
756 previously done in threads_impl_thread_new.
759 t....the threadobject
761 *******************************************************************************/
763 void threads_impl_thread_reuse(threadobject *t)
765 /* get the pthread id */
767 t->tid = pthread_self();
769 #if defined(ENABLE_DEBUG_FILTER)
770 /* Initialize filter counters */
771 t->filterverbosecallctr[0] = 0;
772 t->filterverbosecallctr[1] = 0;
776 t->tracejavacallindent = 0;
777 t->tracejavacallcount = 0;
784 /* not really needed */
785 t->flc_object = NULL;
789 /* threads_impl_thread_free ****************************************************
791 Cleanup thread stuff.
794 t....the threadobject
796 *******************************************************************************/
800 void threads_impl_thread_free(threadobject *t)
804 /* Destroy the mutex and the condition. */
806 mutex_destroy(&(t->flc_lock));
808 result = pthread_cond_destroy(&(t->flc_cond));
811 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
813 mutex_destroy(&(t->waitmutex));
815 result = pthread_cond_destroy(&(t->waitcond));
818 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
820 mutex_destroy(&(t->suspendmutex));
822 result = pthread_cond_destroy(&(t->suspendcond));
825 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
830 /* threads_impl_preinit ********************************************************
832 Do some early initialization of stuff required.
834 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
835 is called AFTER this function!
837 *******************************************************************************/
839 void threads_impl_preinit(void)
843 mutex_init(&stopworldlock);
845 /* initialize exit mutex and condition (on exit we join all
848 mutex_init(&mutex_join);
850 result = pthread_cond_init(&cond_join, NULL);
852 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
854 #if defined(ENABLE_GC_CACAO)
855 /* initialize the GC mutext */
857 mutex_init(&mutex_gc);
860 #if !defined(HAVE___THREAD)
861 result = pthread_key_create(&thread_current_key, NULL);
863 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
866 threads_sem_init(&suspend_ack, 0, 0);
870 /* threads_mutex_gc_lock *******************************************************
872 Enter the global GC mutex.
874 *******************************************************************************/
876 #if defined(ENABLE_GC_CACAO)
877 void threads_mutex_gc_lock(void)
879 mutex_lock(&mutex_gc);
884 /* threads_mutex_gc_unlock *****************************************************
886 Leave the global GC mutex.
888 *******************************************************************************/
890 #if defined(ENABLE_GC_CACAO)
891 void threads_mutex_gc_unlock(void)
893 mutex_unlock(&mutex_gc);
897 /* threads_mutex_join_lock *****************************************************
899 Enter the join mutex.
901 *******************************************************************************/
903 void threads_mutex_join_lock(void)
905 mutex_lock(&mutex_join);
909 /* threads_mutex_join_unlock ***************************************************
911 Leave the join mutex.
913 *******************************************************************************/
915 void threads_mutex_join_unlock(void)
917 mutex_unlock(&mutex_join);
921 /* threads_impl_init ***********************************************************
923 Initializes the implementation specific bits.
925 *******************************************************************************/
927 void threads_impl_init(void)
932 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
934 /* Initialize the thread attribute object. */
936 result = pthread_attr_init(&attr);
939 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
941 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
944 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
948 /* threads_startup_thread ******************************************************
950 Thread startup function called by pthread_create.
952 Thread which have a startup.function != NULL are marked as internal
953 threads. All other threads are threated as normal Java threads.
955 NOTE: This function is not called directly by pthread_create. The Boehm GC
956 inserts its own GC_start_routine in between, which then calls
960 arg..........the argument passed to pthread_create, ie. a pointer to
961 a startupinfo struct. CAUTION: When the `psem` semaphore
962 is posted, the startupinfo struct becomes invalid! (It
963 is allocated on the stack of threads_start_thread.)
965 ******************************************************************************/
967 static void *threads_startup_thread(void *arg)
969 startupinfo *startup;
971 java_lang_Thread *object;
972 #if defined(WITH_CLASSPATH_GNU)
973 java_lang_VMThread *vmt;
979 functionptr function;
981 #if defined(ENABLE_INTRP)
982 u1 *intrp_thread_stack;
984 /* create interpreter stack */
987 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
988 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
991 intrp_thread_stack = NULL;
994 /* get passed startupinfo structure and the values in there */
999 function = startup->function;
1000 psem = startup->psem;
1002 /* Seems like we've encountered a situation where thread->tid was
1003 not set by pthread_create. We alleviate this problem by waiting
1004 for pthread_create to return. */
1006 threads_sem_wait(startup->psem_first);
1008 #if defined(__DARWIN__)
1009 t->mach_thread = mach_thread_self();
1012 /* Now that we are in the new thread, we can store the internal
1013 thread data-structure in the TSD. */
1015 thread_set_current(t);
1017 /* get the java.lang.Thread object for this thread */
1019 object = (java_lang_Thread *) thread_get_object(t);
1021 /* set our priority */
1023 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
1025 /* Thread is completely initialized. */
1027 thread_set_state_runnable(t);
1029 /* tell threads_startup_thread that we registered ourselves */
1030 /* CAUTION: *startup becomes invalid with this! */
1033 threads_sem_post(psem);
1035 #if defined(ENABLE_INTRP)
1036 /* set interpreter stack */
1039 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1042 #if defined(ENABLE_JVMTI)
1043 /* fire thread start event */
1046 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1049 DEBUGTHREADS("starting", t);
1051 /* find and run the Thread.run()V method if no other function was passed */
1053 if (function == NULL) {
1054 #if defined(WITH_CLASSPATH_GNU)
1055 /* We need to start the run method of
1056 java.lang.VMThread. Since this is a final class, we can use
1057 the class object directly. */
1059 c = class_java_lang_VMThread;
1060 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1061 LLNI_class_get(object, c);
1063 # error unknown classpath configuration
1066 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1069 vm_abort("threads_startup_thread: run() method not found in class");
1071 /* set ThreadMXBean variables */
1073 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1074 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1076 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1077 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1078 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1079 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1081 #if defined(WITH_CLASSPATH_GNU)
1082 /* we need to start the run method of java.lang.VMThread */
1084 LLNI_field_get_ref(object, vmThread, vmt);
1085 o = (java_handle_t *) vmt;
1087 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1088 o = (java_handle_t *) object;
1090 # error unknown classpath configuration
1093 /* Run the thread. */
1095 (void) vm_call_method(m, o);
1098 /* set ThreadMXBean variables */
1100 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1101 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1103 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1104 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1105 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1106 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1108 /* call passed function, e.g. finalizer_thread */
1113 DEBUGTHREADS("stopping", t);
1115 #if defined(ENABLE_JVMTI)
1116 /* fire thread end event */
1119 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1122 /* We ignore the return value. */
1124 (void) threads_detach_thread(t);
1126 /* set ThreadMXBean variables */
1128 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1134 /* threads_impl_thread_start ***************************************************
1136 Start a thread in the JVM. Both (vm internal and java) thread
1140 thread....the thread object
1141 f.........function to run in the new thread. NULL means that the
1142 "run" method of the object `t` should be called
1144 ******************************************************************************/
1146 void threads_impl_thread_start(threadobject *thread, functionptr f)
1150 pthread_attr_t attr;
1151 startupinfo startup;
1154 /* fill startupinfo structure passed by pthread_create to
1155 * threads_startup_thread */
1157 startup.thread = thread;
1158 startup.function = f; /* maybe we don't call Thread.run()V */
1159 startup.psem = &sem;
1160 startup.psem_first = &sem_first;
1162 threads_sem_init(&sem, 0, 0);
1163 threads_sem_init(&sem_first, 0, 0);
1165 /* Initialize thread attributes. */
1167 result = pthread_attr_init(&attr);
1170 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1172 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1175 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1177 /* initialize thread stacksize */
1179 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1182 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1184 /* create the thread */
1186 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1189 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1191 /* destroy the thread attributes */
1193 result = pthread_attr_destroy(&attr);
1196 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1198 /* signal that pthread_create has returned, so thread->tid is valid */
1200 threads_sem_post(&sem_first);
1202 /* wait here until the thread has entered itself into the thread list */
1204 threads_sem_wait(&sem);
1209 sem_destroy(&sem_first);
1213 /* threads_set_thread_priority *************************************************
1215 Set the priority of the given thread.
1218 tid..........thread id
1219 priority.....priority to set
1221 ******************************************************************************/
1223 void threads_set_thread_priority(pthread_t tid, int priority)
1225 struct sched_param schedp;
1228 pthread_getschedparam(tid, &policy, &schedp);
1229 schedp.sched_priority = priority;
1230 pthread_setschedparam(tid, policy, &schedp);
1234 /* threads_detach_thread *******************************************************
1236 Detaches the passed thread from the VM. Used in JNI.
1238 *******************************************************************************/
1240 bool threads_detach_thread(threadobject *t)
1243 java_lang_Thread *object;
1245 #if defined(ENABLE_JAVASE)
1246 java_lang_ThreadGroup *group;
1253 /* If the given thread has already been detached, this operation
1256 result = thread_is_attached(t);
1258 if (result == false)
1261 DEBUGTHREADS("detaching", t);
1263 object = (java_lang_Thread *) thread_get_object(t);
1265 #if defined(ENABLE_JAVASE)
1266 LLNI_field_get_ref(object, group, group);
1268 /* If there's an uncaught exception, call uncaughtException on the
1269 thread's exception handler, or the thread's group if this is
1272 e = exceptions_get_and_clear_exception();
1275 /* We use the type void* for handler here, as it's not trivial
1276 to build the java_lang_Thread_UncaughtExceptionHandler
1277 header file with cacaoh. */
1279 # if defined(WITH_CLASSPATH_GNU)
1280 LLNI_field_get_ref(object, exceptionHandler, handler);
1281 # elif defined(WITH_CLASSPATH_SUN)
1282 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1285 if (handler != NULL) {
1286 LLNI_class_get(handler, c);
1287 o = (java_handle_t *) handler;
1290 LLNI_class_get(group, c);
1291 o = (java_handle_t *) group;
1294 m = class_resolveclassmethod(c,
1295 utf_uncaughtException,
1296 utf_java_lang_Thread_java_lang_Throwable__V,
1303 (void) vm_call_method(m, o, object, e);
1305 if (exceptions_get_exception())
1309 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1311 /* Remove thread from the thread group. */
1313 if (group != NULL) {
1314 LLNI_class_get(group, c);
1316 # if defined(WITH_CLASSPATH_GNU)
1317 m = class_resolveclassmethod(c,
1319 utf_java_lang_Thread__V,
1320 class_java_lang_ThreadGroup,
1322 # elif defined(WITH_CLASSPATH_SUN)
1323 m = class_resolveclassmethod(c,
1325 utf_java_lang_Thread__V,
1326 class_java_lang_ThreadGroup,
1329 # error unknown classpath configuration
1335 o = (java_handle_t *) group;
1337 (void) vm_call_method(m, o, object);
1339 if (exceptions_get_exception())
1342 /* Reset the threadgroup in the Java thread object (Mauve
1343 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1345 LLNI_field_set_ref(object, group, NULL);
1349 /* Thread has terminated. */
1351 thread_set_state_terminated(t);
1353 /* Notify all threads waiting on this thread. These are joining
1356 o = (java_handle_t *) object;
1358 /* XXX Care about exceptions? */
1359 (void) lock_monitor_enter(o);
1361 lock_notify_all_object(o);
1363 /* XXX Care about exceptions? */
1364 (void) lock_monitor_exit(o);
1366 /* Enter the join-mutex before calling thread_free, so
1367 threads_join_all_threads gets the correct number of non-daemon
1370 threads_mutex_join_lock();
1372 /* Free the internal thread data-structure. */
1376 /* Signal that this thread has finished and leave the mutex. */
1378 pthread_cond_signal(&cond_join);
1379 threads_mutex_join_unlock();
1385 /* threads_suspend_thread ******************************************************
1387 Suspend the passed thread. Execution stops until the thread
1388 is explicitly resumend again.
1391 reason.....Reason for suspending this thread.
1393 *******************************************************************************/
1395 bool threads_suspend_thread(threadobject *thread, s4 reason)
1397 /* acquire the suspendmutex */
1398 mutex_lock(&(thread->suspendmutex));
1400 if (thread->suspended) {
1401 mutex_unlock(&(thread->suspendmutex));
1405 /* set the reason for the suspension */
1406 thread->suspend_reason = reason;
1408 /* send the suspend signal to the thread */
1409 assert(thread != THREADOBJECT);
1410 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1411 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1414 /* REMEMBER: do not release the suspendmutex, this is done
1415 by the thread itself in threads_suspend_ack(). */
1421 /* threads_suspend_ack *********************************************************
1423 Acknowledges the suspension of the current thread.
1426 pc.....The PC where the thread suspended its execution.
1427 sp.....The SP before the thread suspended its execution.
1429 *******************************************************************************/
1431 void threads_suspend_ack(u1* pc, u1* sp)
1433 threadobject *thread;
1435 thread = THREADOBJECT;
1437 assert(thread->suspend_reason != 0);
1439 /* TODO: remember dump memory size */
1441 #if defined(ENABLE_GC_CACAO)
1442 /* inform the GC about the suspension */
1443 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1445 /* check if the GC wants to leave the thread running */
1446 if (!gc_suspend(thread, pc, sp)) {
1448 /* REMEMBER: we do not unlock the suspendmutex because the thread
1449 will suspend itself again at a later time */
1456 /* mark this thread as suspended and remember the PC */
1458 thread->suspended = true;
1460 /* if we are stopping the world, we should send a global ack */
1461 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1462 threads_sem_post(&suspend_ack);
1465 DEBUGTHREADS("suspending", thread);
1467 /* release the suspension mutex and wait till we are resumed */
1468 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1470 DEBUGTHREADS("resuming", thread);
1472 /* if we are stopping the world, we should send a global ack */
1473 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1474 threads_sem_post(&suspend_ack);
1477 /* TODO: free dump memory */
1479 /* release the suspendmutex */
1480 mutex_unlock(&(thread->suspendmutex));
1484 /* threads_resume_thread *******************************************************
1486 Resumes the execution of the passed thread.
1488 *******************************************************************************/
1490 bool threads_resume_thread(threadobject *thread)
1492 /* acquire the suspendmutex */
1493 mutex_lock(&(thread->suspendmutex));
1495 if (!thread->suspended) {
1496 mutex_unlock(&(thread->suspendmutex));
1500 thread->suspended = false;
1502 /* tell everyone that the thread should resume */
1503 assert(thread != THREADOBJECT);
1504 pthread_cond_broadcast(&(thread->suspendcond));
1506 /* release the suspendmutex */
1507 mutex_unlock(&(thread->suspendmutex));
1513 /* threads_join_all_threads ****************************************************
1515 Join all non-daemon threads.
1517 *******************************************************************************/
1519 void threads_join_all_threads(void)
1523 /* get current thread */
1527 /* This thread is waiting for all non-daemon threads to exit. */
1529 thread_set_state_waiting(t);
1531 /* enter join mutex */
1533 threads_mutex_join_lock();
1535 /* Wait for condition as long as we have non-daemon threads. We
1536 compare against 1 because the current (main thread) is also a
1537 non-daemon thread. */
1539 while (threadlist_get_non_daemons() > 1)
1540 pthread_cond_wait(&cond_join, &mutex_join);
1542 /* leave join mutex */
1544 threads_mutex_join_unlock();
1548 /* threads_timespec_earlier ****************************************************
1550 Return true if timespec tv1 is earlier than timespec tv2.
1553 tv1..........first timespec
1554 tv2..........second timespec
1557 true, if the first timespec is earlier
1559 *******************************************************************************/
1561 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1562 const struct timespec *tv2)
1564 return (tv1->tv_sec < tv2->tv_sec)
1566 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1570 /* threads_current_time_is_earlier_than ****************************************
1572 Check if the current time is earlier than the given timespec.
1575 tv...........the timespec to compare against
1578 true, if the current time is earlier
1580 *******************************************************************************/
1582 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1584 struct timeval tvnow;
1585 struct timespec tsnow;
1587 /* get current time */
1589 if (gettimeofday(&tvnow, NULL) != 0)
1590 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1592 /* convert it to a timespec */
1594 tsnow.tv_sec = tvnow.tv_sec;
1595 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1597 /* compare current time with the given timespec */
1599 return threads_timespec_earlier(&tsnow, tv);
1603 /* threads_wait_with_timeout ***************************************************
1605 Wait until the given point in time on a monitor until either
1606 we are notified, we are interrupted, or the time is up.
1609 t............the current thread
1610 wakeupTime...absolute (latest) wakeup time
1611 If both tv_sec and tv_nsec are zero, this function
1612 waits for an unlimited amount of time.
1614 *******************************************************************************/
1616 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1618 /* acquire the waitmutex */
1620 mutex_lock(&t->waitmutex);
1622 /* mark us as sleeping */
1626 /* wait on waitcond */
1628 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1630 while (!t->interrupted && !t->signaled
1631 && threads_current_time_is_earlier_than(wakeupTime))
1633 thread_set_state_timed_waiting(t);
1635 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1638 thread_set_state_runnable(t);
1643 while (!t->interrupted && !t->signaled) {
1644 thread_set_state_waiting(t);
1646 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1648 thread_set_state_runnable(t);
1652 t->sleeping = false;
1654 /* release the waitmutex */
1656 mutex_unlock(&t->waitmutex);
1660 /* threads_wait_with_timeout_relative ******************************************
1662 Wait for the given maximum amount of time on a monitor until either
1663 we are notified, we are interrupted, or the time is up.
1666 t............the current thread
1667 millis.......milliseconds to wait
1668 nanos........nanoseconds to wait
1670 *******************************************************************************/
1672 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1675 struct timespec wakeupTime;
1677 /* calculate the the (latest) wakeup time */
1679 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1683 threads_wait_with_timeout(thread, &wakeupTime);
1687 /* threads_calc_absolute_time **************************************************
1689 Calculate the absolute point in time a given number of ms and ns from now.
1692 millis............milliseconds from now
1693 nanos.............nanoseconds from now
1696 *tm...............receives the timespec of the absolute point in time
1698 *******************************************************************************/
1700 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1702 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1705 gettimeofday(&tv, NULL);
1706 tv.tv_sec += millis / 1000;
1708 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1709 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1710 tm->tv_nsec = nsec % 1000000000;
1719 /* threads_thread_interrupt ****************************************************
1721 Interrupt the given thread.
1723 The thread gets the "waitcond" signal and
1724 its interrupted flag is set to true.
1727 thread............the thread to interrupt
1729 *******************************************************************************/
1731 void threads_thread_interrupt(threadobject *thread)
1733 /* Signal the thread a "waitcond" and tell it that it has been
1736 mutex_lock(&thread->waitmutex);
1738 DEBUGTHREADS("interrupted", thread);
1740 /* Interrupt blocking system call using a signal. */
1742 pthread_kill(thread->tid, SIGHUP);
1744 if (thread->sleeping)
1745 pthread_cond_signal(&thread->waitcond);
1747 thread->interrupted = true;
1749 mutex_unlock(&thread->waitmutex);
1753 /* threads_sleep ***************************************************************
1755 Sleep the current thread for the specified amount of time.
1757 *******************************************************************************/
1759 void threads_sleep(int64_t millis, int32_t nanos)
1762 struct timespec wakeupTime;
1766 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1767 exceptions_throw_illegalargumentexception();
1771 t = thread_get_current();
1773 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1774 /* Clear interrupted flag (Mauve test:
1775 gnu/testlet/java/lang/Thread/interrupt). */
1777 thread_set_interrupted(t, false);
1779 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1780 exceptions_throw_interruptedexception();
1784 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1786 threads_wait_with_timeout(t, &wakeupTime);
1788 interrupted = thread_is_interrupted(t);
1791 thread_set_interrupted(t, false);
1793 /* An other exception could have been thrown
1794 (e.g. ThreadDeathException). */
1796 if (!exceptions_get_exception())
1797 exceptions_throw_interruptedexception();
1802 /* threads_yield ***************************************************************
1804 Yield to the scheduler.
1806 *******************************************************************************/
1808 void threads_yield(void)
1815 * These are local overrides for various environment variables in Emacs.
1816 * Please do not remove this and leave it at the end of the file, where
1817 * Emacs will automagically detect them.
1818 * ---------------------------------------------------------------------
1821 * indent-tabs-mode: t
1825 * vim:noexpandtab:sw=4:ts=4: